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