132b31808SJens Wiklander /* 232b31808SJens Wiklander * TLS client-side functions 332b31808SJens Wiklander * 432b31808SJens Wiklander * Copyright The Mbed TLS Contributors 5b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 632b31808SJens Wiklander */ 732b31808SJens Wiklander 832b31808SJens Wiklander #include "common.h" 932b31808SJens Wiklander 1032b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2) 1132b31808SJens Wiklander 1232b31808SJens Wiklander #include "mbedtls/platform.h" 1332b31808SJens Wiklander 1432b31808SJens Wiklander #include "mbedtls/ssl.h" 1532b31808SJens Wiklander #include "ssl_client.h" 1632b31808SJens Wiklander #include "ssl_misc.h" 17b0563631STom Van Eyck #include "debug_internal.h" 1832b31808SJens Wiklander #include "mbedtls/error.h" 1932b31808SJens Wiklander #include "mbedtls/constant_time.h" 2032b31808SJens Wiklander 2132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 22b0563631STom Van Eyck #include "psa_util_internal.h" 2332b31808SJens Wiklander #include "psa/crypto.h" 24b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 25b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many 26b0563631STom Van Eyck * arguments in each translating place. */ 27b0563631STom Van Eyck static int local_err_translation(psa_status_t status) 28b0563631STom Van Eyck { 29b0563631STom Van Eyck return psa_status_to_mbedtls(status, psa_to_ssl_errors, 30b0563631STom Van Eyck ARRAY_LENGTH(psa_to_ssl_errors), 31b0563631STom Van Eyck psa_generic_status_to_mbedtls); 32b0563631STom Van Eyck } 33b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) 34b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 3532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 3632b31808SJens Wiklander 3732b31808SJens Wiklander #include <string.h> 3832b31808SJens Wiklander 3932b31808SJens Wiklander #include <stdint.h> 4032b31808SJens Wiklander 4132b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME) 4232b31808SJens Wiklander #include "mbedtls/platform_time.h" 4332b31808SJens Wiklander #endif 4432b31808SJens Wiklander 4532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 4632b31808SJens Wiklander #include "mbedtls/platform_util.h" 4732b31808SJens Wiklander #endif 4832b31808SJens Wiklander 4932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 5032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 5132b31808SJens Wiklander static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl, 5232b31808SJens Wiklander unsigned char *buf, 5332b31808SJens Wiklander const unsigned char *end, 5432b31808SJens Wiklander size_t *olen) 5532b31808SJens Wiklander { 5632b31808SJens Wiklander unsigned char *p = buf; 5732b31808SJens Wiklander 5832b31808SJens Wiklander *olen = 0; 5932b31808SJens Wiklander 6032b31808SJens Wiklander /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the 6132b31808SJens Wiklander * initial ClientHello, in which case also adding the renegotiation 6232b31808SJens Wiklander * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ 6332b31808SJens Wiklander if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 6432b31808SJens Wiklander return 0; 6532b31808SJens Wiklander } 6632b31808SJens Wiklander 6732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 6832b31808SJens Wiklander ("client hello, adding renegotiation extension")); 6932b31808SJens Wiklander 7032b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + ssl->verify_data_len); 7132b31808SJens Wiklander 7232b31808SJens Wiklander /* 7332b31808SJens Wiklander * Secure renegotiation 7432b31808SJens Wiklander */ 7532b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0); 7632b31808SJens Wiklander p += 2; 7732b31808SJens Wiklander 7832b31808SJens Wiklander *p++ = 0x00; 7932b31808SJens Wiklander *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len + 1); 8032b31808SJens Wiklander *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len); 8132b31808SJens Wiklander 8232b31808SJens Wiklander memcpy(p, ssl->own_verify_data, ssl->verify_data_len); 8332b31808SJens Wiklander 8432b31808SJens Wiklander *olen = 5 + ssl->verify_data_len; 8532b31808SJens Wiklander 8632b31808SJens Wiklander return 0; 8732b31808SJens Wiklander } 8832b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */ 8932b31808SJens Wiklander 90b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 91b0563631STom Van Eyck defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 9232b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 9332b31808SJens Wiklander 9432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 9532b31808SJens Wiklander static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, 9632b31808SJens Wiklander unsigned char *buf, 9732b31808SJens Wiklander const unsigned char *end, 9832b31808SJens Wiklander size_t *olen) 9932b31808SJens Wiklander { 10032b31808SJens Wiklander unsigned char *p = buf; 10132b31808SJens Wiklander (void) ssl; /* ssl used for debugging only */ 10232b31808SJens Wiklander 10332b31808SJens Wiklander *olen = 0; 10432b31808SJens Wiklander 10532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 10632b31808SJens Wiklander ("client hello, adding supported_point_formats extension")); 10732b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); 10832b31808SJens Wiklander 10932b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0); 11032b31808SJens Wiklander p += 2; 11132b31808SJens Wiklander 11232b31808SJens Wiklander *p++ = 0x00; 11332b31808SJens Wiklander *p++ = 2; 11432b31808SJens Wiklander 11532b31808SJens Wiklander *p++ = 1; 11632b31808SJens Wiklander *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; 11732b31808SJens Wiklander 11832b31808SJens Wiklander *olen = 6; 11932b31808SJens Wiklander 12032b31808SJens Wiklander return 0; 12132b31808SJens Wiklander } 122b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 123b0563631STom Van Eyck MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 12432b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 12532b31808SJens Wiklander 12632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 12732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 12832b31808SJens Wiklander static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, 12932b31808SJens Wiklander unsigned char *buf, 13032b31808SJens Wiklander const unsigned char *end, 13132b31808SJens Wiklander size_t *olen) 13232b31808SJens Wiklander { 13332b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 13432b31808SJens Wiklander unsigned char *p = buf; 13532b31808SJens Wiklander size_t kkpp_len = 0; 13632b31808SJens Wiklander 13732b31808SJens Wiklander *olen = 0; 13832b31808SJens Wiklander 13932b31808SJens Wiklander /* Skip costly extension if we can't use EC J-PAKE anyway */ 14032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 14132b31808SJens Wiklander if (ssl->handshake->psa_pake_ctx_is_ok != 1) { 14232b31808SJens Wiklander return 0; 14332b31808SJens Wiklander } 14432b31808SJens Wiklander #else 14532b31808SJens Wiklander if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) { 14632b31808SJens Wiklander return 0; 14732b31808SJens Wiklander } 14832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 14932b31808SJens Wiklander 15032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 15132b31808SJens Wiklander ("client hello, adding ecjpake_kkpp extension")); 15232b31808SJens Wiklander 15332b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 15432b31808SJens Wiklander 15532b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); 15632b31808SJens Wiklander p += 2; 15732b31808SJens Wiklander 15832b31808SJens Wiklander /* 15932b31808SJens Wiklander * We may need to send ClientHello multiple times for Hello verification. 16032b31808SJens Wiklander * We don't want to compute fresh values every time (both for performance 16132b31808SJens Wiklander * and consistency reasons), so cache the extension content. 16232b31808SJens Wiklander */ 16332b31808SJens Wiklander if (ssl->handshake->ecjpake_cache == NULL || 16432b31808SJens Wiklander ssl->handshake->ecjpake_cache_len == 0) { 16532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters")); 16632b31808SJens Wiklander 16732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 16832b31808SJens Wiklander ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 16932b31808SJens Wiklander p + 2, end - p - 2, &kkpp_len, 17032b31808SJens Wiklander MBEDTLS_ECJPAKE_ROUND_ONE); 17132b31808SJens Wiklander if (ret != 0) { 17232b31808SJens Wiklander psa_destroy_key(ssl->handshake->psa_pake_password); 17332b31808SJens Wiklander psa_pake_abort(&ssl->handshake->psa_pake_ctx); 17432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 17532b31808SJens Wiklander return ret; 17632b31808SJens Wiklander } 17732b31808SJens Wiklander #else 17832b31808SJens Wiklander ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, 17932b31808SJens Wiklander p + 2, end - p - 2, &kkpp_len, 18032b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 18132b31808SJens Wiklander if (ret != 0) { 18232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, 18332b31808SJens Wiklander "mbedtls_ecjpake_write_round_one", ret); 18432b31808SJens Wiklander return ret; 18532b31808SJens Wiklander } 18632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 18732b31808SJens Wiklander 18832b31808SJens Wiklander ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len); 18932b31808SJens Wiklander if (ssl->handshake->ecjpake_cache == NULL) { 19032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed")); 19132b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED; 19232b31808SJens Wiklander } 19332b31808SJens Wiklander 19432b31808SJens Wiklander memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len); 19532b31808SJens Wiklander ssl->handshake->ecjpake_cache_len = kkpp_len; 19632b31808SJens Wiklander } else { 19732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters")); 19832b31808SJens Wiklander 19932b31808SJens Wiklander kkpp_len = ssl->handshake->ecjpake_cache_len; 20032b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len); 20132b31808SJens Wiklander 20232b31808SJens Wiklander memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len); 20332b31808SJens Wiklander } 20432b31808SJens Wiklander 20532b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0); 20632b31808SJens Wiklander p += 2; 20732b31808SJens Wiklander 20832b31808SJens Wiklander *olen = kkpp_len + 4; 20932b31808SJens Wiklander 21032b31808SJens Wiklander return 0; 21132b31808SJens Wiklander } 21232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 21332b31808SJens Wiklander 21432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 21532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 21632b31808SJens Wiklander static int ssl_write_cid_ext(mbedtls_ssl_context *ssl, 21732b31808SJens Wiklander unsigned char *buf, 21832b31808SJens Wiklander const unsigned char *end, 21932b31808SJens Wiklander size_t *olen) 22032b31808SJens Wiklander { 22132b31808SJens Wiklander unsigned char *p = buf; 22232b31808SJens Wiklander size_t ext_len; 22332b31808SJens Wiklander 22432b31808SJens Wiklander /* 22532b31808SJens Wiklander * struct { 22632b31808SJens Wiklander * opaque cid<0..2^8-1>; 22732b31808SJens Wiklander * } ConnectionId; 22832b31808SJens Wiklander */ 22932b31808SJens Wiklander 23032b31808SJens Wiklander *olen = 0; 23132b31808SJens Wiklander if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || 23232b31808SJens Wiklander ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { 23332b31808SJens Wiklander return 0; 23432b31808SJens Wiklander } 23532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding CID extension")); 23632b31808SJens Wiklander 23732b31808SJens Wiklander /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX 23832b31808SJens Wiklander * which is at most 255, so the increment cannot overflow. */ 23932b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, (unsigned) (ssl->own_cid_len + 5)); 24032b31808SJens Wiklander 24132b31808SJens Wiklander /* Add extension ID + size */ 24232b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0); 24332b31808SJens Wiklander p += 2; 24432b31808SJens Wiklander ext_len = (size_t) ssl->own_cid_len + 1; 24532b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 24632b31808SJens Wiklander p += 2; 24732b31808SJens Wiklander 24832b31808SJens Wiklander *p++ = (uint8_t) ssl->own_cid_len; 24932b31808SJens Wiklander memcpy(p, ssl->own_cid, ssl->own_cid_len); 25032b31808SJens Wiklander 25132b31808SJens Wiklander *olen = ssl->own_cid_len + 5; 25232b31808SJens Wiklander 25332b31808SJens Wiklander return 0; 25432b31808SJens Wiklander } 25532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 25632b31808SJens Wiklander 25732b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 25832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 25932b31808SJens Wiklander static int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl, 26032b31808SJens Wiklander unsigned char *buf, 26132b31808SJens Wiklander const unsigned char *end, 26232b31808SJens Wiklander size_t *olen) 26332b31808SJens Wiklander { 26432b31808SJens Wiklander unsigned char *p = buf; 26532b31808SJens Wiklander 26632b31808SJens Wiklander *olen = 0; 26732b31808SJens Wiklander 26832b31808SJens Wiklander if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) { 26932b31808SJens Wiklander return 0; 27032b31808SJens Wiklander } 27132b31808SJens Wiklander 27232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 27332b31808SJens Wiklander ("client hello, adding max_fragment_length extension")); 27432b31808SJens Wiklander 27532b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5); 27632b31808SJens Wiklander 27732b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0); 27832b31808SJens Wiklander p += 2; 27932b31808SJens Wiklander 28032b31808SJens Wiklander *p++ = 0x00; 28132b31808SJens Wiklander *p++ = 1; 28232b31808SJens Wiklander 28332b31808SJens Wiklander *p++ = ssl->conf->mfl_code; 28432b31808SJens Wiklander 28532b31808SJens Wiklander *olen = 5; 28632b31808SJens Wiklander 28732b31808SJens Wiklander return 0; 28832b31808SJens Wiklander } 28932b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 29032b31808SJens Wiklander 29132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 29232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 29332b31808SJens Wiklander static int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 29432b31808SJens Wiklander unsigned char *buf, 29532b31808SJens Wiklander const unsigned char *end, 29632b31808SJens Wiklander size_t *olen) 29732b31808SJens Wiklander { 29832b31808SJens Wiklander unsigned char *p = buf; 29932b31808SJens Wiklander 30032b31808SJens Wiklander *olen = 0; 30132b31808SJens Wiklander 30232b31808SJens Wiklander if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) { 30332b31808SJens Wiklander return 0; 30432b31808SJens Wiklander } 30532b31808SJens Wiklander 30632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 30732b31808SJens Wiklander ("client hello, adding encrypt_then_mac extension")); 30832b31808SJens Wiklander 30932b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 31032b31808SJens Wiklander 31132b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0); 31232b31808SJens Wiklander p += 2; 31332b31808SJens Wiklander 31432b31808SJens Wiklander *p++ = 0x00; 31532b31808SJens Wiklander *p++ = 0x00; 31632b31808SJens Wiklander 31732b31808SJens Wiklander *olen = 4; 31832b31808SJens Wiklander 31932b31808SJens Wiklander return 0; 32032b31808SJens Wiklander } 32132b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 32232b31808SJens Wiklander 32332b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 32432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 32532b31808SJens Wiklander static int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl, 32632b31808SJens Wiklander unsigned char *buf, 32732b31808SJens Wiklander const unsigned char *end, 32832b31808SJens Wiklander size_t *olen) 32932b31808SJens Wiklander { 33032b31808SJens Wiklander unsigned char *p = buf; 33132b31808SJens Wiklander 33232b31808SJens Wiklander *olen = 0; 33332b31808SJens Wiklander 33432b31808SJens Wiklander if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) { 33532b31808SJens Wiklander return 0; 33632b31808SJens Wiklander } 33732b31808SJens Wiklander 33832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 33932b31808SJens Wiklander ("client hello, adding extended_master_secret extension")); 34032b31808SJens Wiklander 34132b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 34232b31808SJens Wiklander 34332b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0); 34432b31808SJens Wiklander p += 2; 34532b31808SJens Wiklander 34632b31808SJens Wiklander *p++ = 0x00; 34732b31808SJens Wiklander *p++ = 0x00; 34832b31808SJens Wiklander 34932b31808SJens Wiklander *olen = 4; 35032b31808SJens Wiklander 35132b31808SJens Wiklander return 0; 35232b31808SJens Wiklander } 35332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 35432b31808SJens Wiklander 35532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 35632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 35732b31808SJens Wiklander static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl, 35832b31808SJens Wiklander unsigned char *buf, 35932b31808SJens Wiklander const unsigned char *end, 36032b31808SJens Wiklander size_t *olen) 36132b31808SJens Wiklander { 36232b31808SJens Wiklander unsigned char *p = buf; 36332b31808SJens Wiklander size_t tlen = ssl->session_negotiate->ticket_len; 36432b31808SJens Wiklander 36532b31808SJens Wiklander *olen = 0; 36632b31808SJens Wiklander 367cb034002SJerome Forissier if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) == 368cb034002SJerome Forissier MBEDTLS_SSL_SESSION_TICKETS_DISABLED) { 36932b31808SJens Wiklander return 0; 37032b31808SJens Wiklander } 37132b31808SJens Wiklander 37232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 37332b31808SJens Wiklander ("client hello, adding session ticket extension")); 37432b31808SJens Wiklander 37532b31808SJens Wiklander /* The addition is safe here since the ticket length is 16 bit. */ 37632b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + tlen); 37732b31808SJens Wiklander 37832b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0); 37932b31808SJens Wiklander p += 2; 38032b31808SJens Wiklander 38132b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(tlen, p, 0); 38232b31808SJens Wiklander p += 2; 38332b31808SJens Wiklander 38432b31808SJens Wiklander *olen = 4; 38532b31808SJens Wiklander 38632b31808SJens Wiklander if (ssl->session_negotiate->ticket == NULL || tlen == 0) { 38732b31808SJens Wiklander return 0; 38832b31808SJens Wiklander } 38932b31808SJens Wiklander 39032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 39132b31808SJens Wiklander ("sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen)); 39232b31808SJens Wiklander 39332b31808SJens Wiklander memcpy(p, ssl->session_negotiate->ticket, tlen); 39432b31808SJens Wiklander 39532b31808SJens Wiklander *olen += tlen; 39632b31808SJens Wiklander 39732b31808SJens Wiklander return 0; 39832b31808SJens Wiklander } 39932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */ 40032b31808SJens Wiklander 40132b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) 40232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 40332b31808SJens Wiklander static int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl, 40432b31808SJens Wiklander unsigned char *buf, 40532b31808SJens Wiklander const unsigned char *end, 40632b31808SJens Wiklander size_t *olen) 40732b31808SJens Wiklander { 40832b31808SJens Wiklander unsigned char *p = buf; 40932b31808SJens Wiklander size_t protection_profiles_index = 0, ext_len = 0; 41032b31808SJens Wiklander uint16_t mki_len = 0, profile_value = 0; 41132b31808SJens Wiklander 41232b31808SJens Wiklander *olen = 0; 41332b31808SJens Wiklander 41432b31808SJens Wiklander if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 41532b31808SJens Wiklander (ssl->conf->dtls_srtp_profile_list == NULL) || 41632b31808SJens Wiklander (ssl->conf->dtls_srtp_profile_list_len == 0)) { 41732b31808SJens Wiklander return 0; 41832b31808SJens Wiklander } 41932b31808SJens Wiklander 42032b31808SJens Wiklander /* RFC 5764 section 4.1.1 42132b31808SJens Wiklander * uint8 SRTPProtectionProfile[2]; 42232b31808SJens Wiklander * 42332b31808SJens Wiklander * struct { 42432b31808SJens Wiklander * SRTPProtectionProfiles SRTPProtectionProfiles; 42532b31808SJens Wiklander * opaque srtp_mki<0..255>; 42632b31808SJens Wiklander * } UseSRTPData; 42732b31808SJens Wiklander * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; 42832b31808SJens Wiklander */ 42932b31808SJens Wiklander if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { 43032b31808SJens Wiklander mki_len = ssl->dtls_srtp_info.mki_len; 43132b31808SJens Wiklander } 43232b31808SJens Wiklander /* Extension length = 2 bytes for profiles length, 43332b31808SJens Wiklander * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ), 43432b31808SJens Wiklander * 1 byte for srtp_mki vector length and the mki_len value 43532b31808SJens Wiklander */ 43632b31808SJens Wiklander ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len; 43732b31808SJens Wiklander 43832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension")); 43932b31808SJens Wiklander 44032b31808SJens Wiklander /* Check there is room in the buffer for the extension + 4 bytes 44132b31808SJens Wiklander * - the extension tag (2 bytes) 44232b31808SJens Wiklander * - the extension length (2 bytes) 44332b31808SJens Wiklander */ 44432b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4); 44532b31808SJens Wiklander 44632b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0); 44732b31808SJens Wiklander p += 2; 44832b31808SJens Wiklander 44932b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 45032b31808SJens Wiklander p += 2; 45132b31808SJens Wiklander 45232b31808SJens Wiklander /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */ 45332b31808SJens Wiklander /* micro-optimization: 45432b31808SJens Wiklander * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 45532b31808SJens Wiklander * which is lower than 127, so the upper byte of the length is always 0 45632b31808SJens Wiklander * For the documentation, the more generic code is left in comments 45732b31808SJens Wiklander * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) 45832b31808SJens Wiklander * >> 8 ) & 0xFF ); 45932b31808SJens Wiklander */ 46032b31808SJens Wiklander *p++ = 0; 46132b31808SJens Wiklander *p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len); 46232b31808SJens Wiklander 46332b31808SJens Wiklander for (protection_profiles_index = 0; 46432b31808SJens Wiklander protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; 46532b31808SJens Wiklander protection_profiles_index++) { 46632b31808SJens Wiklander profile_value = mbedtls_ssl_check_srtp_profile_value 46732b31808SJens Wiklander (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]); 46832b31808SJens Wiklander if (profile_value != MBEDTLS_TLS_SRTP_UNSET) { 46932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x", 47032b31808SJens Wiklander profile_value)); 47132b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(profile_value, p, 0); 47232b31808SJens Wiklander p += 2; 47332b31808SJens Wiklander } else { 47432b31808SJens Wiklander /* 47532b31808SJens Wiklander * Note: we shall never arrive here as protection profiles 47632b31808SJens Wiklander * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function 47732b31808SJens Wiklander */ 47832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 47932b31808SJens Wiklander ("client hello, " 48032b31808SJens Wiklander "illegal DTLS-SRTP protection profile %d", 48132b31808SJens Wiklander ssl->conf->dtls_srtp_profile_list[protection_profiles_index] 48232b31808SJens Wiklander )); 48332b31808SJens Wiklander return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 48432b31808SJens Wiklander } 48532b31808SJens Wiklander } 48632b31808SJens Wiklander 48732b31808SJens Wiklander *p++ = mki_len & 0xFF; 48832b31808SJens Wiklander 48932b31808SJens Wiklander if (mki_len != 0) { 49032b31808SJens Wiklander memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len); 49132b31808SJens Wiklander /* 49232b31808SJens Wiklander * Increment p to point to the current position. 49332b31808SJens Wiklander */ 49432b31808SJens Wiklander p += mki_len; 49532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "sending mki", ssl->dtls_srtp_info.mki_value, 49632b31808SJens Wiklander ssl->dtls_srtp_info.mki_len); 49732b31808SJens Wiklander } 49832b31808SJens Wiklander 49932b31808SJens Wiklander /* 50032b31808SJens Wiklander * total extension length: extension type (2 bytes) 50132b31808SJens Wiklander * + extension length (2 bytes) 50232b31808SJens Wiklander * + protection profile length (2 bytes) 50332b31808SJens Wiklander * + 2 * number of protection profiles 50432b31808SJens Wiklander * + srtp_mki vector length(1 byte) 50532b31808SJens Wiklander * + mki value 50632b31808SJens Wiklander */ 50732b31808SJens Wiklander *olen = p - buf; 50832b31808SJens Wiklander 50932b31808SJens Wiklander return 0; 51032b31808SJens Wiklander } 51132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */ 51232b31808SJens Wiklander 51332b31808SJens Wiklander int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl, 51432b31808SJens Wiklander unsigned char *buf, 51532b31808SJens Wiklander const unsigned char *end, 51632b31808SJens Wiklander int uses_ec, 51732b31808SJens Wiklander size_t *out_len) 51832b31808SJens Wiklander { 51932b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 52032b31808SJens Wiklander unsigned char *p = buf; 52132b31808SJens Wiklander size_t ext_len = 0; 52232b31808SJens Wiklander 52332b31808SJens Wiklander (void) ssl; 52432b31808SJens Wiklander (void) end; 52532b31808SJens Wiklander (void) uses_ec; 52632b31808SJens Wiklander (void) ret; 52732b31808SJens Wiklander (void) ext_len; 52832b31808SJens Wiklander 52932b31808SJens Wiklander *out_len = 0; 53032b31808SJens Wiklander 53132b31808SJens Wiklander /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added 53232b31808SJens Wiklander * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ 53332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 53432b31808SJens Wiklander if ((ret = ssl_write_renegotiation_ext(ssl, p, end, &ext_len)) != 0) { 53532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_renegotiation_ext", ret); 53632b31808SJens Wiklander return ret; 53732b31808SJens Wiklander } 53832b31808SJens Wiklander p += ext_len; 53932b31808SJens Wiklander #endif 54032b31808SJens Wiklander 541b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 542b0563631STom Van Eyck defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 54332b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 54432b31808SJens Wiklander if (uses_ec) { 54532b31808SJens Wiklander if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end, 54632b31808SJens Wiklander &ext_len)) != 0) { 54732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_supported_point_formats_ext", ret); 54832b31808SJens Wiklander return ret; 54932b31808SJens Wiklander } 55032b31808SJens Wiklander p += ext_len; 55132b31808SJens Wiklander } 55232b31808SJens Wiklander #endif 55332b31808SJens Wiklander 55432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 55532b31808SJens Wiklander if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p, end, &ext_len)) != 0) { 55632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); 55732b31808SJens Wiklander return ret; 55832b31808SJens Wiklander } 55932b31808SJens Wiklander p += ext_len; 56032b31808SJens Wiklander #endif 56132b31808SJens Wiklander 56232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 56332b31808SJens Wiklander if ((ret = ssl_write_cid_ext(ssl, p, end, &ext_len)) != 0) { 56432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_cid_ext", ret); 56532b31808SJens Wiklander return ret; 56632b31808SJens Wiklander } 56732b31808SJens Wiklander p += ext_len; 56832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 56932b31808SJens Wiklander 57032b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 57132b31808SJens Wiklander if ((ret = ssl_write_max_fragment_length_ext(ssl, p, end, 57232b31808SJens Wiklander &ext_len)) != 0) { 57332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_max_fragment_length_ext", ret); 57432b31808SJens Wiklander return ret; 57532b31808SJens Wiklander } 57632b31808SJens Wiklander p += ext_len; 57732b31808SJens Wiklander #endif 57832b31808SJens Wiklander 57932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 58032b31808SJens Wiklander if ((ret = ssl_write_encrypt_then_mac_ext(ssl, p, end, &ext_len)) != 0) { 58132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_encrypt_then_mac_ext", ret); 58232b31808SJens Wiklander return ret; 58332b31808SJens Wiklander } 58432b31808SJens Wiklander p += ext_len; 58532b31808SJens Wiklander #endif 58632b31808SJens Wiklander 58732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 58832b31808SJens Wiklander if ((ret = ssl_write_extended_ms_ext(ssl, p, end, &ext_len)) != 0) { 58932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_extended_ms_ext", ret); 59032b31808SJens Wiklander return ret; 59132b31808SJens Wiklander } 59232b31808SJens Wiklander p += ext_len; 59332b31808SJens Wiklander #endif 59432b31808SJens Wiklander 59532b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) 59632b31808SJens Wiklander if ((ret = ssl_write_use_srtp_ext(ssl, p, end, &ext_len)) != 0) { 59732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_use_srtp_ext", ret); 59832b31808SJens Wiklander return ret; 59932b31808SJens Wiklander } 60032b31808SJens Wiklander p += ext_len; 60132b31808SJens Wiklander #endif 60232b31808SJens Wiklander 60332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 60432b31808SJens Wiklander if ((ret = ssl_write_session_ticket_ext(ssl, p, end, &ext_len)) != 0) { 60532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_session_ticket_ext", ret); 60632b31808SJens Wiklander return ret; 60732b31808SJens Wiklander } 60832b31808SJens Wiklander p += ext_len; 60932b31808SJens Wiklander #endif 61032b31808SJens Wiklander 611b0563631STom Van Eyck *out_len = (size_t) (p - buf); 61232b31808SJens Wiklander 61332b31808SJens Wiklander return 0; 61432b31808SJens Wiklander } 61532b31808SJens Wiklander 61632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 61732b31808SJens Wiklander static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl, 61832b31808SJens Wiklander const unsigned char *buf, 61932b31808SJens Wiklander size_t len) 62032b31808SJens Wiklander { 62132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 62232b31808SJens Wiklander if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 62332b31808SJens Wiklander /* Check verify-data in constant-time. The length OTOH is no secret */ 62432b31808SJens Wiklander if (len != 1 + ssl->verify_data_len * 2 || 62532b31808SJens Wiklander buf[0] != ssl->verify_data_len * 2 || 62632b31808SJens Wiklander mbedtls_ct_memcmp(buf + 1, 62732b31808SJens Wiklander ssl->own_verify_data, ssl->verify_data_len) != 0 || 62832b31808SJens Wiklander mbedtls_ct_memcmp(buf + 1 + ssl->verify_data_len, 62932b31808SJens Wiklander ssl->peer_verify_data, ssl->verify_data_len) != 0) { 63032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info")); 63132b31808SJens Wiklander mbedtls_ssl_send_alert_message( 63232b31808SJens Wiklander ssl, 63332b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 63432b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 63532b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 63632b31808SJens Wiklander } 63732b31808SJens Wiklander } else 63832b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */ 63932b31808SJens Wiklander { 64032b31808SJens Wiklander if (len != 1 || buf[0] != 0x00) { 64132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 64232b31808SJens Wiklander ("non-zero length renegotiation info")); 64332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 64432b31808SJens Wiklander ssl, 64532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 64632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 64732b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 64832b31808SJens Wiklander } 64932b31808SJens Wiklander 65032b31808SJens Wiklander ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; 65132b31808SJens Wiklander } 65232b31808SJens Wiklander 65332b31808SJens Wiklander return 0; 65432b31808SJens Wiklander } 65532b31808SJens Wiklander 65632b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 65732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 65832b31808SJens Wiklander static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl, 65932b31808SJens Wiklander const unsigned char *buf, 66032b31808SJens Wiklander size_t len) 66132b31808SJens Wiklander { 66232b31808SJens Wiklander /* 66332b31808SJens Wiklander * server should use the extension only if we did, 66432b31808SJens Wiklander * and if so the server's value should match ours (and len is always 1) 66532b31808SJens Wiklander */ 66632b31808SJens Wiklander if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || 66732b31808SJens Wiklander len != 1 || 66832b31808SJens Wiklander buf[0] != ssl->conf->mfl_code) { 66932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 67032b31808SJens Wiklander ("non-matching max fragment length extension")); 67132b31808SJens Wiklander mbedtls_ssl_send_alert_message( 67232b31808SJens Wiklander ssl, 67332b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 67432b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 67532b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 67632b31808SJens Wiklander } 67732b31808SJens Wiklander 67832b31808SJens Wiklander return 0; 67932b31808SJens Wiklander } 68032b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 68132b31808SJens Wiklander 68232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 68332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 68432b31808SJens Wiklander static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl, 68532b31808SJens Wiklander const unsigned char *buf, 68632b31808SJens Wiklander size_t len) 68732b31808SJens Wiklander { 68832b31808SJens Wiklander size_t peer_cid_len; 68932b31808SJens Wiklander 69032b31808SJens Wiklander if ( /* CID extension only makes sense in DTLS */ 69132b31808SJens Wiklander ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || 69232b31808SJens Wiklander /* The server must only send the CID extension if we have offered it. */ 69332b31808SJens Wiklander ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { 69432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension unexpected")); 69532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 69632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 69732b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 69832b31808SJens Wiklander } 69932b31808SJens Wiklander 70032b31808SJens Wiklander if (len == 0) { 70132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 70232b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 70332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 70432b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 70532b31808SJens Wiklander } 70632b31808SJens Wiklander 70732b31808SJens Wiklander peer_cid_len = *buf++; 70832b31808SJens Wiklander len--; 70932b31808SJens Wiklander 71032b31808SJens Wiklander if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) { 71132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 71232b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 71332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 71432b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 71532b31808SJens Wiklander } 71632b31808SJens Wiklander 71732b31808SJens Wiklander if (len != peer_cid_len) { 71832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 71932b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 72032b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 72132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 72232b31808SJens Wiklander } 72332b31808SJens Wiklander 72432b31808SJens Wiklander ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; 72532b31808SJens Wiklander ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; 72632b31808SJens Wiklander memcpy(ssl->handshake->peer_cid, buf, peer_cid_len); 72732b31808SJens Wiklander 72832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated")); 72932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "Server CID", buf, peer_cid_len); 73032b31808SJens Wiklander 73132b31808SJens Wiklander return 0; 73232b31808SJens Wiklander } 73332b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 73432b31808SJens Wiklander 73532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 73632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 73732b31808SJens Wiklander static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 73832b31808SJens Wiklander const unsigned char *buf, 73932b31808SJens Wiklander size_t len) 74032b31808SJens Wiklander { 74132b31808SJens Wiklander if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || 74232b31808SJens Wiklander len != 0) { 74332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 74432b31808SJens Wiklander ("non-matching encrypt-then-MAC extension")); 74532b31808SJens Wiklander mbedtls_ssl_send_alert_message( 74632b31808SJens Wiklander ssl, 74732b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 74832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 74932b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 75032b31808SJens Wiklander } 75132b31808SJens Wiklander 75232b31808SJens Wiklander ((void) buf); 75332b31808SJens Wiklander 75432b31808SJens Wiklander ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; 75532b31808SJens Wiklander 75632b31808SJens Wiklander return 0; 75732b31808SJens Wiklander } 75832b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 75932b31808SJens Wiklander 76032b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 76132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 76232b31808SJens Wiklander static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl, 76332b31808SJens Wiklander const unsigned char *buf, 76432b31808SJens Wiklander size_t len) 76532b31808SJens Wiklander { 76632b31808SJens Wiklander if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || 76732b31808SJens Wiklander len != 0) { 76832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 76932b31808SJens Wiklander ("non-matching extended master secret extension")); 77032b31808SJens Wiklander mbedtls_ssl_send_alert_message( 77132b31808SJens Wiklander ssl, 77232b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 77332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 77432b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 77532b31808SJens Wiklander } 77632b31808SJens Wiklander 77732b31808SJens Wiklander ((void) buf); 77832b31808SJens Wiklander 77932b31808SJens Wiklander ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; 78032b31808SJens Wiklander 78132b31808SJens Wiklander return 0; 78232b31808SJens Wiklander } 78332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 78432b31808SJens Wiklander 78532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 78632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 78732b31808SJens Wiklander static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl, 78832b31808SJens Wiklander const unsigned char *buf, 78932b31808SJens Wiklander size_t len) 79032b31808SJens Wiklander { 791cb034002SJerome Forissier if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) == 792cb034002SJerome Forissier MBEDTLS_SSL_SESSION_TICKETS_DISABLED) || 79332b31808SJens Wiklander len != 0) { 79432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 79532b31808SJens Wiklander ("non-matching session ticket extension")); 79632b31808SJens Wiklander mbedtls_ssl_send_alert_message( 79732b31808SJens Wiklander ssl, 79832b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 79932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 80032b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 80132b31808SJens Wiklander } 80232b31808SJens Wiklander 80332b31808SJens Wiklander ((void) buf); 80432b31808SJens Wiklander 80532b31808SJens Wiklander ssl->handshake->new_session_ticket = 1; 80632b31808SJens Wiklander 80732b31808SJens Wiklander return 0; 80832b31808SJens Wiklander } 80932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */ 81032b31808SJens Wiklander 811b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 812b0563631STom Van Eyck defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 81332b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 81432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 81532b31808SJens Wiklander static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl, 81632b31808SJens Wiklander const unsigned char *buf, 81732b31808SJens Wiklander size_t len) 81832b31808SJens Wiklander { 81932b31808SJens Wiklander size_t list_size; 82032b31808SJens Wiklander const unsigned char *p; 82132b31808SJens Wiklander 82232b31808SJens Wiklander if (len == 0 || (size_t) (buf[0] + 1) != len) { 82332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 82432b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 82532b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 82632b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 82732b31808SJens Wiklander } 82832b31808SJens Wiklander list_size = buf[0]; 82932b31808SJens Wiklander 83032b31808SJens Wiklander p = buf + 1; 83132b31808SJens Wiklander while (list_size > 0) { 83232b31808SJens Wiklander if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || 83332b31808SJens Wiklander p[0] == MBEDTLS_ECP_PF_COMPRESSED) { 83432b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 835b0563631STom Van Eyck defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) 83632b31808SJens Wiklander ssl->handshake->ecdh_ctx.point_format = p[0]; 837b0563631STom Van Eyck #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ 83832b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 83932b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 84032b31808SJens Wiklander mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx, 84132b31808SJens Wiklander p[0]); 84232b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 84332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0])); 84432b31808SJens Wiklander return 0; 84532b31808SJens Wiklander } 84632b31808SJens Wiklander 84732b31808SJens Wiklander list_size--; 84832b31808SJens Wiklander p++; 84932b31808SJens Wiklander } 85032b31808SJens Wiklander 85132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("no point format in common")); 85232b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 85332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 85432b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 85532b31808SJens Wiklander } 856b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 857b0563631STom Van Eyck MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 85832b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 85932b31808SJens Wiklander 86032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 86132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 86232b31808SJens Wiklander static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl, 86332b31808SJens Wiklander const unsigned char *buf, 86432b31808SJens Wiklander size_t len) 86532b31808SJens Wiklander { 86632b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 86732b31808SJens Wiklander 86832b31808SJens Wiklander if (ssl->handshake->ciphersuite_info->key_exchange != 86932b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 87032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension")); 87132b31808SJens Wiklander return 0; 87232b31808SJens Wiklander } 87332b31808SJens Wiklander 87432b31808SJens Wiklander /* If we got here, we no longer need our cached extension */ 87532b31808SJens Wiklander mbedtls_free(ssl->handshake->ecjpake_cache); 87632b31808SJens Wiklander ssl->handshake->ecjpake_cache = NULL; 87732b31808SJens Wiklander ssl->handshake->ecjpake_cache_len = 0; 87832b31808SJens Wiklander 87932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 88032b31808SJens Wiklander if ((ret = mbedtls_psa_ecjpake_read_round( 88132b31808SJens Wiklander &ssl->handshake->psa_pake_ctx, buf, len, 88232b31808SJens Wiklander MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) { 88332b31808SJens Wiklander psa_destroy_key(ssl->handshake->psa_pake_password); 88432b31808SJens Wiklander psa_pake_abort(&ssl->handshake->psa_pake_ctx); 88532b31808SJens Wiklander 88632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret); 88732b31808SJens Wiklander mbedtls_ssl_send_alert_message( 88832b31808SJens Wiklander ssl, 88932b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 89032b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 89132b31808SJens Wiklander return ret; 89232b31808SJens Wiklander } 89332b31808SJens Wiklander 89432b31808SJens Wiklander return 0; 89532b31808SJens Wiklander #else 89632b31808SJens Wiklander if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx, 89732b31808SJens Wiklander buf, len)) != 0) { 89832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret); 89932b31808SJens Wiklander mbedtls_ssl_send_alert_message( 90032b31808SJens Wiklander ssl, 90132b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 90232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 90332b31808SJens Wiklander return ret; 90432b31808SJens Wiklander } 90532b31808SJens Wiklander 90632b31808SJens Wiklander return 0; 90732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 90832b31808SJens Wiklander } 90932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 91032b31808SJens Wiklander 91132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN) 91232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 91332b31808SJens Wiklander static int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl, 91432b31808SJens Wiklander const unsigned char *buf, size_t len) 91532b31808SJens Wiklander { 91632b31808SJens Wiklander size_t list_len, name_len; 91732b31808SJens Wiklander const char **p; 91832b31808SJens Wiklander 91932b31808SJens Wiklander /* If we didn't send it, the server shouldn't send it */ 92032b31808SJens Wiklander if (ssl->conf->alpn_list == NULL) { 92132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching ALPN extension")); 92232b31808SJens Wiklander mbedtls_ssl_send_alert_message( 92332b31808SJens Wiklander ssl, 92432b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 92532b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 92632b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 92732b31808SJens Wiklander } 92832b31808SJens Wiklander 92932b31808SJens Wiklander /* 93032b31808SJens Wiklander * opaque ProtocolName<1..2^8-1>; 93132b31808SJens Wiklander * 93232b31808SJens Wiklander * struct { 93332b31808SJens Wiklander * ProtocolName protocol_name_list<2..2^16-1> 93432b31808SJens Wiklander * } ProtocolNameList; 93532b31808SJens Wiklander * 93632b31808SJens Wiklander * the "ProtocolNameList" MUST contain exactly one "ProtocolName" 93732b31808SJens Wiklander */ 93832b31808SJens Wiklander 93932b31808SJens Wiklander /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ 94032b31808SJens Wiklander if (len < 4) { 94132b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 94232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 94332b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 94432b31808SJens Wiklander } 94532b31808SJens Wiklander 946b0563631STom Van Eyck list_len = MBEDTLS_GET_UINT16_BE(buf, 0); 94732b31808SJens Wiklander if (list_len != len - 2) { 94832b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 94932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 95032b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 95132b31808SJens Wiklander } 95232b31808SJens Wiklander 95332b31808SJens Wiklander name_len = buf[2]; 95432b31808SJens Wiklander if (name_len != list_len - 1) { 95532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 95632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 95732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 95832b31808SJens Wiklander } 95932b31808SJens Wiklander 96032b31808SJens Wiklander /* Check that the server chosen protocol was in our list and save it */ 96132b31808SJens Wiklander for (p = ssl->conf->alpn_list; *p != NULL; p++) { 96232b31808SJens Wiklander if (name_len == strlen(*p) && 96332b31808SJens Wiklander memcmp(buf + 3, *p, name_len) == 0) { 96432b31808SJens Wiklander ssl->alpn_chosen = *p; 96532b31808SJens Wiklander return 0; 96632b31808SJens Wiklander } 96732b31808SJens Wiklander } 96832b31808SJens Wiklander 96932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("ALPN extension: no matching protocol")); 97032b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 97132b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 97232b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 97332b31808SJens Wiklander } 97432b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */ 97532b31808SJens Wiklander 97632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) 97732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 97832b31808SJens Wiklander static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, 97932b31808SJens Wiklander const unsigned char *buf, 98032b31808SJens Wiklander size_t len) 98132b31808SJens Wiklander { 98232b31808SJens Wiklander mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET; 98332b31808SJens Wiklander size_t i, mki_len = 0; 98432b31808SJens Wiklander uint16_t server_protection_profile_value = 0; 98532b31808SJens Wiklander 98632b31808SJens Wiklander /* If use_srtp is not configured, just ignore the extension */ 98732b31808SJens Wiklander if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 98832b31808SJens Wiklander (ssl->conf->dtls_srtp_profile_list == NULL) || 98932b31808SJens Wiklander (ssl->conf->dtls_srtp_profile_list_len == 0)) { 99032b31808SJens Wiklander return 0; 99132b31808SJens Wiklander } 99232b31808SJens Wiklander 99332b31808SJens Wiklander /* RFC 5764 section 4.1.1 99432b31808SJens Wiklander * uint8 SRTPProtectionProfile[2]; 99532b31808SJens Wiklander * 99632b31808SJens Wiklander * struct { 99732b31808SJens Wiklander * SRTPProtectionProfiles SRTPProtectionProfiles; 99832b31808SJens Wiklander * opaque srtp_mki<0..255>; 99932b31808SJens Wiklander * } UseSRTPData; 100032b31808SJens Wiklander 100132b31808SJens Wiklander * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; 100232b31808SJens Wiklander * 100332b31808SJens Wiklander */ 100432b31808SJens Wiklander if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { 100532b31808SJens Wiklander mki_len = ssl->dtls_srtp_info.mki_len; 100632b31808SJens Wiklander } 100732b31808SJens Wiklander 100832b31808SJens Wiklander /* 100932b31808SJens Wiklander * Length is 5 + optional mki_value : one protection profile length (2 bytes) 101032b31808SJens Wiklander * + protection profile (2 bytes) 101132b31808SJens Wiklander * + mki_len(1 byte) 101232b31808SJens Wiklander * and optional srtp_mki 101332b31808SJens Wiklander */ 101432b31808SJens Wiklander if ((len < 5) || (len != (buf[4] + 5u))) { 101532b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 101632b31808SJens Wiklander } 101732b31808SJens Wiklander 101832b31808SJens Wiklander /* 101932b31808SJens Wiklander * get the server protection profile 102032b31808SJens Wiklander */ 102132b31808SJens Wiklander 102232b31808SJens Wiklander /* 102332b31808SJens Wiklander * protection profile length must be 0x0002 as we must have only 102432b31808SJens Wiklander * one protection profile in server Hello 102532b31808SJens Wiklander */ 102632b31808SJens Wiklander if ((buf[0] != 0) || (buf[1] != 2)) { 102732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 102832b31808SJens Wiklander } 102932b31808SJens Wiklander 103032b31808SJens Wiklander server_protection_profile_value = (buf[2] << 8) | buf[3]; 103132b31808SJens Wiklander server_protection = mbedtls_ssl_check_srtp_profile_value( 103232b31808SJens Wiklander server_protection_profile_value); 103332b31808SJens Wiklander if (server_protection != MBEDTLS_TLS_SRTP_UNSET) { 103432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s", 103532b31808SJens Wiklander mbedtls_ssl_get_srtp_profile_as_string( 103632b31808SJens Wiklander server_protection))); 103732b31808SJens Wiklander } 103832b31808SJens Wiklander 103932b31808SJens Wiklander ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; 104032b31808SJens Wiklander 104132b31808SJens Wiklander /* 104232b31808SJens Wiklander * Check we have the server profile in our list 104332b31808SJens Wiklander */ 104432b31808SJens Wiklander for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) { 104532b31808SJens Wiklander if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) { 104632b31808SJens Wiklander ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; 104732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s", 104832b31808SJens Wiklander mbedtls_ssl_get_srtp_profile_as_string( 104932b31808SJens Wiklander server_protection))); 105032b31808SJens Wiklander break; 105132b31808SJens Wiklander } 105232b31808SJens Wiklander } 105332b31808SJens Wiklander 105432b31808SJens Wiklander /* If no match was found : server problem, it shall never answer with incompatible profile */ 105532b31808SJens Wiklander if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) { 105632b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 105732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 105832b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 105932b31808SJens Wiklander } 106032b31808SJens Wiklander 106132b31808SJens Wiklander /* If server does not use mki in its reply, make sure the client won't keep 106232b31808SJens Wiklander * one as negotiated */ 106332b31808SJens Wiklander if (len == 5) { 106432b31808SJens Wiklander ssl->dtls_srtp_info.mki_len = 0; 106532b31808SJens Wiklander } 106632b31808SJens Wiklander 106732b31808SJens Wiklander /* 106832b31808SJens Wiklander * RFC5764: 106932b31808SJens Wiklander * If the client detects a nonzero-length MKI in the server's response 107032b31808SJens Wiklander * that is different than the one the client offered, then the client 107132b31808SJens Wiklander * MUST abort the handshake and SHOULD send an invalid_parameter alert. 107232b31808SJens Wiklander */ 107332b31808SJens Wiklander if (len > 5 && (buf[4] != mki_len || 107432b31808SJens Wiklander (memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) { 107532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 107632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 107732b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 107832b31808SJens Wiklander } 107932b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C) 108032b31808SJens Wiklander if (len > 5) { 108132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value, 108232b31808SJens Wiklander ssl->dtls_srtp_info.mki_len); 108332b31808SJens Wiklander } 108432b31808SJens Wiklander #endif 108532b31808SJens Wiklander return 0; 108632b31808SJens Wiklander } 108732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */ 108832b31808SJens Wiklander 108932b31808SJens Wiklander /* 109032b31808SJens Wiklander * Parse HelloVerifyRequest. Only called after verifying the HS type. 109132b31808SJens Wiklander */ 109232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 109332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 109432b31808SJens Wiklander static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) 109532b31808SJens Wiklander { 109632b31808SJens Wiklander int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 109732b31808SJens Wiklander const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 109832b31808SJens Wiklander uint16_t dtls_legacy_version; 109932b31808SJens Wiklander 110032b31808SJens Wiklander #if !defined(MBEDTLS_SSL_PROTO_TLS1_3) 110132b31808SJens Wiklander uint8_t cookie_len; 110232b31808SJens Wiklander #else 110332b31808SJens Wiklander uint16_t cookie_len; 110432b31808SJens Wiklander #endif 110532b31808SJens Wiklander 110632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse hello verify request")); 110732b31808SJens Wiklander 110832b31808SJens Wiklander /* Check that there is enough room for: 110932b31808SJens Wiklander * - 2 bytes of version 111032b31808SJens Wiklander * - 1 byte of cookie_len 111132b31808SJens Wiklander */ 111232b31808SJens Wiklander if (mbedtls_ssl_hs_hdr_len(ssl) + 3 > ssl->in_msglen) { 111332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 111432b31808SJens Wiklander ("incoming HelloVerifyRequest message is too short")); 111532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 111632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 111732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 111832b31808SJens Wiklander } 111932b31808SJens Wiklander 112032b31808SJens Wiklander /* 112132b31808SJens Wiklander * struct { 112232b31808SJens Wiklander * ProtocolVersion server_version; 112332b31808SJens Wiklander * opaque cookie<0..2^8-1>; 112432b31808SJens Wiklander * } HelloVerifyRequest; 112532b31808SJens Wiklander */ 112632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2); 112732b31808SJens Wiklander dtls_legacy_version = MBEDTLS_GET_UINT16_BE(p, 0); 112832b31808SJens Wiklander p += 2; 112932b31808SJens Wiklander 113032b31808SJens Wiklander /* 113132b31808SJens Wiklander * Since the RFC is not clear on this point, accept DTLS 1.0 (0xfeff) 113232b31808SJens Wiklander * The DTLS 1.3 (current draft) renames ProtocolVersion server_version to 113332b31808SJens Wiklander * legacy_version and locks the value of legacy_version to 0xfefd (DTLS 1.2) 113432b31808SJens Wiklander */ 113532b31808SJens Wiklander if (dtls_legacy_version != 0xfefd && dtls_legacy_version != 0xfeff) { 113632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server version")); 113732b31808SJens Wiklander 113832b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 113932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); 114032b31808SJens Wiklander 114132b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; 114232b31808SJens Wiklander } 114332b31808SJens Wiklander 114432b31808SJens Wiklander cookie_len = *p++; 114532b31808SJens Wiklander if ((ssl->in_msg + ssl->in_msglen) - p < cookie_len) { 114632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 114732b31808SJens Wiklander ("cookie length does not match incoming message size")); 114832b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 114932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 115032b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 115132b31808SJens Wiklander } 115232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "cookie", p, cookie_len); 115332b31808SJens Wiklander 115432b31808SJens Wiklander mbedtls_free(ssl->handshake->cookie); 115532b31808SJens Wiklander 115632b31808SJens Wiklander ssl->handshake->cookie = mbedtls_calloc(1, cookie_len); 115732b31808SJens Wiklander if (ssl->handshake->cookie == NULL) { 115832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("alloc failed (%d bytes)", cookie_len)); 115932b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED; 116032b31808SJens Wiklander } 116132b31808SJens Wiklander 116232b31808SJens Wiklander memcpy(ssl->handshake->cookie, p, cookie_len); 116332b31808SJens Wiklander ssl->handshake->cookie_len = cookie_len; 116432b31808SJens Wiklander 116532b31808SJens Wiklander /* Start over at ClientHello */ 116632b31808SJens Wiklander ssl->state = MBEDTLS_SSL_CLIENT_HELLO; 116732b31808SJens Wiklander ret = mbedtls_ssl_reset_checksum(ssl); 116832b31808SJens Wiklander if (0 != ret) { 116932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret); 117032b31808SJens Wiklander return ret; 117132b31808SJens Wiklander } 117232b31808SJens Wiklander 117332b31808SJens Wiklander mbedtls_ssl_recv_flight_completed(ssl); 117432b31808SJens Wiklander 117532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse hello verify request")); 117632b31808SJens Wiklander 117732b31808SJens Wiklander return 0; 117832b31808SJens Wiklander } 117932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */ 118032b31808SJens Wiklander 118132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 118232b31808SJens Wiklander static int ssl_parse_server_hello(mbedtls_ssl_context *ssl) 118332b31808SJens Wiklander { 118432b31808SJens Wiklander int ret, i; 118532b31808SJens Wiklander size_t n; 118632b31808SJens Wiklander size_t ext_len; 118732b31808SJens Wiklander unsigned char *buf, *ext; 118832b31808SJens Wiklander unsigned char comp; 118932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 119032b31808SJens Wiklander int renegotiation_info_seen = 0; 119132b31808SJens Wiklander #endif 119232b31808SJens Wiklander int handshake_failure = 0; 119332b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *suite_info; 119432b31808SJens Wiklander 119532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello")); 119632b31808SJens Wiklander 119732b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 119832b31808SJens Wiklander /* No alert on a read error. */ 119932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 120032b31808SJens Wiklander return ret; 120132b31808SJens Wiklander } 120232b31808SJens Wiklander 120332b31808SJens Wiklander buf = ssl->in_msg; 120432b31808SJens Wiklander 120532b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 120632b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 120732b31808SJens Wiklander if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 120832b31808SJens Wiklander ssl->renego_records_seen++; 120932b31808SJens Wiklander 121032b31808SJens Wiklander if (ssl->conf->renego_max_records >= 0 && 121132b31808SJens Wiklander ssl->renego_records_seen > ssl->conf->renego_max_records) { 121232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 121332b31808SJens Wiklander ("renegotiation requested, but not honored by server")); 121432b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 121532b31808SJens Wiklander } 121632b31808SJens Wiklander 121732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 121832b31808SJens Wiklander ("non-handshake message during renegotiation")); 121932b31808SJens Wiklander 122032b31808SJens Wiklander ssl->keep_current_message = 1; 122132b31808SJens Wiklander return MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO; 122232b31808SJens Wiklander } 122332b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */ 122432b31808SJens Wiklander 122532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 122632b31808SJens Wiklander mbedtls_ssl_send_alert_message( 122732b31808SJens Wiklander ssl, 122832b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 122932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 123032b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 123132b31808SJens Wiklander } 123232b31808SJens Wiklander 123332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 123432b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 123532b31808SJens Wiklander if (buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) { 123632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("received hello verify request")); 123732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); 123832b31808SJens Wiklander return ssl_parse_hello_verify_request(ssl); 123932b31808SJens Wiklander } else { 124032b31808SJens Wiklander /* We made it through the verification process */ 124132b31808SJens Wiklander mbedtls_free(ssl->handshake->cookie); 124232b31808SJens Wiklander ssl->handshake->cookie = NULL; 124332b31808SJens Wiklander ssl->handshake->cookie_len = 0; 124432b31808SJens Wiklander } 124532b31808SJens Wiklander } 124632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */ 124732b31808SJens Wiklander 124832b31808SJens Wiklander if (ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len(ssl) || 124932b31808SJens Wiklander buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO) { 125032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 125132b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 125232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 125332b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 125432b31808SJens Wiklander } 125532b31808SJens Wiklander 125632b31808SJens Wiklander /* 125732b31808SJens Wiklander * 0 . 1 server_version 125832b31808SJens Wiklander * 2 . 33 random (maybe including 4 bytes of Unix time) 125932b31808SJens Wiklander * 34 . 34 session_id length = n 126032b31808SJens Wiklander * 35 . 34+n session_id 126132b31808SJens Wiklander * 35+n . 36+n cipher_suite 126232b31808SJens Wiklander * 37+n . 37+n compression_method 126332b31808SJens Wiklander * 126432b31808SJens Wiklander * 38+n . 39+n extensions length (optional) 126532b31808SJens Wiklander * 40+n . .. extensions 126632b31808SJens Wiklander */ 126732b31808SJens Wiklander buf += mbedtls_ssl_hs_hdr_len(ssl); 126832b31808SJens Wiklander 126932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2); 1270b0563631STom Van Eyck ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf, 1271b0563631STom Van Eyck ssl->conf->transport); 127232b31808SJens Wiklander ssl->session_negotiate->tls_version = ssl->tls_version; 1273b0563631STom Van Eyck ssl->session_negotiate->endpoint = ssl->conf->endpoint; 127432b31808SJens Wiklander 127532b31808SJens Wiklander if (ssl->tls_version < ssl->conf->min_tls_version || 127632b31808SJens Wiklander ssl->tls_version > ssl->conf->max_tls_version) { 127732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 127832b31808SJens Wiklander ( 127932b31808SJens Wiklander "server version out of bounds - min: [0x%x], server: [0x%x], max: [0x%x]", 128032b31808SJens Wiklander (unsigned) ssl->conf->min_tls_version, 128132b31808SJens Wiklander (unsigned) ssl->tls_version, 128232b31808SJens Wiklander (unsigned) ssl->conf->max_tls_version)); 128332b31808SJens Wiklander 128432b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 128532b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); 128632b31808SJens Wiklander 128732b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; 128832b31808SJens Wiklander } 128932b31808SJens Wiklander 129032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %lu", 129132b31808SJens Wiklander ((unsigned long) buf[2] << 24) | 129232b31808SJens Wiklander ((unsigned long) buf[3] << 16) | 129332b31808SJens Wiklander ((unsigned long) buf[4] << 8) | 129432b31808SJens Wiklander ((unsigned long) buf[5]))); 129532b31808SJens Wiklander 129632b31808SJens Wiklander memcpy(ssl->handshake->randbytes + 32, buf + 2, 32); 129732b31808SJens Wiklander 129832b31808SJens Wiklander n = buf[34]; 129932b31808SJens Wiklander 130032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 2, 32); 130132b31808SJens Wiklander 130232b31808SJens Wiklander if (n > 32) { 130332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 130432b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 130532b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 130632b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 130732b31808SJens Wiklander } 130832b31808SJens Wiklander 130932b31808SJens Wiklander if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) { 1310b0563631STom Van Eyck ext_len = MBEDTLS_GET_UINT16_BE(buf, 38 + n); 131132b31808SJens Wiklander 131232b31808SJens Wiklander if ((ext_len > 0 && ext_len < 4) || 131332b31808SJens Wiklander ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) { 131432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 131532b31808SJens Wiklander mbedtls_ssl_send_alert_message( 131632b31808SJens Wiklander ssl, 131732b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 131832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 131932b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 132032b31808SJens Wiklander } 132132b31808SJens Wiklander } else if (ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl) + 38 + n) { 132232b31808SJens Wiklander ext_len = 0; 132332b31808SJens Wiklander } else { 132432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 132532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 132632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 132732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 132832b31808SJens Wiklander } 132932b31808SJens Wiklander 133032b31808SJens Wiklander /* ciphersuite (used later) */ 1331b0563631STom Van Eyck i = (int) MBEDTLS_GET_UINT16_BE(buf, n + 35); 133232b31808SJens Wiklander 133332b31808SJens Wiklander /* 133432b31808SJens Wiklander * Read and check compression 133532b31808SJens Wiklander */ 133632b31808SJens Wiklander comp = buf[37 + n]; 133732b31808SJens Wiklander 133832b31808SJens Wiklander if (comp != MBEDTLS_SSL_COMPRESS_NULL) { 133932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 134032b31808SJens Wiklander ("server hello, bad compression: %d", comp)); 134132b31808SJens Wiklander mbedtls_ssl_send_alert_message( 134232b31808SJens Wiklander ssl, 134332b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 134432b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 134532b31808SJens Wiklander return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 134632b31808SJens Wiklander } 134732b31808SJens Wiklander 134832b31808SJens Wiklander /* 134932b31808SJens Wiklander * Initialize update checksum functions 135032b31808SJens Wiklander */ 135132b31808SJens Wiklander ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(i); 135232b31808SJens Wiklander if (ssl->handshake->ciphersuite_info == NULL) { 135332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 135432b31808SJens Wiklander ("ciphersuite info for %04x not found", (unsigned int) i)); 135532b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 135632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 135732b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 135832b31808SJens Wiklander } 135932b31808SJens Wiklander 136032b31808SJens Wiklander mbedtls_ssl_optimize_checksum(ssl, ssl->handshake->ciphersuite_info); 136132b31808SJens Wiklander 136232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n)); 136332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "server hello, session id", buf + 35, n); 136432b31808SJens Wiklander 136532b31808SJens Wiklander /* 136632b31808SJens Wiklander * Check if the session can be resumed 136732b31808SJens Wiklander */ 136832b31808SJens Wiklander if (ssl->handshake->resume == 0 || n == 0 || 136932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 137032b31808SJens Wiklander ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || 137132b31808SJens Wiklander #endif 137232b31808SJens Wiklander ssl->session_negotiate->ciphersuite != i || 137332b31808SJens Wiklander ssl->session_negotiate->id_len != n || 137432b31808SJens Wiklander memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) { 137532b31808SJens Wiklander ssl->state++; 137632b31808SJens Wiklander ssl->handshake->resume = 0; 137732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME) 137832b31808SJens Wiklander ssl->session_negotiate->start = mbedtls_time(NULL); 137932b31808SJens Wiklander #endif 138032b31808SJens Wiklander ssl->session_negotiate->ciphersuite = i; 138132b31808SJens Wiklander ssl->session_negotiate->id_len = n; 138232b31808SJens Wiklander memcpy(ssl->session_negotiate->id, buf + 35, n); 138332b31808SJens Wiklander } else { 138432b31808SJens Wiklander ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; 138532b31808SJens Wiklander } 138632b31808SJens Wiklander 138732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", 138832b31808SJens Wiklander ssl->handshake->resume ? "a" : "no")); 138932b31808SJens Wiklander 139032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %04x", (unsigned) i)); 139132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d", 139232b31808SJens Wiklander buf[37 + n])); 139332b31808SJens Wiklander 139432b31808SJens Wiklander /* 139532b31808SJens Wiklander * Perform cipher suite validation in same way as in ssl_write_client_hello. 139632b31808SJens Wiklander */ 139732b31808SJens Wiklander i = 0; 139832b31808SJens Wiklander while (1) { 139932b31808SJens Wiklander if (ssl->conf->ciphersuite_list[i] == 0) { 140032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 140132b31808SJens Wiklander mbedtls_ssl_send_alert_message( 140232b31808SJens Wiklander ssl, 140332b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 140432b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 140532b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 140632b31808SJens Wiklander } 140732b31808SJens Wiklander 140832b31808SJens Wiklander if (ssl->conf->ciphersuite_list[i++] == 140932b31808SJens Wiklander ssl->session_negotiate->ciphersuite) { 141032b31808SJens Wiklander break; 141132b31808SJens Wiklander } 141232b31808SJens Wiklander } 141332b31808SJens Wiklander 141432b31808SJens Wiklander suite_info = mbedtls_ssl_ciphersuite_from_id( 141532b31808SJens Wiklander ssl->session_negotiate->ciphersuite); 141632b31808SJens Wiklander if (mbedtls_ssl_validate_ciphersuite(ssl, suite_info, ssl->tls_version, 141732b31808SJens Wiklander ssl->tls_version) != 0) { 141832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 141932b31808SJens Wiklander mbedtls_ssl_send_alert_message( 142032b31808SJens Wiklander ssl, 142132b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 142232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 142332b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 142432b31808SJens Wiklander } 142532b31808SJens Wiklander 142632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 142732b31808SJens Wiklander ("server hello, chosen ciphersuite: %s", suite_info->name)); 142832b31808SJens Wiklander 142932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 143032b31808SJens Wiklander if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && 143132b31808SJens Wiklander ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { 143232b31808SJens Wiklander ssl->handshake->ecrs_enabled = 1; 143332b31808SJens Wiklander } 143432b31808SJens Wiklander #endif 143532b31808SJens Wiklander 143632b31808SJens Wiklander if (comp != MBEDTLS_SSL_COMPRESS_NULL) { 143732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 143832b31808SJens Wiklander mbedtls_ssl_send_alert_message( 143932b31808SJens Wiklander ssl, 144032b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 144132b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 144232b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 144332b31808SJens Wiklander } 144432b31808SJens Wiklander 144532b31808SJens Wiklander ext = buf + 40 + n; 144632b31808SJens Wiklander 144732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 144832b31808SJens Wiklander ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, 144932b31808SJens Wiklander ext_len)); 145032b31808SJens Wiklander 145132b31808SJens Wiklander while (ext_len) { 1452b0563631STom Van Eyck unsigned int ext_id = MBEDTLS_GET_UINT16_BE(ext, 0); 1453b0563631STom Van Eyck unsigned int ext_size = MBEDTLS_GET_UINT16_BE(ext, 2); 145432b31808SJens Wiklander 145532b31808SJens Wiklander if (ext_size + 4 > ext_len) { 145632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 145732b31808SJens Wiklander mbedtls_ssl_send_alert_message( 145832b31808SJens Wiklander ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 145932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 146032b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 146132b31808SJens Wiklander } 146232b31808SJens Wiklander 146332b31808SJens Wiklander switch (ext_id) { 146432b31808SJens Wiklander case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: 146532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension")); 146632b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 146732b31808SJens Wiklander renegotiation_info_seen = 1; 146832b31808SJens Wiklander #endif 146932b31808SJens Wiklander 147032b31808SJens Wiklander if ((ret = ssl_parse_renegotiation_info(ssl, ext + 4, 147132b31808SJens Wiklander ext_size)) != 0) { 147232b31808SJens Wiklander return ret; 147332b31808SJens Wiklander } 147432b31808SJens Wiklander 147532b31808SJens Wiklander break; 147632b31808SJens Wiklander 147732b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 147832b31808SJens Wiklander case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: 147932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 148032b31808SJens Wiklander ("found max_fragment_length extension")); 148132b31808SJens Wiklander 148232b31808SJens Wiklander if ((ret = ssl_parse_max_fragment_length_ext(ssl, 148332b31808SJens Wiklander ext + 4, ext_size)) != 0) { 148432b31808SJens Wiklander return ret; 148532b31808SJens Wiklander } 148632b31808SJens Wiklander 148732b31808SJens Wiklander break; 148832b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 148932b31808SJens Wiklander 149032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 149132b31808SJens Wiklander case MBEDTLS_TLS_EXT_CID: 149232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension")); 149332b31808SJens Wiklander 149432b31808SJens Wiklander if ((ret = ssl_parse_cid_ext(ssl, 149532b31808SJens Wiklander ext + 4, 149632b31808SJens Wiklander ext_size)) != 0) { 149732b31808SJens Wiklander return ret; 149832b31808SJens Wiklander } 149932b31808SJens Wiklander 150032b31808SJens Wiklander break; 150132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 150232b31808SJens Wiklander 150332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 150432b31808SJens Wiklander case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: 150532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt_then_mac extension")); 150632b31808SJens Wiklander 150732b31808SJens Wiklander if ((ret = ssl_parse_encrypt_then_mac_ext(ssl, 150832b31808SJens Wiklander ext + 4, ext_size)) != 0) { 150932b31808SJens Wiklander return ret; 151032b31808SJens Wiklander } 151132b31808SJens Wiklander 151232b31808SJens Wiklander break; 151332b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 151432b31808SJens Wiklander 151532b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 151632b31808SJens Wiklander case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: 151732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 151832b31808SJens Wiklander ("found extended_master_secret extension")); 151932b31808SJens Wiklander 152032b31808SJens Wiklander if ((ret = ssl_parse_extended_ms_ext(ssl, 152132b31808SJens Wiklander ext + 4, ext_size)) != 0) { 152232b31808SJens Wiklander return ret; 152332b31808SJens Wiklander } 152432b31808SJens Wiklander 152532b31808SJens Wiklander break; 152632b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 152732b31808SJens Wiklander 152832b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 152932b31808SJens Wiklander case MBEDTLS_TLS_EXT_SESSION_TICKET: 153032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found session_ticket extension")); 153132b31808SJens Wiklander 153232b31808SJens Wiklander if ((ret = ssl_parse_session_ticket_ext(ssl, 153332b31808SJens Wiklander ext + 4, ext_size)) != 0) { 153432b31808SJens Wiklander return ret; 153532b31808SJens Wiklander } 153632b31808SJens Wiklander 153732b31808SJens Wiklander break; 153832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */ 153932b31808SJens Wiklander 1540b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 1541b0563631STom Van Eyck defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 154232b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 154332b31808SJens Wiklander case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: 154432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 154532b31808SJens Wiklander ("found supported_point_formats extension")); 154632b31808SJens Wiklander 154732b31808SJens Wiklander if ((ret = ssl_parse_supported_point_formats_ext(ssl, 154832b31808SJens Wiklander ext + 4, ext_size)) != 0) { 154932b31808SJens Wiklander return ret; 155032b31808SJens Wiklander } 155132b31808SJens Wiklander 155232b31808SJens Wiklander break; 1553b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 1554b0563631STom Van Eyck MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 155532b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 155632b31808SJens Wiklander 155732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 155832b31808SJens Wiklander case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: 155932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake_kkpp extension")); 156032b31808SJens Wiklander 156132b31808SJens Wiklander if ((ret = ssl_parse_ecjpake_kkpp(ssl, 156232b31808SJens Wiklander ext + 4, ext_size)) != 0) { 156332b31808SJens Wiklander return ret; 156432b31808SJens Wiklander } 156532b31808SJens Wiklander 156632b31808SJens Wiklander break; 156732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 156832b31808SJens Wiklander 156932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN) 157032b31808SJens Wiklander case MBEDTLS_TLS_EXT_ALPN: 157132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); 157232b31808SJens Wiklander 157332b31808SJens Wiklander if ((ret = ssl_parse_alpn_ext(ssl, ext + 4, ext_size)) != 0) { 157432b31808SJens Wiklander return ret; 157532b31808SJens Wiklander } 157632b31808SJens Wiklander 157732b31808SJens Wiklander break; 157832b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */ 157932b31808SJens Wiklander 158032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) 158132b31808SJens Wiklander case MBEDTLS_TLS_EXT_USE_SRTP: 158232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension")); 158332b31808SJens Wiklander 158432b31808SJens Wiklander if ((ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size)) != 0) { 158532b31808SJens Wiklander return ret; 158632b31808SJens Wiklander } 158732b31808SJens Wiklander 158832b31808SJens Wiklander break; 158932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */ 159032b31808SJens Wiklander 159132b31808SJens Wiklander default: 159232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 159332b31808SJens Wiklander ("unknown extension found: %u (ignoring)", ext_id)); 159432b31808SJens Wiklander } 159532b31808SJens Wiklander 159632b31808SJens Wiklander ext_len -= 4 + ext_size; 159732b31808SJens Wiklander ext += 4 + ext_size; 159832b31808SJens Wiklander 159932b31808SJens Wiklander if (ext_len > 0 && ext_len < 4) { 160032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 160132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 160232b31808SJens Wiklander } 160332b31808SJens Wiklander } 160432b31808SJens Wiklander 160532b31808SJens Wiklander /* 160632b31808SJens Wiklander * mbedtls_ssl_derive_keys() has to be called after the parsing of the 160732b31808SJens Wiklander * extensions. It sets the transform data for the resumed session which in 160832b31808SJens Wiklander * case of DTLS includes the server CID extracted from the CID extension. 160932b31808SJens Wiklander */ 161032b31808SJens Wiklander if (ssl->handshake->resume) { 161132b31808SJens Wiklander if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 161232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 161332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 161432b31808SJens Wiklander ssl, 161532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 161632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 161732b31808SJens Wiklander return ret; 161832b31808SJens Wiklander } 161932b31808SJens Wiklander } 162032b31808SJens Wiklander 162132b31808SJens Wiklander /* 162232b31808SJens Wiklander * Renegotiation security checks 162332b31808SJens Wiklander */ 162432b31808SJens Wiklander if (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 162532b31808SJens Wiklander ssl->conf->allow_legacy_renegotiation == 162632b31808SJens Wiklander MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) { 162732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 162832b31808SJens Wiklander ("legacy renegotiation, breaking off handshake")); 162932b31808SJens Wiklander handshake_failure = 1; 163032b31808SJens Wiklander } 163132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 163232b31808SJens Wiklander else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 163332b31808SJens Wiklander ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && 163432b31808SJens Wiklander renegotiation_info_seen == 0) { 163532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 163632b31808SJens Wiklander ("renegotiation_info extension missing (secure)")); 163732b31808SJens Wiklander handshake_failure = 1; 163832b31808SJens Wiklander } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 163932b31808SJens Wiklander ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 164032b31808SJens Wiklander ssl->conf->allow_legacy_renegotiation == 164132b31808SJens Wiklander MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) { 164232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed")); 164332b31808SJens Wiklander handshake_failure = 1; 164432b31808SJens Wiklander } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 164532b31808SJens Wiklander ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 164632b31808SJens Wiklander renegotiation_info_seen == 1) { 164732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 164832b31808SJens Wiklander ("renegotiation_info extension present (legacy)")); 164932b31808SJens Wiklander handshake_failure = 1; 165032b31808SJens Wiklander } 165132b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */ 165232b31808SJens Wiklander 165332b31808SJens Wiklander if (handshake_failure == 1) { 165432b31808SJens Wiklander mbedtls_ssl_send_alert_message( 165532b31808SJens Wiklander ssl, 165632b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 165732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 165832b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 165932b31808SJens Wiklander } 166032b31808SJens Wiklander 166132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); 166232b31808SJens Wiklander 166332b31808SJens Wiklander return 0; 166432b31808SJens Wiklander } 166532b31808SJens Wiklander 166632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 166732b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 166832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 166932b31808SJens Wiklander static int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl, 167032b31808SJens Wiklander unsigned char **p, 167132b31808SJens Wiklander unsigned char *end) 167232b31808SJens Wiklander { 167332b31808SJens Wiklander int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 167432b31808SJens Wiklander size_t dhm_actual_bitlen; 167532b31808SJens Wiklander 167632b31808SJens Wiklander /* 167732b31808SJens Wiklander * Ephemeral DH parameters: 167832b31808SJens Wiklander * 167932b31808SJens Wiklander * struct { 168032b31808SJens Wiklander * opaque dh_p<1..2^16-1>; 168132b31808SJens Wiklander * opaque dh_g<1..2^16-1>; 168232b31808SJens Wiklander * opaque dh_Ys<1..2^16-1>; 168332b31808SJens Wiklander * } ServerDHParams; 168432b31808SJens Wiklander */ 168532b31808SJens Wiklander if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx, 168632b31808SJens Wiklander p, end)) != 0) { 168732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret); 168832b31808SJens Wiklander return ret; 168932b31808SJens Wiklander } 169032b31808SJens Wiklander 169132b31808SJens Wiklander dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx); 169232b31808SJens Wiklander if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) { 169332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u", 169432b31808SJens Wiklander dhm_actual_bitlen, 169532b31808SJens Wiklander ssl->conf->dhm_min_bitlen)); 169632b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 169732b31808SJens Wiklander } 169832b31808SJens Wiklander 169932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P); 170032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G); 170132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); 170232b31808SJens Wiklander 170332b31808SJens Wiklander return ret; 170432b31808SJens Wiklander } 170532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || 170632b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 170732b31808SJens Wiklander 170832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 170932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 171032b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 171132b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 171232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 171332b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, 171432b31808SJens Wiklander unsigned char **p, 171532b31808SJens Wiklander unsigned char *end) 171632b31808SJens Wiklander { 171732b31808SJens Wiklander uint16_t tls_id; 1718b0563631STom Van Eyck size_t ecpoint_len; 171932b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1720b0563631STom Van Eyck psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 172132b31808SJens Wiklander size_t ec_bits = 0; 172232b31808SJens Wiklander 172332b31808SJens Wiklander /* 172432b31808SJens Wiklander * struct { 172532b31808SJens Wiklander * ECParameters curve_params; 172632b31808SJens Wiklander * ECPoint public; 172732b31808SJens Wiklander * } ServerECDHParams; 172832b31808SJens Wiklander * 172932b31808SJens Wiklander * 1 curve_type (must be "named_curve") 173032b31808SJens Wiklander * 2..3 NamedCurve 173132b31808SJens Wiklander * 4 ECPoint.len 173232b31808SJens Wiklander * 5+ ECPoint contents 173332b31808SJens Wiklander */ 173432b31808SJens Wiklander if (end - *p < 4) { 173532b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 173632b31808SJens Wiklander } 173732b31808SJens Wiklander 173832b31808SJens Wiklander /* First byte is curve_type; only named_curve is handled */ 173932b31808SJens Wiklander if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) { 174032b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 174132b31808SJens Wiklander } 174232b31808SJens Wiklander 174332b31808SJens Wiklander /* Next two bytes are the namedcurve value */ 1744b0563631STom Van Eyck tls_id = MBEDTLS_GET_UINT16_BE(*p, 0); 1745b0563631STom Van Eyck *p += 2; 174632b31808SJens Wiklander 174732b31808SJens Wiklander /* Check it's a curve we offered */ 174832b31808SJens Wiklander if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) { 174932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 175032b31808SJens Wiklander ("bad server key exchange message (ECDHE curve): %u", 175132b31808SJens Wiklander (unsigned) tls_id)); 175232b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 175332b31808SJens Wiklander } 175432b31808SJens Wiklander 175532b31808SJens Wiklander /* Convert EC's TLS ID to PSA key type. */ 1756b0563631STom Van Eyck if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, 175732b31808SJens Wiklander &ec_bits) == PSA_ERROR_NOT_SUPPORTED) { 175832b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 175932b31808SJens Wiklander } 1760b0563631STom Van Eyck handshake->xxdh_psa_type = key_type; 1761b0563631STom Van Eyck handshake->xxdh_psa_bits = ec_bits; 176232b31808SJens Wiklander 176332b31808SJens Wiklander /* Keep a copy of the peer's public key */ 176432b31808SJens Wiklander ecpoint_len = *(*p)++; 176532b31808SJens Wiklander if ((size_t) (end - *p) < ecpoint_len) { 176632b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 176732b31808SJens Wiklander } 176832b31808SJens Wiklander 1769b0563631STom Van Eyck if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) { 177032b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 177132b31808SJens Wiklander } 177232b31808SJens Wiklander 1773b0563631STom Van Eyck memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len); 1774b0563631STom Van Eyck handshake->xxdh_psa_peerkey_len = ecpoint_len; 177532b31808SJens Wiklander *p += ecpoint_len; 177632b31808SJens Wiklander 177732b31808SJens Wiklander return 0; 177832b31808SJens Wiklander } 177932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 178032b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 178132b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 178232b31808SJens Wiklander #else 178332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 178432b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 178532b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 178632b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ 178732b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 178832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 178932b31808SJens Wiklander static int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl) 179032b31808SJens Wiklander { 179132b31808SJens Wiklander uint16_t tls_id; 179232b31808SJens Wiklander mbedtls_ecp_group_id grp_id; 179332b31808SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 179432b31808SJens Wiklander grp_id = ssl->handshake->ecdh_ctx.grp.id; 179532b31808SJens Wiklander #else 179632b31808SJens Wiklander grp_id = ssl->handshake->ecdh_ctx.grp_id; 179732b31808SJens Wiklander #endif 179832b31808SJens Wiklander 179932b31808SJens Wiklander tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); 180032b31808SJens Wiklander if (tls_id == 0) { 180132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 180232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 180332b31808SJens Wiklander } 180432b31808SJens Wiklander 180532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s", 180632b31808SJens Wiklander mbedtls_ssl_get_curve_name_from_tls_id(tls_id))); 180732b31808SJens Wiklander 180832b31808SJens Wiklander if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { 180932b31808SJens Wiklander return -1; 181032b31808SJens Wiklander } 181132b31808SJens Wiklander 181232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 181332b31808SJens Wiklander MBEDTLS_DEBUG_ECDH_QP); 181432b31808SJens Wiklander 181532b31808SJens Wiklander return 0; 181632b31808SJens Wiklander } 181732b31808SJens Wiklander 181832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 181932b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 182032b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 182132b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || 182232b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 182332b31808SJens Wiklander 182432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 182532b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 182632b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 182732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 182832b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, 182932b31808SJens Wiklander unsigned char **p, 183032b31808SJens Wiklander unsigned char *end) 183132b31808SJens Wiklander { 183232b31808SJens Wiklander int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 183332b31808SJens Wiklander 183432b31808SJens Wiklander /* 183532b31808SJens Wiklander * Ephemeral ECDH parameters: 183632b31808SJens Wiklander * 183732b31808SJens Wiklander * struct { 183832b31808SJens Wiklander * ECParameters curve_params; 183932b31808SJens Wiklander * ECPoint public; 184032b31808SJens Wiklander * } ServerECDHParams; 184132b31808SJens Wiklander */ 184232b31808SJens Wiklander if ((ret = mbedtls_ecdh_read_params(&ssl->handshake->ecdh_ctx, 184332b31808SJens Wiklander (const unsigned char **) p, end)) != 0) { 184432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_read_params"), ret); 184532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 184632b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 184732b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 184832b31808SJens Wiklander } 184932b31808SJens Wiklander #endif 185032b31808SJens Wiklander return ret; 185132b31808SJens Wiklander } 185232b31808SJens Wiklander 185332b31808SJens Wiklander if (ssl_check_server_ecdh_params(ssl) != 0) { 185432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 185532b31808SJens Wiklander ("bad server key exchange message (ECDHE curve)")); 185632b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 185732b31808SJens Wiklander } 185832b31808SJens Wiklander 185932b31808SJens Wiklander return ret; 186032b31808SJens Wiklander } 186132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \ 186232b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ 186332b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 186432b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */ 186532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 186632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 186732b31808SJens Wiklander static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl, 186832b31808SJens Wiklander unsigned char **p, 186932b31808SJens Wiklander unsigned char *end) 187032b31808SJens Wiklander { 187132b31808SJens Wiklander int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 187232b31808SJens Wiklander uint16_t len; 187332b31808SJens Wiklander ((void) ssl); 187432b31808SJens Wiklander 187532b31808SJens Wiklander /* 187632b31808SJens Wiklander * PSK parameters: 187732b31808SJens Wiklander * 187832b31808SJens Wiklander * opaque psk_identity_hint<0..2^16-1>; 187932b31808SJens Wiklander */ 188032b31808SJens Wiklander if (end - (*p) < 2) { 188132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 188232b31808SJens Wiklander ("bad server key exchange message (psk_identity_hint length)")); 188332b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 188432b31808SJens Wiklander } 1885b0563631STom Van Eyck len = MBEDTLS_GET_UINT16_BE(*p, 0); 188632b31808SJens Wiklander *p += 2; 188732b31808SJens Wiklander 188832b31808SJens Wiklander if (end - (*p) < len) { 188932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 189032b31808SJens Wiklander ("bad server key exchange message (psk_identity_hint length)")); 189132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 189232b31808SJens Wiklander } 189332b31808SJens Wiklander 189432b31808SJens Wiklander /* 189532b31808SJens Wiklander * Note: we currently ignore the PSK identity hint, as we only allow one 189632b31808SJens Wiklander * PSK to be provisioned on the client. This could be changed later if 189732b31808SJens Wiklander * someone needs that feature. 189832b31808SJens Wiklander */ 189932b31808SJens Wiklander *p += len; 190032b31808SJens Wiklander ret = 0; 190132b31808SJens Wiklander 190232b31808SJens Wiklander return ret; 190332b31808SJens Wiklander } 190432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 190532b31808SJens Wiklander 190632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ 190732b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 190832b31808SJens Wiklander /* 190932b31808SJens Wiklander * Generate a pre-master secret and encrypt it with the server's RSA key 191032b31808SJens Wiklander */ 191132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 191232b31808SJens Wiklander static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl, 191332b31808SJens Wiklander size_t offset, size_t *olen, 191432b31808SJens Wiklander size_t pms_offset) 191532b31808SJens Wiklander { 191632b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 191732b31808SJens Wiklander size_t len_bytes = 2; 191832b31808SJens Wiklander unsigned char *p = ssl->handshake->premaster + pms_offset; 191932b31808SJens Wiklander mbedtls_pk_context *peer_pk; 192032b31808SJens Wiklander 192132b31808SJens Wiklander if (offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN) { 192232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small for encrypted pms")); 192332b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 192432b31808SJens Wiklander } 192532b31808SJens Wiklander 192632b31808SJens Wiklander /* 192732b31808SJens Wiklander * Generate (part of) the pre-master as 192832b31808SJens Wiklander * struct { 192932b31808SJens Wiklander * ProtocolVersion client_version; 193032b31808SJens Wiklander * opaque random[46]; 193132b31808SJens Wiklander * } PreMasterSecret; 193232b31808SJens Wiklander */ 193332b31808SJens Wiklander mbedtls_ssl_write_version(p, ssl->conf->transport, 193432b31808SJens Wiklander MBEDTLS_SSL_VERSION_TLS1_2); 193532b31808SJens Wiklander 193632b31808SJens Wiklander if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p + 2, 46)) != 0) { 193732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret); 193832b31808SJens Wiklander return ret; 193932b31808SJens Wiklander } 194032b31808SJens Wiklander 194132b31808SJens Wiklander ssl->handshake->pmslen = 48; 194232b31808SJens Wiklander 194332b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 194432b31808SJens Wiklander peer_pk = &ssl->handshake->peer_pubkey; 194532b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 194632b31808SJens Wiklander if (ssl->session_negotiate->peer_cert == NULL) { 194732b31808SJens Wiklander /* Should never happen */ 194832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 194932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 195032b31808SJens Wiklander } 195132b31808SJens Wiklander peer_pk = &ssl->session_negotiate->peer_cert->pk; 195232b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 195332b31808SJens Wiklander 195432b31808SJens Wiklander /* 195532b31808SJens Wiklander * Now write it out, encrypted 195632b31808SJens Wiklander */ 195732b31808SJens Wiklander if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_RSA)) { 195832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("certificate key type mismatch")); 195932b31808SJens Wiklander return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 196032b31808SJens Wiklander } 196132b31808SJens Wiklander 196232b31808SJens Wiklander if ((ret = mbedtls_pk_encrypt(peer_pk, 196332b31808SJens Wiklander p, ssl->handshake->pmslen, 196432b31808SJens Wiklander ssl->out_msg + offset + len_bytes, olen, 196532b31808SJens Wiklander MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, 196632b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 1967*c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_encrypt", ret); 196832b31808SJens Wiklander return ret; 196932b31808SJens Wiklander } 197032b31808SJens Wiklander 197132b31808SJens Wiklander if (len_bytes == 2) { 197232b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(*olen, ssl->out_msg, offset); 197332b31808SJens Wiklander *olen += 2; 197432b31808SJens Wiklander } 197532b31808SJens Wiklander 197632b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 197732b31808SJens Wiklander /* We don't need the peer's public key anymore. Free it. */ 197832b31808SJens Wiklander mbedtls_pk_free(peer_pk); 197932b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 198032b31808SJens Wiklander return 0; 198132b31808SJens Wiklander } 198232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || 198332b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 198432b31808SJens Wiklander 198532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 198632b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 198732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 198832b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) 198932b31808SJens Wiklander { 199032b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 199132b31808SJens Wiklander mbedtls_pk_context *peer_pk; 199232b31808SJens Wiklander 199332b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 199432b31808SJens Wiklander peer_pk = &ssl->handshake->peer_pubkey; 199532b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 199632b31808SJens Wiklander if (ssl->session_negotiate->peer_cert == NULL) { 199732b31808SJens Wiklander /* Should never happen */ 199832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 199932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 200032b31808SJens Wiklander } 200132b31808SJens Wiklander peer_pk = &ssl->session_negotiate->peer_cert->pk; 200232b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 200332b31808SJens Wiklander 200432b31808SJens Wiklander /* This is a public key, so it can't be opaque, so can_do() is a good 200532b31808SJens Wiklander * enough check to ensure pk_ec() is safe to use below. */ 200632b31808SJens Wiklander if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_ECKEY)) { 200732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable")); 200832b31808SJens Wiklander return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 200932b31808SJens Wiklander } 201032b31808SJens Wiklander 2011b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2012b0563631STom Van Eyck const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk); 2013b0563631STom Van Eyck #endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */ 201432b31808SJens Wiklander 201532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 201632b31808SJens Wiklander uint16_t tls_id = 0; 2017b0563631STom Van Eyck psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 2018b0563631STom Van Eyck mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk); 201932b31808SJens Wiklander 2020b0563631STom Van Eyck if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { 202132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); 202232b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; 202332b31808SJens Wiklander } 202432b31808SJens Wiklander 2025b0563631STom Van Eyck tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); 202632b31808SJens Wiklander if (tls_id == 0) { 202732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported", 2028b0563631STom Van Eyck grp_id)); 202932b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 203032b31808SJens Wiklander } 203132b31808SJens Wiklander 203232b31808SJens Wiklander /* If the above conversion to TLS ID was fine, then also this one will be, 203332b31808SJens Wiklander so there is no need to check the return value here */ 2034b0563631STom Van Eyck mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, 2035b0563631STom Van Eyck &ssl->handshake->xxdh_psa_bits); 203632b31808SJens Wiklander 2037b0563631STom Van Eyck ssl->handshake->xxdh_psa_type = key_type; 203832b31808SJens Wiklander 203932b31808SJens Wiklander /* Store peer's public key in psa format. */ 2040b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2041b0563631STom Van Eyck memcpy(ssl->handshake->xxdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len); 2042b0563631STom Van Eyck ssl->handshake->xxdh_psa_peerkey_len = peer_pk->pub_raw_len; 2043b0563631STom Van Eyck ret = 0; 2044b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 2045b0563631STom Van Eyck size_t olen = 0; 204632b31808SJens Wiklander ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q, 204732b31808SJens Wiklander MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, 2048b0563631STom Van Eyck ssl->handshake->xxdh_psa_peerkey, 2049b0563631STom Van Eyck sizeof(ssl->handshake->xxdh_psa_peerkey)); 205032b31808SJens Wiklander 205132b31808SJens Wiklander if (ret != 0) { 205232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret); 205332b31808SJens Wiklander return ret; 205432b31808SJens Wiklander } 2055b0563631STom Van Eyck ssl->handshake->xxdh_psa_peerkey_len = olen; 2056b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 2057b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */ 205832b31808SJens Wiklander if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key, 205932b31808SJens Wiklander MBEDTLS_ECDH_THEIRS)) != 0) { 206032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret); 206132b31808SJens Wiklander return ret; 206232b31808SJens Wiklander } 206332b31808SJens Wiklander 206432b31808SJens Wiklander if (ssl_check_server_ecdh_params(ssl) != 0) { 206532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); 206632b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; 206732b31808SJens Wiklander } 2068b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */ 206932b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 207032b31808SJens Wiklander /* We don't need the peer's public key anymore. Free it, 207132b31808SJens Wiklander * so that more RAM is available for upcoming expensive 207232b31808SJens Wiklander * operations like ECDHE. */ 207332b31808SJens Wiklander mbedtls_pk_free(peer_pk); 207432b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 207532b31808SJens Wiklander 207632b31808SJens Wiklander return ret; 207732b31808SJens Wiklander } 207832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || 207932b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 208032b31808SJens Wiklander 208132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 208232b31808SJens Wiklander static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) 208332b31808SJens Wiklander { 208432b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 208532b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 208632b31808SJens Wiklander ssl->handshake->ciphersuite_info; 208732b31808SJens Wiklander unsigned char *p = NULL, *end = NULL; 208832b31808SJens Wiklander 208932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server key exchange")); 209032b31808SJens Wiklander 209132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 209232b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { 209332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); 209432b31808SJens Wiklander ssl->state++; 209532b31808SJens Wiklander return 0; 209632b31808SJens Wiklander } 209732b31808SJens Wiklander ((void) p); 209832b31808SJens Wiklander ((void) end); 209932b31808SJens Wiklander #endif 210032b31808SJens Wiklander 210132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 210232b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 210332b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || 210432b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { 210532b31808SJens Wiklander if ((ret = ssl_get_ecdh_params_from_cert(ssl)) != 0) { 210632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret); 210732b31808SJens Wiklander mbedtls_ssl_send_alert_message( 210832b31808SJens Wiklander ssl, 210932b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 211032b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 211132b31808SJens Wiklander return ret; 211232b31808SJens Wiklander } 211332b31808SJens Wiklander 211432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); 211532b31808SJens Wiklander ssl->state++; 211632b31808SJens Wiklander return 0; 211732b31808SJens Wiklander } 211832b31808SJens Wiklander ((void) p); 211932b31808SJens Wiklander ((void) end); 212032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 212132b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 212232b31808SJens Wiklander 212332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 212432b31808SJens Wiklander if (ssl->handshake->ecrs_enabled && 212532b31808SJens Wiklander ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing) { 212632b31808SJens Wiklander goto start_processing; 212732b31808SJens Wiklander } 212832b31808SJens Wiklander #endif 212932b31808SJens Wiklander 213032b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 213132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 213232b31808SJens Wiklander return ret; 213332b31808SJens Wiklander } 213432b31808SJens Wiklander 213532b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 213632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 213732b31808SJens Wiklander mbedtls_ssl_send_alert_message( 213832b31808SJens Wiklander ssl, 213932b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 214032b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 214132b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 214232b31808SJens Wiklander } 214332b31808SJens Wiklander 214432b31808SJens Wiklander /* 214532b31808SJens Wiklander * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server 214632b31808SJens Wiklander * doesn't use a psk_identity_hint 214732b31808SJens Wiklander */ 214832b31808SJens Wiklander if (ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE) { 214932b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 215032b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 215132b31808SJens Wiklander /* Current message is probably either 215232b31808SJens Wiklander * CertificateRequest or ServerHelloDone */ 215332b31808SJens Wiklander ssl->keep_current_message = 1; 215432b31808SJens Wiklander goto exit; 215532b31808SJens Wiklander } 215632b31808SJens Wiklander 215732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 215832b31808SJens Wiklander ("server key exchange message must not be skipped")); 215932b31808SJens Wiklander mbedtls_ssl_send_alert_message( 216032b31808SJens Wiklander ssl, 216132b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 216232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 216332b31808SJens Wiklander 216432b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 216532b31808SJens Wiklander } 216632b31808SJens Wiklander 216732b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 216832b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 216932b31808SJens Wiklander ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; 217032b31808SJens Wiklander } 217132b31808SJens Wiklander 217232b31808SJens Wiklander start_processing: 217332b31808SJens Wiklander #endif 217432b31808SJens Wiklander p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 217532b31808SJens Wiklander end = ssl->in_msg + ssl->in_hslen; 2176b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_BUF(3, "server key exchange", p, (size_t) (end - p)); 217732b31808SJens Wiklander 217832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 217932b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 218032b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || 218132b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || 218232b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 218332b31808SJens Wiklander if (ssl_parse_server_psk_hint(ssl, &p, end) != 0) { 218432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 218532b31808SJens Wiklander mbedtls_ssl_send_alert_message( 218632b31808SJens Wiklander ssl, 218732b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 218832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 218932b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 219032b31808SJens Wiklander } 219132b31808SJens Wiklander } /* FALLTHROUGH */ 219232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 219332b31808SJens Wiklander 219432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ 219532b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 219632b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 219732b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 219832b31808SJens Wiklander ; /* nothing more to do */ 219932b31808SJens Wiklander } else 220032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || 220132b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 220232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 220332b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 220432b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || 220532b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { 220632b31808SJens Wiklander if (ssl_parse_server_dh_params(ssl, &p, end) != 0) { 220732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 220832b31808SJens Wiklander mbedtls_ssl_send_alert_message( 220932b31808SJens Wiklander ssl, 221032b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 221132b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 221232b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 221332b31808SJens Wiklander } 221432b31808SJens Wiklander } else 221532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || 221632b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 221732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 221832b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 221932b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 222032b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || 222132b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || 222232b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) { 222332b31808SJens Wiklander if (ssl_parse_server_ecdh_params(ssl, &p, end) != 0) { 222432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 222532b31808SJens Wiklander mbedtls_ssl_send_alert_message( 222632b31808SJens Wiklander ssl, 222732b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 222832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 222932b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 223032b31808SJens Wiklander } 223132b31808SJens Wiklander } else 223232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 223332b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 223432b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 223532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 223632b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 223732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 223832b31808SJens Wiklander /* 223932b31808SJens Wiklander * The first 3 bytes are: 224032b31808SJens Wiklander * [0] MBEDTLS_ECP_TLS_NAMED_CURVE 224132b31808SJens Wiklander * [1, 2] elliptic curve's TLS ID 224232b31808SJens Wiklander * 224332b31808SJens Wiklander * However since we only support secp256r1 for now, we check only 224432b31808SJens Wiklander * that TLS ID here 224532b31808SJens Wiklander */ 224632b31808SJens Wiklander uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE(p, 1); 224732b31808SJens Wiklander uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( 224832b31808SJens Wiklander MBEDTLS_ECP_DP_SECP256R1); 224932b31808SJens Wiklander 225032b31808SJens Wiklander if (exp_tls_id == 0) { 225132b31808SJens Wiklander return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 225232b31808SJens Wiklander } 225332b31808SJens Wiklander 225432b31808SJens Wiklander if ((*p != MBEDTLS_ECP_TLS_NAMED_CURVE) || 225532b31808SJens Wiklander (read_tls_id != exp_tls_id)) { 225632b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 225732b31808SJens Wiklander } 225832b31808SJens Wiklander 225932b31808SJens Wiklander p += 3; 226032b31808SJens Wiklander 226132b31808SJens Wiklander if ((ret = mbedtls_psa_ecjpake_read_round( 226232b31808SJens Wiklander &ssl->handshake->psa_pake_ctx, p, end - p, 226332b31808SJens Wiklander MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) { 226432b31808SJens Wiklander psa_destroy_key(ssl->handshake->psa_pake_password); 226532b31808SJens Wiklander psa_pake_abort(&ssl->handshake->psa_pake_ctx); 226632b31808SJens Wiklander 226732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret); 226832b31808SJens Wiklander mbedtls_ssl_send_alert_message( 226932b31808SJens Wiklander ssl, 227032b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 227132b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 227232b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 227332b31808SJens Wiklander } 227432b31808SJens Wiklander #else 227532b31808SJens Wiklander ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx, 227632b31808SJens Wiklander p, end - p); 227732b31808SJens Wiklander if (ret != 0) { 227832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret); 227932b31808SJens Wiklander mbedtls_ssl_send_alert_message( 228032b31808SJens Wiklander ssl, 228132b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 228232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 228332b31808SJens Wiklander return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 228432b31808SJens Wiklander } 228532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 228632b31808SJens Wiklander } else 228732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 228832b31808SJens Wiklander { 228932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 229032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 229132b31808SJens Wiklander } 229232b31808SJens Wiklander 229332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 229432b31808SJens Wiklander if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) { 229532b31808SJens Wiklander size_t sig_len, hashlen; 2296b0563631STom Van Eyck unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 229732b31808SJens Wiklander 229832b31808SJens Wiklander mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; 229932b31808SJens Wiklander mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; 230032b31808SJens Wiklander unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 2301b0563631STom Van Eyck size_t params_len = (size_t) (p - params); 230232b31808SJens Wiklander void *rs_ctx = NULL; 230332b31808SJens Wiklander uint16_t sig_alg; 230432b31808SJens Wiklander 230532b31808SJens Wiklander mbedtls_pk_context *peer_pk; 230632b31808SJens Wiklander 230732b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 230832b31808SJens Wiklander peer_pk = &ssl->handshake->peer_pubkey; 230932b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 231032b31808SJens Wiklander if (ssl->session_negotiate->peer_cert == NULL) { 231132b31808SJens Wiklander /* Should never happen */ 231232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 231332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 231432b31808SJens Wiklander } 231532b31808SJens Wiklander peer_pk = &ssl->session_negotiate->peer_cert->pk; 231632b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 231732b31808SJens Wiklander 231832b31808SJens Wiklander /* 231932b31808SJens Wiklander * Handle the digitally-signed structure 232032b31808SJens Wiklander */ 232132b31808SJens Wiklander MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); 232232b31808SJens Wiklander sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); 232332b31808SJens Wiklander if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( 232432b31808SJens Wiklander sig_alg, &pk_alg, &md_alg) != 0 && 232532b31808SJens Wiklander !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) && 232632b31808SJens Wiklander !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { 232732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 232832b31808SJens Wiklander ("bad server key exchange message")); 232932b31808SJens Wiklander mbedtls_ssl_send_alert_message( 233032b31808SJens Wiklander ssl, 233132b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 233232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 233332b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 233432b31808SJens Wiklander } 233532b31808SJens Wiklander p += 2; 233632b31808SJens Wiklander 233732b31808SJens Wiklander if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { 233832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 233932b31808SJens Wiklander ("bad server key exchange message")); 234032b31808SJens Wiklander mbedtls_ssl_send_alert_message( 234132b31808SJens Wiklander ssl, 234232b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 234332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 234432b31808SJens Wiklander return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 234532b31808SJens Wiklander } 234632b31808SJens Wiklander 234732b31808SJens Wiklander /* 234832b31808SJens Wiklander * Read signature 234932b31808SJens Wiklander */ 235032b31808SJens Wiklander 235132b31808SJens Wiklander if (p > end - 2) { 235232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 235332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 235432b31808SJens Wiklander ssl, 235532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 235632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 235732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 235832b31808SJens Wiklander } 2359b0563631STom Van Eyck sig_len = MBEDTLS_GET_UINT16_BE(p, 0); 236032b31808SJens Wiklander p += 2; 236132b31808SJens Wiklander 236232b31808SJens Wiklander if (p != end - sig_len) { 236332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 236432b31808SJens Wiklander mbedtls_ssl_send_alert_message( 236532b31808SJens Wiklander ssl, 236632b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 236732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 236832b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 236932b31808SJens Wiklander } 237032b31808SJens Wiklander 237132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "signature", p, sig_len); 237232b31808SJens Wiklander 237332b31808SJens Wiklander /* 237432b31808SJens Wiklander * Compute the hash that has been signed 237532b31808SJens Wiklander */ 237632b31808SJens Wiklander if (md_alg != MBEDTLS_MD_NONE) { 237732b31808SJens Wiklander ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen, 237832b31808SJens Wiklander params, params_len, 237932b31808SJens Wiklander md_alg); 238032b31808SJens Wiklander if (ret != 0) { 238132b31808SJens Wiklander return ret; 238232b31808SJens Wiklander } 238332b31808SJens Wiklander } else { 238432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 238532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 238632b31808SJens Wiklander } 238732b31808SJens Wiklander 238832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen); 238932b31808SJens Wiklander 239032b31808SJens Wiklander /* 239132b31808SJens Wiklander * Verify signature 239232b31808SJens Wiklander */ 239332b31808SJens Wiklander if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { 239432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 239532b31808SJens Wiklander mbedtls_ssl_send_alert_message( 239632b31808SJens Wiklander ssl, 239732b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 239832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 239932b31808SJens Wiklander return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 240032b31808SJens Wiklander } 240132b31808SJens Wiklander 240232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 240332b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 240432b31808SJens Wiklander rs_ctx = &ssl->handshake->ecrs_ctx.pk; 240532b31808SJens Wiklander } 240632b31808SJens Wiklander #endif 240732b31808SJens Wiklander 240832b31808SJens Wiklander #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 240932b31808SJens Wiklander if (pk_alg == MBEDTLS_PK_RSASSA_PSS) { 241032b31808SJens Wiklander mbedtls_pk_rsassa_pss_options rsassa_pss_options; 241132b31808SJens Wiklander rsassa_pss_options.mgf1_hash_id = md_alg; 241232b31808SJens Wiklander rsassa_pss_options.expected_salt_len = 2413b0563631STom Van Eyck mbedtls_md_get_size_from_type(md_alg); 241432b31808SJens Wiklander if (rsassa_pss_options.expected_salt_len == 0) { 241532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 241632b31808SJens Wiklander } 241732b31808SJens Wiklander 241832b31808SJens Wiklander ret = mbedtls_pk_verify_ext(pk_alg, &rsassa_pss_options, 241932b31808SJens Wiklander peer_pk, 242032b31808SJens Wiklander md_alg, hash, hashlen, 242132b31808SJens Wiklander p, sig_len); 242232b31808SJens Wiklander } else 242332b31808SJens Wiklander #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 242432b31808SJens Wiklander ret = mbedtls_pk_verify_restartable(peer_pk, 242532b31808SJens Wiklander md_alg, hash, hashlen, p, sig_len, rs_ctx); 242632b31808SJens Wiklander 242732b31808SJens Wiklander if (ret != 0) { 242832b31808SJens Wiklander int send_alert_msg = 1; 242932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 243032b31808SJens Wiklander send_alert_msg = (ret != MBEDTLS_ERR_ECP_IN_PROGRESS); 243132b31808SJens Wiklander #endif 243232b31808SJens Wiklander if (send_alert_msg) { 243332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 243432b31808SJens Wiklander ssl, 243532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 243632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR); 243732b31808SJens Wiklander } 243832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret); 243932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 244032b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 244132b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 244232b31808SJens Wiklander } 244332b31808SJens Wiklander #endif 244432b31808SJens Wiklander return ret; 244532b31808SJens Wiklander } 244632b31808SJens Wiklander 244732b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 244832b31808SJens Wiklander /* We don't need the peer's public key anymore. Free it, 244932b31808SJens Wiklander * so that more RAM is available for upcoming expensive 245032b31808SJens Wiklander * operations like ECDHE. */ 245132b31808SJens Wiklander mbedtls_pk_free(peer_pk); 245232b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 245332b31808SJens Wiklander } 245432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 245532b31808SJens Wiklander 245632b31808SJens Wiklander exit: 245732b31808SJens Wiklander ssl->state++; 245832b31808SJens Wiklander 245932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange")); 246032b31808SJens Wiklander 246132b31808SJens Wiklander return 0; 246232b31808SJens Wiklander } 246332b31808SJens Wiklander 246432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 246532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 246632b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) 246732b31808SJens Wiklander { 246832b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 246932b31808SJens Wiklander ssl->handshake->ciphersuite_info; 247032b31808SJens Wiklander 247132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); 247232b31808SJens Wiklander 247332b31808SJens Wiklander if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 247432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); 247532b31808SJens Wiklander ssl->state++; 247632b31808SJens Wiklander return 0; 247732b31808SJens Wiklander } 247832b31808SJens Wiklander 247932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 248032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 248132b31808SJens Wiklander } 248232b31808SJens Wiklander #else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 248332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 248432b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) 248532b31808SJens Wiklander { 248632b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 248732b31808SJens Wiklander unsigned char *buf; 248832b31808SJens Wiklander size_t n = 0; 248932b31808SJens Wiklander size_t cert_type_len = 0, dn_len = 0; 249032b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 249132b31808SJens Wiklander ssl->handshake->ciphersuite_info; 249232b31808SJens Wiklander size_t sig_alg_len; 249332b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C) 249432b31808SJens Wiklander unsigned char *sig_alg; 249532b31808SJens Wiklander unsigned char *dn; 249632b31808SJens Wiklander #endif 249732b31808SJens Wiklander 249832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); 249932b31808SJens Wiklander 250032b31808SJens Wiklander if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 250132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); 250232b31808SJens Wiklander ssl->state++; 250332b31808SJens Wiklander return 0; 250432b31808SJens Wiklander } 250532b31808SJens Wiklander 250632b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 250732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 250832b31808SJens Wiklander return ret; 250932b31808SJens Wiklander } 251032b31808SJens Wiklander 251132b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 251232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 251332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 251432b31808SJens Wiklander ssl, 251532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 251632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 251732b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 251832b31808SJens Wiklander } 251932b31808SJens Wiklander 252032b31808SJens Wiklander ssl->state++; 252132b31808SJens Wiklander ssl->handshake->client_auth = 252232b31808SJens Wiklander (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST); 252332b31808SJens Wiklander 252432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("got %s certificate request", 252532b31808SJens Wiklander ssl->handshake->client_auth ? "a" : "no")); 252632b31808SJens Wiklander 252732b31808SJens Wiklander if (ssl->handshake->client_auth == 0) { 252832b31808SJens Wiklander /* Current message is probably the ServerHelloDone */ 252932b31808SJens Wiklander ssl->keep_current_message = 1; 253032b31808SJens Wiklander goto exit; 253132b31808SJens Wiklander } 253232b31808SJens Wiklander 253332b31808SJens Wiklander /* 253432b31808SJens Wiklander * struct { 253532b31808SJens Wiklander * ClientCertificateType certificate_types<1..2^8-1>; 253632b31808SJens Wiklander * SignatureAndHashAlgorithm 253732b31808SJens Wiklander * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only 253832b31808SJens Wiklander * DistinguishedName certificate_authorities<0..2^16-1>; 253932b31808SJens Wiklander * } CertificateRequest; 254032b31808SJens Wiklander * 254132b31808SJens Wiklander * Since we only support a single certificate on clients, let's just 254232b31808SJens Wiklander * ignore all the information that's supposed to help us pick a 254332b31808SJens Wiklander * certificate. 254432b31808SJens Wiklander * 254532b31808SJens Wiklander * We could check that our certificate matches the request, and bail out 254632b31808SJens Wiklander * if it doesn't, but it's simpler to just send the certificate anyway, 254732b31808SJens Wiklander * and give the server the opportunity to decide if it should terminate 254832b31808SJens Wiklander * the connection when it doesn't like our certificate. 254932b31808SJens Wiklander * 255032b31808SJens Wiklander * Same goes for the hash in TLS 1.2's signature_algorithms: at this 255132b31808SJens Wiklander * point we only have one hash available (see comments in 255232b31808SJens Wiklander * write_certificate_verify), so let's just use what we have. 255332b31808SJens Wiklander * 255432b31808SJens Wiklander * However, we still minimally parse the message to check it is at least 255532b31808SJens Wiklander * superficially sane. 255632b31808SJens Wiklander */ 255732b31808SJens Wiklander buf = ssl->in_msg; 255832b31808SJens Wiklander 255932b31808SJens Wiklander /* certificate_types */ 256032b31808SJens Wiklander if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) { 256132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 256232b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 256332b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 256432b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 256532b31808SJens Wiklander } 256632b31808SJens Wiklander cert_type_len = buf[mbedtls_ssl_hs_hdr_len(ssl)]; 256732b31808SJens Wiklander n = cert_type_len; 256832b31808SJens Wiklander 256932b31808SJens Wiklander /* 257032b31808SJens Wiklander * In the subsequent code there are two paths that read from buf: 257132b31808SJens Wiklander * * the length of the signature algorithms field (if minor version of 257232b31808SJens Wiklander * SSL is 3), 257332b31808SJens Wiklander * * distinguished name length otherwise. 257432b31808SJens Wiklander * Both reach at most the index: 257532b31808SJens Wiklander * ...hdr_len + 2 + n, 257632b31808SJens Wiklander * therefore the buffer length at this point must be greater than that 257732b31808SJens Wiklander * regardless of the actual code path. 257832b31808SJens Wiklander */ 257932b31808SJens Wiklander if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) { 258032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 258132b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 258232b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 258332b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 258432b31808SJens Wiklander } 258532b31808SJens Wiklander 258632b31808SJens Wiklander /* supported_signature_algorithms */ 2587b0563631STom Van Eyck sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); 258832b31808SJens Wiklander 258932b31808SJens Wiklander /* 259032b31808SJens Wiklander * The furthest access in buf is in the loop few lines below: 259132b31808SJens Wiklander * sig_alg[i + 1], 259232b31808SJens Wiklander * where: 259332b31808SJens Wiklander * sig_alg = buf + ...hdr_len + 3 + n, 259432b31808SJens Wiklander * max(i) = sig_alg_len - 1. 259532b31808SJens Wiklander * Therefore the furthest access is: 259632b31808SJens Wiklander * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], 259732b31808SJens Wiklander * which reduces to: 259832b31808SJens Wiklander * buf[...hdr_len + 3 + n + sig_alg_len], 259932b31808SJens Wiklander * which is one less than we need the buf to be. 260032b31808SJens Wiklander */ 260132b31808SJens Wiklander if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) { 260232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 260332b31808SJens Wiklander mbedtls_ssl_send_alert_message( 260432b31808SJens Wiklander ssl, 260532b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 260632b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 260732b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 260832b31808SJens Wiklander } 260932b31808SJens Wiklander 261032b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C) 261132b31808SJens Wiklander sig_alg = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n; 261232b31808SJens Wiklander for (size_t i = 0; i < sig_alg_len; i += 2) { 261332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 261432b31808SJens Wiklander ("Supported Signature Algorithm found: %02x %02x", 261532b31808SJens Wiklander sig_alg[i], sig_alg[i + 1])); 261632b31808SJens Wiklander } 261732b31808SJens Wiklander #endif 261832b31808SJens Wiklander 261932b31808SJens Wiklander n += 2 + sig_alg_len; 262032b31808SJens Wiklander 262132b31808SJens Wiklander /* certificate_authorities */ 2622b0563631STom Van Eyck dn_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); 262332b31808SJens Wiklander 262432b31808SJens Wiklander n += dn_len; 262532b31808SJens Wiklander if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) { 262632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 262732b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 262832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 262932b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 263032b31808SJens Wiklander } 263132b31808SJens Wiklander 263232b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C) 263332b31808SJens Wiklander dn = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n - dn_len; 263432b31808SJens Wiklander for (size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len) { 263532b31808SJens Wiklander unsigned char *p = dn + i + 2; 263632b31808SJens Wiklander mbedtls_x509_name name; 263732b31808SJens Wiklander size_t asn1_len; 263832b31808SJens Wiklander char s[MBEDTLS_X509_MAX_DN_NAME_SIZE]; 263932b31808SJens Wiklander memset(&name, 0, sizeof(name)); 264032b31808SJens Wiklander dni_len = MBEDTLS_GET_UINT16_BE(dn + i, 0); 264132b31808SJens Wiklander if (dni_len > dn_len - i - 2 || 264232b31808SJens Wiklander mbedtls_asn1_get_tag(&p, p + dni_len, &asn1_len, 264332b31808SJens Wiklander MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 || 264432b31808SJens Wiklander mbedtls_x509_get_name(&p, p + asn1_len, &name) != 0) { 264532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 264632b31808SJens Wiklander mbedtls_ssl_send_alert_message( 264732b31808SJens Wiklander ssl, 264832b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 264932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 265032b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 265132b31808SJens Wiklander } 265232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 265332b31808SJens Wiklander ("DN hint: %.*s", 265432b31808SJens Wiklander mbedtls_x509_dn_gets(s, sizeof(s), &name), s)); 265532b31808SJens Wiklander mbedtls_asn1_free_named_data_list_shallow(name.next); 265632b31808SJens Wiklander } 265732b31808SJens Wiklander #endif 265832b31808SJens Wiklander 265932b31808SJens Wiklander exit: 266032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request")); 266132b31808SJens Wiklander 266232b31808SJens Wiklander return 0; 266332b31808SJens Wiklander } 266432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 266532b31808SJens Wiklander 266632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 266732b31808SJens Wiklander static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl) 266832b31808SJens Wiklander { 266932b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 267032b31808SJens Wiklander 267132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello done")); 267232b31808SJens Wiklander 267332b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 267432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 267532b31808SJens Wiklander return ret; 267632b31808SJens Wiklander } 267732b31808SJens Wiklander 267832b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 267932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); 268032b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 268132b31808SJens Wiklander } 268232b31808SJens Wiklander 268332b31808SJens Wiklander if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) || 268432b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE) { 268532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); 268632b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 268732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 268832b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 268932b31808SJens Wiklander } 269032b31808SJens Wiklander 269132b31808SJens Wiklander ssl->state++; 269232b31808SJens Wiklander 269332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 269432b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 269532b31808SJens Wiklander mbedtls_ssl_recv_flight_completed(ssl); 269632b31808SJens Wiklander } 269732b31808SJens Wiklander #endif 269832b31808SJens Wiklander 269932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello done")); 270032b31808SJens Wiklander 270132b31808SJens Wiklander return 0; 270232b31808SJens Wiklander } 270332b31808SJens Wiklander 270432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 270532b31808SJens Wiklander static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) 270632b31808SJens Wiklander { 270732b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 270832b31808SJens Wiklander 270932b31808SJens Wiklander size_t header_len; 271032b31808SJens Wiklander size_t content_len; 271132b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 271232b31808SJens Wiklander ssl->handshake->ciphersuite_info; 271332b31808SJens Wiklander 271432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client key exchange")); 271532b31808SJens Wiklander 271632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) 271732b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) { 271832b31808SJens Wiklander /* 271932b31808SJens Wiklander * DHM key exchange -- send G^X mod P 272032b31808SJens Wiklander */ 272132b31808SJens Wiklander content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); 272232b31808SJens Wiklander 272332b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(content_len, ssl->out_msg, 4); 272432b31808SJens Wiklander header_len = 6; 272532b31808SJens Wiklander 272632b31808SJens Wiklander ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, 272732b31808SJens Wiklander (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), 272832b31808SJens Wiklander &ssl->out_msg[header_len], content_len, 272932b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 273032b31808SJens Wiklander if (ret != 0) { 273132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); 273232b31808SJens Wiklander return ret; 273332b31808SJens Wiklander } 273432b31808SJens Wiklander 273532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X); 273632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX); 273732b31808SJens Wiklander 273832b31808SJens Wiklander if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 273932b31808SJens Wiklander ssl->handshake->premaster, 274032b31808SJens Wiklander MBEDTLS_PREMASTER_SIZE, 274132b31808SJens Wiklander &ssl->handshake->pmslen, 274232b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 274332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 274432b31808SJens Wiklander return ret; 274532b31808SJens Wiklander } 274632b31808SJens Wiklander 274732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 274832b31808SJens Wiklander } else 274932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ 275032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 275132b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ 275232b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 275332b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 275432b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || 275532b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || 275632b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || 275732b31808SJens Wiklander ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { 275832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 275932b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 276032b31808SJens Wiklander psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; 276132b31808SJens Wiklander psa_key_attributes_t key_attributes; 276232b31808SJens Wiklander 276332b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake; 276432b31808SJens Wiklander 276532b31808SJens Wiklander header_len = 4; 276632b31808SJens Wiklander 276732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); 276832b31808SJens Wiklander 276932b31808SJens Wiklander /* 277032b31808SJens Wiklander * Generate EC private key for ECDHE exchange. 277132b31808SJens Wiklander */ 277232b31808SJens Wiklander 277332b31808SJens Wiklander /* The master secret is obtained from the shared ECDH secret by 277432b31808SJens Wiklander * applying the TLS 1.2 PRF with a specific salt and label. While 277532b31808SJens Wiklander * the PSA Crypto API encourages combining key agreement schemes 277632b31808SJens Wiklander * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not 277732b31808SJens Wiklander * yet support the provisioning of salt + label to the KDF. 277832b31808SJens Wiklander * For the time being, we therefore need to split the computation 277932b31808SJens Wiklander * of the ECDH secret and the application of the TLS 1.2 PRF. */ 278032b31808SJens Wiklander key_attributes = psa_key_attributes_init(); 278132b31808SJens Wiklander psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 278232b31808SJens Wiklander psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2783b0563631STom Van Eyck psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); 2784b0563631STom Van Eyck psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); 278532b31808SJens Wiklander 278632b31808SJens Wiklander /* Generate ECDH private key. */ 278732b31808SJens Wiklander status = psa_generate_key(&key_attributes, 2788b0563631STom Van Eyck &handshake->xxdh_psa_privkey); 278932b31808SJens Wiklander if (status != PSA_SUCCESS) { 279032b31808SJens Wiklander return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 279132b31808SJens Wiklander } 279232b31808SJens Wiklander 279332b31808SJens Wiklander /* Export the public part of the ECDH private key from PSA. 279432b31808SJens Wiklander * The export format is an ECPoint structure as expected by TLS, 279532b31808SJens Wiklander * but we just need to add a length byte before that. */ 279632b31808SJens Wiklander unsigned char *own_pubkey = ssl->out_msg + header_len + 1; 279732b31808SJens Wiklander unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 279832b31808SJens Wiklander size_t own_pubkey_max_len = (size_t) (end - own_pubkey); 279932b31808SJens Wiklander size_t own_pubkey_len; 280032b31808SJens Wiklander 2801b0563631STom Van Eyck status = psa_export_public_key(handshake->xxdh_psa_privkey, 280232b31808SJens Wiklander own_pubkey, own_pubkey_max_len, 280332b31808SJens Wiklander &own_pubkey_len); 280432b31808SJens Wiklander if (status != PSA_SUCCESS) { 2805b0563631STom Van Eyck psa_destroy_key(handshake->xxdh_psa_privkey); 2806b0563631STom Van Eyck handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 280732b31808SJens Wiklander return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 280832b31808SJens Wiklander } 280932b31808SJens Wiklander 281032b31808SJens Wiklander ssl->out_msg[header_len] = (unsigned char) own_pubkey_len; 281132b31808SJens Wiklander content_len = own_pubkey_len + 1; 281232b31808SJens Wiklander 281332b31808SJens Wiklander /* The ECDH secret is the premaster secret used for key derivation. */ 281432b31808SJens Wiklander 281532b31808SJens Wiklander /* Compute ECDH shared secret. */ 281632b31808SJens Wiklander status = psa_raw_key_agreement(PSA_ALG_ECDH, 2817b0563631STom Van Eyck handshake->xxdh_psa_privkey, 2818b0563631STom Van Eyck handshake->xxdh_psa_peerkey, 2819b0563631STom Van Eyck handshake->xxdh_psa_peerkey_len, 282032b31808SJens Wiklander ssl->handshake->premaster, 282132b31808SJens Wiklander sizeof(ssl->handshake->premaster), 282232b31808SJens Wiklander &ssl->handshake->pmslen); 282332b31808SJens Wiklander 2824b0563631STom Van Eyck destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); 2825b0563631STom Van Eyck handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 282632b31808SJens Wiklander 282732b31808SJens Wiklander if (status != PSA_SUCCESS || destruction_status != PSA_SUCCESS) { 282832b31808SJens Wiklander return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 282932b31808SJens Wiklander } 283032b31808SJens Wiklander #else 283132b31808SJens Wiklander /* 283232b31808SJens Wiklander * ECDH key exchange -- send client public value 283332b31808SJens Wiklander */ 283432b31808SJens Wiklander header_len = 4; 283532b31808SJens Wiklander 283632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 283732b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 283832b31808SJens Wiklander if (ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret) { 283932b31808SJens Wiklander goto ecdh_calc_secret; 284032b31808SJens Wiklander } 284132b31808SJens Wiklander 284232b31808SJens Wiklander mbedtls_ecdh_enable_restart(&ssl->handshake->ecdh_ctx); 284332b31808SJens Wiklander } 284432b31808SJens Wiklander #endif 284532b31808SJens Wiklander 284632b31808SJens Wiklander ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, 284732b31808SJens Wiklander &content_len, 284832b31808SJens Wiklander &ssl->out_msg[header_len], 1000, 284932b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 285032b31808SJens Wiklander if (ret != 0) { 285132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); 285232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 285332b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 285432b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 285532b31808SJens Wiklander } 285632b31808SJens Wiklander #endif 285732b31808SJens Wiklander return ret; 285832b31808SJens Wiklander } 285932b31808SJens Wiklander 286032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 286132b31808SJens Wiklander MBEDTLS_DEBUG_ECDH_Q); 286232b31808SJens Wiklander 286332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 286432b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 286532b31808SJens Wiklander ssl->handshake->ecrs_n = content_len; 286632b31808SJens Wiklander ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; 286732b31808SJens Wiklander } 286832b31808SJens Wiklander 286932b31808SJens Wiklander ecdh_calc_secret: 287032b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 287132b31808SJens Wiklander content_len = ssl->handshake->ecrs_n; 287232b31808SJens Wiklander } 287332b31808SJens Wiklander #endif 287432b31808SJens Wiklander if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, 287532b31808SJens Wiklander &ssl->handshake->pmslen, 287632b31808SJens Wiklander ssl->handshake->premaster, 287732b31808SJens Wiklander MBEDTLS_MPI_MAX_SIZE, 287832b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 287932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); 288032b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 288132b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 288232b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 288332b31808SJens Wiklander } 288432b31808SJens Wiklander #endif 288532b31808SJens Wiklander return ret; 288632b31808SJens Wiklander } 288732b31808SJens Wiklander 288832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 288932b31808SJens Wiklander MBEDTLS_DEBUG_ECDH_Z); 289032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 289132b31808SJens Wiklander } else 289232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 289332b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || 289432b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 289532b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 289632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) && \ 289732b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 289832b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 289932b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 290032b31808SJens Wiklander psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; 290132b31808SJens Wiklander psa_key_attributes_t key_attributes; 290232b31808SJens Wiklander 290332b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake; 290432b31808SJens Wiklander 290532b31808SJens Wiklander /* 290632b31808SJens Wiklander * opaque psk_identity<0..2^16-1>; 290732b31808SJens Wiklander */ 290832b31808SJens Wiklander if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { 290932b31808SJens Wiklander /* We don't offer PSK suites if we don't have a PSK, 291032b31808SJens Wiklander * and we check that the server's choice is among the 291132b31808SJens Wiklander * ciphersuites we offered, so this should never happen. */ 291232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 291332b31808SJens Wiklander } 291432b31808SJens Wiklander 291532b31808SJens Wiklander /* uint16 to store content length */ 291632b31808SJens Wiklander const size_t content_len_size = 2; 291732b31808SJens Wiklander 291832b31808SJens Wiklander header_len = 4; 291932b31808SJens Wiklander 292032b31808SJens Wiklander if (header_len + content_len_size + ssl->conf->psk_identity_len 292132b31808SJens Wiklander > MBEDTLS_SSL_OUT_CONTENT_LEN) { 292232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 292332b31808SJens Wiklander ("psk identity too long or SSL buffer too short")); 292432b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 292532b31808SJens Wiklander } 292632b31808SJens Wiklander 292732b31808SJens Wiklander unsigned char *p = ssl->out_msg + header_len; 292832b31808SJens Wiklander 292932b31808SJens Wiklander *p++ = MBEDTLS_BYTE_1(ssl->conf->psk_identity_len); 293032b31808SJens Wiklander *p++ = MBEDTLS_BYTE_0(ssl->conf->psk_identity_len); 293132b31808SJens Wiklander header_len += content_len_size; 293232b31808SJens Wiklander 293332b31808SJens Wiklander memcpy(p, ssl->conf->psk_identity, 293432b31808SJens Wiklander ssl->conf->psk_identity_len); 293532b31808SJens Wiklander p += ssl->conf->psk_identity_len; 293632b31808SJens Wiklander 293732b31808SJens Wiklander header_len += ssl->conf->psk_identity_len; 293832b31808SJens Wiklander 293932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); 294032b31808SJens Wiklander 294132b31808SJens Wiklander /* 294232b31808SJens Wiklander * Generate EC private key for ECDHE exchange. 294332b31808SJens Wiklander */ 294432b31808SJens Wiklander 294532b31808SJens Wiklander /* The master secret is obtained from the shared ECDH secret by 294632b31808SJens Wiklander * applying the TLS 1.2 PRF with a specific salt and label. While 294732b31808SJens Wiklander * the PSA Crypto API encourages combining key agreement schemes 294832b31808SJens Wiklander * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not 294932b31808SJens Wiklander * yet support the provisioning of salt + label to the KDF. 295032b31808SJens Wiklander * For the time being, we therefore need to split the computation 295132b31808SJens Wiklander * of the ECDH secret and the application of the TLS 1.2 PRF. */ 295232b31808SJens Wiklander key_attributes = psa_key_attributes_init(); 295332b31808SJens Wiklander psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 295432b31808SJens Wiklander psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2955b0563631STom Van Eyck psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); 2956b0563631STom Van Eyck psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); 295732b31808SJens Wiklander 295832b31808SJens Wiklander /* Generate ECDH private key. */ 295932b31808SJens Wiklander status = psa_generate_key(&key_attributes, 2960b0563631STom Van Eyck &handshake->xxdh_psa_privkey); 296132b31808SJens Wiklander if (status != PSA_SUCCESS) { 296232b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status); 296332b31808SJens Wiklander } 296432b31808SJens Wiklander 296532b31808SJens Wiklander /* Export the public part of the ECDH private key from PSA. 296632b31808SJens Wiklander * The export format is an ECPoint structure as expected by TLS, 296732b31808SJens Wiklander * but we just need to add a length byte before that. */ 296832b31808SJens Wiklander unsigned char *own_pubkey = p + 1; 296932b31808SJens Wiklander unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 297032b31808SJens Wiklander size_t own_pubkey_max_len = (size_t) (end - own_pubkey); 297132b31808SJens Wiklander size_t own_pubkey_len = 0; 297232b31808SJens Wiklander 2973b0563631STom Van Eyck status = psa_export_public_key(handshake->xxdh_psa_privkey, 297432b31808SJens Wiklander own_pubkey, own_pubkey_max_len, 297532b31808SJens Wiklander &own_pubkey_len); 297632b31808SJens Wiklander if (status != PSA_SUCCESS) { 2977b0563631STom Van Eyck psa_destroy_key(handshake->xxdh_psa_privkey); 2978b0563631STom Van Eyck handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 297932b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status); 298032b31808SJens Wiklander } 298132b31808SJens Wiklander 298232b31808SJens Wiklander *p = (unsigned char) own_pubkey_len; 298332b31808SJens Wiklander content_len = own_pubkey_len + 1; 298432b31808SJens Wiklander 298532b31808SJens Wiklander /* As RFC 5489 section 2, the premaster secret is formed as follows: 298632b31808SJens Wiklander * - a uint16 containing the length (in octets) of the ECDH computation 298732b31808SJens Wiklander * - the octet string produced by the ECDH computation 298832b31808SJens Wiklander * - a uint16 containing the length (in octets) of the PSK 298932b31808SJens Wiklander * - the PSK itself 299032b31808SJens Wiklander */ 299132b31808SJens Wiklander unsigned char *pms = ssl->handshake->premaster; 299232b31808SJens Wiklander const unsigned char * const pms_end = pms + 299332b31808SJens Wiklander sizeof(ssl->handshake->premaster); 299432b31808SJens Wiklander /* uint16 to store length (in octets) of the ECDH computation */ 299532b31808SJens Wiklander const size_t zlen_size = 2; 299632b31808SJens Wiklander size_t zlen = 0; 299732b31808SJens Wiklander 299832b31808SJens Wiklander /* Perform ECDH computation after the uint16 reserved for the length */ 299932b31808SJens Wiklander status = psa_raw_key_agreement(PSA_ALG_ECDH, 3000b0563631STom Van Eyck handshake->xxdh_psa_privkey, 3001b0563631STom Van Eyck handshake->xxdh_psa_peerkey, 3002b0563631STom Van Eyck handshake->xxdh_psa_peerkey_len, 300332b31808SJens Wiklander pms + zlen_size, 300432b31808SJens Wiklander pms_end - (pms + zlen_size), 300532b31808SJens Wiklander &zlen); 300632b31808SJens Wiklander 3007b0563631STom Van Eyck destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); 3008b0563631STom Van Eyck handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 300932b31808SJens Wiklander 301032b31808SJens Wiklander if (status != PSA_SUCCESS) { 301132b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status); 301232b31808SJens Wiklander } else if (destruction_status != PSA_SUCCESS) { 301332b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(destruction_status); 301432b31808SJens Wiklander } 301532b31808SJens Wiklander 301632b31808SJens Wiklander /* Write the ECDH computation length before the ECDH computation */ 301732b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(zlen, pms, 0); 301832b31808SJens Wiklander pms += zlen_size + zlen; 301932b31808SJens Wiklander } else 302032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO && 302132b31808SJens Wiklander MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 302232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 302332b31808SJens Wiklander if (mbedtls_ssl_ciphersuite_uses_psk(ciphersuite_info)) { 302432b31808SJens Wiklander /* 302532b31808SJens Wiklander * opaque psk_identity<0..2^16-1>; 302632b31808SJens Wiklander */ 302732b31808SJens Wiklander if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { 302832b31808SJens Wiklander /* We don't offer PSK suites if we don't have a PSK, 302932b31808SJens Wiklander * and we check that the server's choice is among the 303032b31808SJens Wiklander * ciphersuites we offered, so this should never happen. */ 303132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 303232b31808SJens Wiklander } 303332b31808SJens Wiklander 303432b31808SJens Wiklander header_len = 4; 303532b31808SJens Wiklander content_len = ssl->conf->psk_identity_len; 303632b31808SJens Wiklander 303732b31808SJens Wiklander if (header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { 303832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 303932b31808SJens Wiklander ("psk identity too long or SSL buffer too short")); 304032b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 304132b31808SJens Wiklander } 304232b31808SJens Wiklander 304332b31808SJens Wiklander ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); 304432b31808SJens Wiklander ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); 304532b31808SJens Wiklander 304632b31808SJens Wiklander memcpy(ssl->out_msg + header_len, 304732b31808SJens Wiklander ssl->conf->psk_identity, 304832b31808SJens Wiklander ssl->conf->psk_identity_len); 304932b31808SJens Wiklander header_len += ssl->conf->psk_identity_len; 305032b31808SJens Wiklander 305132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) 305232b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) { 305332b31808SJens Wiklander content_len = 0; 305432b31808SJens Wiklander } else 305532b31808SJens Wiklander #endif 305632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 305732b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 305832b31808SJens Wiklander if ((ret = ssl_write_encrypted_pms(ssl, header_len, 305932b31808SJens Wiklander &content_len, 2)) != 0) { 306032b31808SJens Wiklander return ret; 306132b31808SJens Wiklander } 306232b31808SJens Wiklander } else 306332b31808SJens Wiklander #endif 306432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 306532b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { 306632b31808SJens Wiklander /* 306732b31808SJens Wiklander * ClientDiffieHellmanPublic public (DHM send G^X mod P) 306832b31808SJens Wiklander */ 306932b31808SJens Wiklander content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); 307032b31808SJens Wiklander 307132b31808SJens Wiklander if (header_len + 2 + content_len > 307232b31808SJens Wiklander MBEDTLS_SSL_OUT_CONTENT_LEN) { 307332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 307432b31808SJens Wiklander ("psk identity or DHM size too long or SSL buffer too short")); 307532b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 307632b31808SJens Wiklander } 307732b31808SJens Wiklander 307832b31808SJens Wiklander ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); 307932b31808SJens Wiklander ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); 308032b31808SJens Wiklander 308132b31808SJens Wiklander ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, 308232b31808SJens Wiklander (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), 308332b31808SJens Wiklander &ssl->out_msg[header_len], content_len, 308432b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 308532b31808SJens Wiklander if (ret != 0) { 308632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); 308732b31808SJens Wiklander return ret; 308832b31808SJens Wiklander } 308932b31808SJens Wiklander 309032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 309132b31808SJens Wiklander unsigned char *pms = ssl->handshake->premaster; 309232b31808SJens Wiklander unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster); 309332b31808SJens Wiklander size_t pms_len; 309432b31808SJens Wiklander 309532b31808SJens Wiklander /* Write length only when we know the actual value */ 309632b31808SJens Wiklander if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 309732b31808SJens Wiklander pms + 2, pms_end - (pms + 2), &pms_len, 309832b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 309932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 310032b31808SJens Wiklander return ret; 310132b31808SJens Wiklander } 310232b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0); 310332b31808SJens Wiklander pms += 2 + pms_len; 310432b31808SJens Wiklander 310532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 310632b31808SJens Wiklander #endif 310732b31808SJens Wiklander } else 310832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 310932b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 311032b31808SJens Wiklander defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 311132b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 311232b31808SJens Wiklander /* 311332b31808SJens Wiklander * ClientECDiffieHellmanPublic public; 311432b31808SJens Wiklander */ 311532b31808SJens Wiklander ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, 311632b31808SJens Wiklander &content_len, 311732b31808SJens Wiklander &ssl->out_msg[header_len], 311832b31808SJens Wiklander MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, 311932b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 312032b31808SJens Wiklander if (ret != 0) { 312132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); 312232b31808SJens Wiklander return ret; 312332b31808SJens Wiklander } 312432b31808SJens Wiklander 312532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 312632b31808SJens Wiklander MBEDTLS_DEBUG_ECDH_Q); 312732b31808SJens Wiklander } else 312832b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 312932b31808SJens Wiklander { 313032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 313132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 313232b31808SJens Wiklander } 313332b31808SJens Wiklander 313432b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) 313532b31808SJens Wiklander if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 3136b0563631STom Van Eyck (mbedtls_key_exchange_type_t) ciphersuite_info-> 3137b0563631STom Van Eyck key_exchange)) != 0) { 313832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, 313932b31808SJens Wiklander "mbedtls_ssl_psk_derive_premaster", ret); 314032b31808SJens Wiklander return ret; 314132b31808SJens Wiklander } 314232b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */ 314332b31808SJens Wiklander } else 314432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 314532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 314632b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { 314732b31808SJens Wiklander header_len = 4; 314832b31808SJens Wiklander if ((ret = ssl_write_encrypted_pms(ssl, header_len, 314932b31808SJens Wiklander &content_len, 0)) != 0) { 315032b31808SJens Wiklander return ret; 315132b31808SJens Wiklander } 315232b31808SJens Wiklander } else 315332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ 315432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 315532b31808SJens Wiklander if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 315632b31808SJens Wiklander header_len = 4; 315732b31808SJens Wiklander 315832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 315932b31808SJens Wiklander unsigned char *out_p = ssl->out_msg + header_len; 316032b31808SJens Wiklander unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - 316132b31808SJens Wiklander header_len; 316232b31808SJens Wiklander ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 316332b31808SJens Wiklander out_p, end_p - out_p, &content_len, 316432b31808SJens Wiklander MBEDTLS_ECJPAKE_ROUND_TWO); 316532b31808SJens Wiklander if (ret != 0) { 316632b31808SJens Wiklander psa_destroy_key(ssl->handshake->psa_pake_password); 316732b31808SJens Wiklander psa_pake_abort(&ssl->handshake->psa_pake_ctx); 316832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 316932b31808SJens Wiklander return ret; 317032b31808SJens Wiklander } 317132b31808SJens Wiklander #else 317232b31808SJens Wiklander ret = mbedtls_ecjpake_write_round_two(&ssl->handshake->ecjpake_ctx, 317332b31808SJens Wiklander ssl->out_msg + header_len, 317432b31808SJens Wiklander MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, 317532b31808SJens Wiklander &content_len, 317632b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 317732b31808SJens Wiklander if (ret != 0) { 317832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret); 317932b31808SJens Wiklander return ret; 318032b31808SJens Wiklander } 318132b31808SJens Wiklander 318232b31808SJens Wiklander ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx, 318332b31808SJens Wiklander ssl->handshake->premaster, 32, &ssl->handshake->pmslen, 318432b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng); 318532b31808SJens Wiklander if (ret != 0) { 318632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret); 318732b31808SJens Wiklander return ret; 318832b31808SJens Wiklander } 318932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 319032b31808SJens Wiklander } else 319132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ 319232b31808SJens Wiklander { 319332b31808SJens Wiklander ((void) ciphersuite_info); 319432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 319532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 319632b31808SJens Wiklander } 319732b31808SJens Wiklander 319832b31808SJens Wiklander ssl->out_msglen = header_len + content_len; 319932b31808SJens Wiklander ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 320032b31808SJens Wiklander ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; 320132b31808SJens Wiklander 320232b31808SJens Wiklander ssl->state++; 320332b31808SJens Wiklander 320432b31808SJens Wiklander if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 320532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 320632b31808SJens Wiklander return ret; 320732b31808SJens Wiklander } 320832b31808SJens Wiklander 320932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client key exchange")); 321032b31808SJens Wiklander 321132b31808SJens Wiklander return 0; 321232b31808SJens Wiklander } 321332b31808SJens Wiklander 321432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 321532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 321632b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) 321732b31808SJens Wiklander { 321832b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 321932b31808SJens Wiklander ssl->handshake->ciphersuite_info; 322032b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 322132b31808SJens Wiklander 322232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); 322332b31808SJens Wiklander 322432b31808SJens Wiklander if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 322532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 322632b31808SJens Wiklander return ret; 322732b31808SJens Wiklander } 322832b31808SJens Wiklander 322932b31808SJens Wiklander if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 323032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 323132b31808SJens Wiklander ssl->state++; 323232b31808SJens Wiklander return 0; 323332b31808SJens Wiklander } 323432b31808SJens Wiklander 323532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 323632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 323732b31808SJens Wiklander } 323832b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 323932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 324032b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) 324132b31808SJens Wiklander { 324232b31808SJens Wiklander int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 324332b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 324432b31808SJens Wiklander ssl->handshake->ciphersuite_info; 324532b31808SJens Wiklander size_t n = 0, offset = 0; 324632b31808SJens Wiklander unsigned char hash[48]; 324732b31808SJens Wiklander unsigned char *hash_start = hash; 324832b31808SJens Wiklander mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; 324932b31808SJens Wiklander size_t hashlen; 325032b31808SJens Wiklander void *rs_ctx = NULL; 325132b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 3252b0563631STom Van Eyck size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf); 325332b31808SJens Wiklander #else 3254b0563631STom Van Eyck size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf); 325532b31808SJens Wiklander #endif 325632b31808SJens Wiklander 325732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); 325832b31808SJens Wiklander 325932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 326032b31808SJens Wiklander if (ssl->handshake->ecrs_enabled && 326132b31808SJens Wiklander ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign) { 326232b31808SJens Wiklander goto sign; 326332b31808SJens Wiklander } 326432b31808SJens Wiklander #endif 326532b31808SJens Wiklander 326632b31808SJens Wiklander if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 326732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 326832b31808SJens Wiklander return ret; 326932b31808SJens Wiklander } 327032b31808SJens Wiklander 327132b31808SJens Wiklander if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 327232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 327332b31808SJens Wiklander ssl->state++; 327432b31808SJens Wiklander return 0; 327532b31808SJens Wiklander } 327632b31808SJens Wiklander 327732b31808SJens Wiklander if (ssl->handshake->client_auth == 0 || 327832b31808SJens Wiklander mbedtls_ssl_own_cert(ssl) == NULL) { 327932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 328032b31808SJens Wiklander ssl->state++; 328132b31808SJens Wiklander return 0; 328232b31808SJens Wiklander } 328332b31808SJens Wiklander 328432b31808SJens Wiklander if (mbedtls_ssl_own_key(ssl) == NULL) { 328532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key for certificate")); 328632b31808SJens Wiklander return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 328732b31808SJens Wiklander } 328832b31808SJens Wiklander 328932b31808SJens Wiklander /* 329032b31808SJens Wiklander * Make a signature of the handshake digests 329132b31808SJens Wiklander */ 329232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 329332b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 329432b31808SJens Wiklander ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; 329532b31808SJens Wiklander } 329632b31808SJens Wiklander 329732b31808SJens Wiklander sign: 329832b31808SJens Wiklander #endif 329932b31808SJens Wiklander 330032b31808SJens Wiklander ret = ssl->handshake->calc_verify(ssl, hash, &hashlen); 330132b31808SJens Wiklander if (0 != ret) { 330232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); 330332b31808SJens Wiklander return ret; 330432b31808SJens Wiklander } 330532b31808SJens Wiklander 330632b31808SJens Wiklander /* 330732b31808SJens Wiklander * digitally-signed struct { 330832b31808SJens Wiklander * opaque handshake_messages[handshake_messages_length]; 330932b31808SJens Wiklander * }; 331032b31808SJens Wiklander * 331132b31808SJens Wiklander * Taking shortcut here. We assume that the server always allows the 331232b31808SJens Wiklander * PRF Hash function and has sent it in the allowed signature 331332b31808SJens Wiklander * algorithms list received in the Certificate Request message. 331432b31808SJens Wiklander * 331532b31808SJens Wiklander * Until we encounter a server that does not, we will take this 331632b31808SJens Wiklander * shortcut. 331732b31808SJens Wiklander * 331832b31808SJens Wiklander * Reason: Otherwise we should have running hashes for SHA512 and 331932b31808SJens Wiklander * SHA224 in order to satisfy 'weird' needs from the server 332032b31808SJens Wiklander * side. 332132b31808SJens Wiklander */ 332232b31808SJens Wiklander if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) { 332332b31808SJens Wiklander md_alg = MBEDTLS_MD_SHA384; 332432b31808SJens Wiklander ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; 332532b31808SJens Wiklander } else { 332632b31808SJens Wiklander md_alg = MBEDTLS_MD_SHA256; 332732b31808SJens Wiklander ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; 332832b31808SJens Wiklander } 332932b31808SJens Wiklander ssl->out_msg[5] = mbedtls_ssl_sig_from_pk(mbedtls_ssl_own_key(ssl)); 333032b31808SJens Wiklander 333132b31808SJens Wiklander /* Info from md_alg will be used instead */ 333232b31808SJens Wiklander hashlen = 0; 333332b31808SJens Wiklander offset = 2; 333432b31808SJens Wiklander 333532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 333632b31808SJens Wiklander if (ssl->handshake->ecrs_enabled) { 333732b31808SJens Wiklander rs_ctx = &ssl->handshake->ecrs_ctx.pk; 333832b31808SJens Wiklander } 333932b31808SJens Wiklander #endif 334032b31808SJens Wiklander 334132b31808SJens Wiklander if ((ret = mbedtls_pk_sign_restartable(mbedtls_ssl_own_key(ssl), 334232b31808SJens Wiklander md_alg, hash_start, hashlen, 334332b31808SJens Wiklander ssl->out_msg + 6 + offset, 334432b31808SJens Wiklander out_buf_len - 6 - offset, 334532b31808SJens Wiklander &n, 334632b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx)) != 0) { 334732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret); 334832b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 334932b31808SJens Wiklander if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 335032b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 335132b31808SJens Wiklander } 335232b31808SJens Wiklander #endif 335332b31808SJens Wiklander return ret; 335432b31808SJens Wiklander } 335532b31808SJens Wiklander 335632b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(n, ssl->out_msg, offset + 4); 335732b31808SJens Wiklander 335832b31808SJens Wiklander ssl->out_msglen = 6 + n + offset; 335932b31808SJens Wiklander ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 336032b31808SJens Wiklander ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; 336132b31808SJens Wiklander 336232b31808SJens Wiklander ssl->state++; 336332b31808SJens Wiklander 336432b31808SJens Wiklander if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 336532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 336632b31808SJens Wiklander return ret; 336732b31808SJens Wiklander } 336832b31808SJens Wiklander 336932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify")); 337032b31808SJens Wiklander 337132b31808SJens Wiklander return ret; 337232b31808SJens Wiklander } 337332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 337432b31808SJens Wiklander 337532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 337632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 337732b31808SJens Wiklander static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl) 337832b31808SJens Wiklander { 337932b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 338032b31808SJens Wiklander uint32_t lifetime; 338132b31808SJens Wiklander size_t ticket_len; 338232b31808SJens Wiklander unsigned char *ticket; 338332b31808SJens Wiklander const unsigned char *msg; 338432b31808SJens Wiklander 338532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket")); 338632b31808SJens Wiklander 338732b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 338832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 338932b31808SJens Wiklander return ret; 339032b31808SJens Wiklander } 339132b31808SJens Wiklander 339232b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 339332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 339432b31808SJens Wiklander mbedtls_ssl_send_alert_message( 339532b31808SJens Wiklander ssl, 339632b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 339732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 339832b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 339932b31808SJens Wiklander } 340032b31808SJens Wiklander 340132b31808SJens Wiklander /* 340232b31808SJens Wiklander * struct { 340332b31808SJens Wiklander * uint32 ticket_lifetime_hint; 340432b31808SJens Wiklander * opaque ticket<0..2^16-1>; 340532b31808SJens Wiklander * } NewSessionTicket; 340632b31808SJens Wiklander * 340732b31808SJens Wiklander * 0 . 3 ticket_lifetime_hint 340832b31808SJens Wiklander * 4 . 5 ticket_len (n) 340932b31808SJens Wiklander * 6 . 5+n ticket content 341032b31808SJens Wiklander */ 341132b31808SJens Wiklander if (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || 341232b31808SJens Wiklander ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len(ssl)) { 341332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 341432b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 341532b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 341632b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 341732b31808SJens Wiklander } 341832b31808SJens Wiklander 341932b31808SJens Wiklander msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 342032b31808SJens Wiklander 3421b0563631STom Van Eyck lifetime = MBEDTLS_GET_UINT32_BE(msg, 0); 342232b31808SJens Wiklander 3423b0563631STom Van Eyck ticket_len = MBEDTLS_GET_UINT16_BE(msg, 4); 342432b31808SJens Wiklander 342532b31808SJens Wiklander if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) { 342632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 342732b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 342832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 342932b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 343032b31808SJens Wiklander } 343132b31808SJens Wiklander 343232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len)); 343332b31808SJens Wiklander 343432b31808SJens Wiklander /* We're not waiting for a NewSessionTicket message any more */ 343532b31808SJens Wiklander ssl->handshake->new_session_ticket = 0; 343632b31808SJens Wiklander ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; 343732b31808SJens Wiklander 343832b31808SJens Wiklander /* 343932b31808SJens Wiklander * Zero-length ticket means the server changed his mind and doesn't want 344032b31808SJens Wiklander * to send a ticket after all, so just forget it 344132b31808SJens Wiklander */ 344232b31808SJens Wiklander if (ticket_len == 0) { 344332b31808SJens Wiklander return 0; 344432b31808SJens Wiklander } 344532b31808SJens Wiklander 344632b31808SJens Wiklander if (ssl->session != NULL && ssl->session->ticket != NULL) { 3447b0563631STom Van Eyck mbedtls_zeroize_and_free(ssl->session->ticket, 344832b31808SJens Wiklander ssl->session->ticket_len); 344932b31808SJens Wiklander ssl->session->ticket = NULL; 345032b31808SJens Wiklander ssl->session->ticket_len = 0; 345132b31808SJens Wiklander } 345232b31808SJens Wiklander 3453b0563631STom Van Eyck mbedtls_zeroize_and_free(ssl->session_negotiate->ticket, 345432b31808SJens Wiklander ssl->session_negotiate->ticket_len); 345532b31808SJens Wiklander ssl->session_negotiate->ticket = NULL; 345632b31808SJens Wiklander ssl->session_negotiate->ticket_len = 0; 345732b31808SJens Wiklander 345832b31808SJens Wiklander if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) { 345932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed")); 346032b31808SJens Wiklander mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 346132b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 346232b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED; 346332b31808SJens Wiklander } 346432b31808SJens Wiklander 346532b31808SJens Wiklander memcpy(ticket, msg + 6, ticket_len); 346632b31808SJens Wiklander 346732b31808SJens Wiklander ssl->session_negotiate->ticket = ticket; 346832b31808SJens Wiklander ssl->session_negotiate->ticket_len = ticket_len; 346932b31808SJens Wiklander ssl->session_negotiate->ticket_lifetime = lifetime; 347032b31808SJens Wiklander 347132b31808SJens Wiklander /* 347232b31808SJens Wiklander * RFC 5077 section 3.4: 347332b31808SJens Wiklander * "If the client receives a session ticket from the server, then it 347432b31808SJens Wiklander * discards any Session ID that was sent in the ServerHello." 347532b31808SJens Wiklander */ 347632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("ticket in use, discarding session id")); 347732b31808SJens Wiklander ssl->session_negotiate->id_len = 0; 347832b31808SJens Wiklander 347932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket")); 348032b31808SJens Wiklander 348132b31808SJens Wiklander return 0; 348232b31808SJens Wiklander } 348332b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */ 348432b31808SJens Wiklander 348532b31808SJens Wiklander /* 348632b31808SJens Wiklander * SSL handshake -- client side -- single step 348732b31808SJens Wiklander */ 348832b31808SJens Wiklander int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) 348932b31808SJens Wiklander { 349032b31808SJens Wiklander int ret = 0; 349132b31808SJens Wiklander 349232b31808SJens Wiklander /* Change state now, so that it is right in mbedtls_ssl_read_record(), used 349332b31808SJens Wiklander * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ 349432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 349532b31808SJens Wiklander if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && 349632b31808SJens Wiklander ssl->handshake->new_session_ticket != 0) { 349732b31808SJens Wiklander ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET; 349832b31808SJens Wiklander } 349932b31808SJens Wiklander #endif 350032b31808SJens Wiklander 350132b31808SJens Wiklander switch (ssl->state) { 350232b31808SJens Wiklander case MBEDTLS_SSL_HELLO_REQUEST: 350332b31808SJens Wiklander ssl->state = MBEDTLS_SSL_CLIENT_HELLO; 350432b31808SJens Wiklander break; 350532b31808SJens Wiklander 350632b31808SJens Wiklander /* 350732b31808SJens Wiklander * ==> ClientHello 350832b31808SJens Wiklander */ 350932b31808SJens Wiklander case MBEDTLS_SSL_CLIENT_HELLO: 351032b31808SJens Wiklander ret = mbedtls_ssl_write_client_hello(ssl); 351132b31808SJens Wiklander break; 351232b31808SJens Wiklander 351332b31808SJens Wiklander /* 351432b31808SJens Wiklander * <== ServerHello 351532b31808SJens Wiklander * Certificate 351632b31808SJens Wiklander * ( ServerKeyExchange ) 351732b31808SJens Wiklander * ( CertificateRequest ) 351832b31808SJens Wiklander * ServerHelloDone 351932b31808SJens Wiklander */ 352032b31808SJens Wiklander case MBEDTLS_SSL_SERVER_HELLO: 352132b31808SJens Wiklander ret = ssl_parse_server_hello(ssl); 352232b31808SJens Wiklander break; 352332b31808SJens Wiklander 352432b31808SJens Wiklander case MBEDTLS_SSL_SERVER_CERTIFICATE: 352532b31808SJens Wiklander ret = mbedtls_ssl_parse_certificate(ssl); 352632b31808SJens Wiklander break; 352732b31808SJens Wiklander 352832b31808SJens Wiklander case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: 352932b31808SJens Wiklander ret = ssl_parse_server_key_exchange(ssl); 353032b31808SJens Wiklander break; 353132b31808SJens Wiklander 353232b31808SJens Wiklander case MBEDTLS_SSL_CERTIFICATE_REQUEST: 353332b31808SJens Wiklander ret = ssl_parse_certificate_request(ssl); 353432b31808SJens Wiklander break; 353532b31808SJens Wiklander 353632b31808SJens Wiklander case MBEDTLS_SSL_SERVER_HELLO_DONE: 353732b31808SJens Wiklander ret = ssl_parse_server_hello_done(ssl); 353832b31808SJens Wiklander break; 353932b31808SJens Wiklander 354032b31808SJens Wiklander /* 354132b31808SJens Wiklander * ==> ( Certificate/Alert ) 354232b31808SJens Wiklander * ClientKeyExchange 354332b31808SJens Wiklander * ( CertificateVerify ) 354432b31808SJens Wiklander * ChangeCipherSpec 354532b31808SJens Wiklander * Finished 354632b31808SJens Wiklander */ 354732b31808SJens Wiklander case MBEDTLS_SSL_CLIENT_CERTIFICATE: 354832b31808SJens Wiklander ret = mbedtls_ssl_write_certificate(ssl); 354932b31808SJens Wiklander break; 355032b31808SJens Wiklander 355132b31808SJens Wiklander case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: 355232b31808SJens Wiklander ret = ssl_write_client_key_exchange(ssl); 355332b31808SJens Wiklander break; 355432b31808SJens Wiklander 355532b31808SJens Wiklander case MBEDTLS_SSL_CERTIFICATE_VERIFY: 355632b31808SJens Wiklander ret = ssl_write_certificate_verify(ssl); 355732b31808SJens Wiklander break; 355832b31808SJens Wiklander 355932b31808SJens Wiklander case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: 356032b31808SJens Wiklander ret = mbedtls_ssl_write_change_cipher_spec(ssl); 356132b31808SJens Wiklander break; 356232b31808SJens Wiklander 356332b31808SJens Wiklander case MBEDTLS_SSL_CLIENT_FINISHED: 356432b31808SJens Wiklander ret = mbedtls_ssl_write_finished(ssl); 356532b31808SJens Wiklander break; 356632b31808SJens Wiklander 356732b31808SJens Wiklander /* 356832b31808SJens Wiklander * <== ( NewSessionTicket ) 356932b31808SJens Wiklander * ChangeCipherSpec 357032b31808SJens Wiklander * Finished 357132b31808SJens Wiklander */ 357232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) 357332b31808SJens Wiklander case MBEDTLS_SSL_NEW_SESSION_TICKET: 357432b31808SJens Wiklander ret = ssl_parse_new_session_ticket(ssl); 357532b31808SJens Wiklander break; 357632b31808SJens Wiklander #endif 357732b31808SJens Wiklander 357832b31808SJens Wiklander case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: 357932b31808SJens Wiklander ret = mbedtls_ssl_parse_change_cipher_spec(ssl); 358032b31808SJens Wiklander break; 358132b31808SJens Wiklander 358232b31808SJens Wiklander case MBEDTLS_SSL_SERVER_FINISHED: 358332b31808SJens Wiklander ret = mbedtls_ssl_parse_finished(ssl); 358432b31808SJens Wiklander break; 358532b31808SJens Wiklander 358632b31808SJens Wiklander case MBEDTLS_SSL_FLUSH_BUFFERS: 358732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); 358832b31808SJens Wiklander ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; 358932b31808SJens Wiklander break; 359032b31808SJens Wiklander 359132b31808SJens Wiklander case MBEDTLS_SSL_HANDSHAKE_WRAPUP: 359232b31808SJens Wiklander mbedtls_ssl_handshake_wrapup(ssl); 359332b31808SJens Wiklander break; 359432b31808SJens Wiklander 359532b31808SJens Wiklander default: 359632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); 359732b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 359832b31808SJens Wiklander } 359932b31808SJens Wiklander 360032b31808SJens Wiklander return ret; 360132b31808SJens Wiklander } 360232b31808SJens Wiklander 360332b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */ 3604