111fa71b9SJerome Forissier /* 211fa71b9SJerome Forissier * Generic SSL/TLS messaging layer functions 311fa71b9SJerome Forissier * (record layer + retransmission state machine) 411fa71b9SJerome Forissier * 57901324dSJerome Forissier * Copyright The Mbed TLS Contributors 611fa71b9SJerome Forissier * SPDX-License-Identifier: Apache-2.0 711fa71b9SJerome Forissier * 811fa71b9SJerome Forissier * Licensed under the Apache License, Version 2.0 (the "License"); you may 911fa71b9SJerome Forissier * not use this file except in compliance with the License. 1011fa71b9SJerome Forissier * You may obtain a copy of the License at 1111fa71b9SJerome Forissier * 1211fa71b9SJerome Forissier * http://www.apache.org/licenses/LICENSE-2.0 1311fa71b9SJerome Forissier * 1411fa71b9SJerome Forissier * Unless required by applicable law or agreed to in writing, software 1511fa71b9SJerome Forissier * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 1611fa71b9SJerome Forissier * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1711fa71b9SJerome Forissier * See the License for the specific language governing permissions and 1811fa71b9SJerome Forissier * limitations under the License. 1911fa71b9SJerome Forissier */ 2011fa71b9SJerome Forissier /* 2111fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc2246.txt 2211fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc4346.txt 2311fa71b9SJerome Forissier */ 2411fa71b9SJerome Forissier 257901324dSJerome Forissier #include "common.h" 2611fa71b9SJerome Forissier 2711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_TLS_C) 2811fa71b9SJerome Forissier 2911fa71b9SJerome Forissier #include "mbedtls/platform.h" 3011fa71b9SJerome Forissier 3111fa71b9SJerome Forissier #include "mbedtls/ssl.h" 32*32b31808SJens Wiklander #include "ssl_misc.h" 3311fa71b9SJerome Forissier #include "mbedtls/debug.h" 3411fa71b9SJerome Forissier #include "mbedtls/error.h" 3511fa71b9SJerome Forissier #include "mbedtls/platform_util.h" 3611fa71b9SJerome Forissier #include "mbedtls/version.h" 37039e02dfSJerome Forissier #include "constant_time_internal.h" 38039e02dfSJerome Forissier #include "mbedtls/constant_time.h" 397901324dSJerome Forissier 4011fa71b9SJerome Forissier #include <string.h> 4111fa71b9SJerome Forissier 4211fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 4311fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 4411fa71b9SJerome Forissier #include "psa/crypto.h" 4511fa71b9SJerome Forissier #endif 4611fa71b9SJerome Forissier 4711fa71b9SJerome Forissier #if defined(MBEDTLS_X509_CRT_PARSE_C) 4811fa71b9SJerome Forissier #include "mbedtls/oid.h" 4911fa71b9SJerome Forissier #endif 5011fa71b9SJerome Forissier 51*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 52*32b31808SJens Wiklander #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \ 53*32b31808SJens Wiklander psa_to_ssl_errors, \ 54*32b31808SJens Wiklander psa_generic_status_to_mbedtls) 55*32b31808SJens Wiklander #endif 56*32b31808SJens Wiklander 5711fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl); 5811fa71b9SJerome Forissier 5911fa71b9SJerome Forissier /* 6011fa71b9SJerome Forissier * Start a timer. 6111fa71b9SJerome Forissier * Passing millisecs = 0 cancels a running timer. 6211fa71b9SJerome Forissier */ 6311fa71b9SJerome Forissier void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs) 6411fa71b9SJerome Forissier { 65*32b31808SJens Wiklander if (ssl->f_set_timer == NULL) { 6611fa71b9SJerome Forissier return; 67*32b31808SJens Wiklander } 6811fa71b9SJerome Forissier 6911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int) millisecs)); 7011fa71b9SJerome Forissier ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs); 7111fa71b9SJerome Forissier } 7211fa71b9SJerome Forissier 7311fa71b9SJerome Forissier /* 7411fa71b9SJerome Forissier * Return -1 is timer is expired, 0 if it isn't. 7511fa71b9SJerome Forissier */ 7611fa71b9SJerome Forissier int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl) 7711fa71b9SJerome Forissier { 78*32b31808SJens Wiklander if (ssl->f_get_timer == NULL) { 79*32b31808SJens Wiklander return 0; 80*32b31808SJens Wiklander } 8111fa71b9SJerome Forissier 82*32b31808SJens Wiklander if (ssl->f_get_timer(ssl->p_timer) == 2) { 8311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired")); 84*32b31808SJens Wiklander return -1; 8511fa71b9SJerome Forissier } 8611fa71b9SJerome Forissier 87*32b31808SJens Wiklander return 0; 8811fa71b9SJerome Forissier } 8911fa71b9SJerome Forissier 90039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 9111fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, 9211fa71b9SJerome Forissier unsigned char *buf, 9311fa71b9SJerome Forissier size_t len, 9411fa71b9SJerome Forissier mbedtls_record *rec); 9511fa71b9SJerome Forissier 9611fa71b9SJerome Forissier int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl, 9711fa71b9SJerome Forissier unsigned char *buf, 9811fa71b9SJerome Forissier size_t buflen) 9911fa71b9SJerome Forissier { 10011fa71b9SJerome Forissier int ret = 0; 10111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record")); 10211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen); 10311fa71b9SJerome Forissier 10411fa71b9SJerome Forissier /* We don't support record checking in TLS because 105*32b31808SJens Wiklander * there doesn't seem to be a usecase for it. 10611fa71b9SJerome Forissier */ 107*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) { 10811fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 10911fa71b9SJerome Forissier goto exit; 11011fa71b9SJerome Forissier } 11111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 112*32b31808SJens Wiklander else { 11311fa71b9SJerome Forissier mbedtls_record rec; 11411fa71b9SJerome Forissier 11511fa71b9SJerome Forissier ret = ssl_parse_record_header(ssl, buf, buflen, &rec); 116*32b31808SJens Wiklander if (ret != 0) { 11711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret); 11811fa71b9SJerome Forissier goto exit; 11911fa71b9SJerome Forissier } 12011fa71b9SJerome Forissier 121*32b31808SJens Wiklander if (ssl->transform_in != NULL) { 12211fa71b9SJerome Forissier ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec); 123*32b31808SJens Wiklander if (ret != 0) { 12411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret); 12511fa71b9SJerome Forissier goto exit; 12611fa71b9SJerome Forissier } 12711fa71b9SJerome Forissier } 12811fa71b9SJerome Forissier } 12911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 13011fa71b9SJerome Forissier 13111fa71b9SJerome Forissier exit: 13211fa71b9SJerome Forissier /* On success, we have decrypted the buffer in-place, so make 13311fa71b9SJerome Forissier * sure we don't leak any plaintext data. */ 13411fa71b9SJerome Forissier mbedtls_platform_zeroize(buf, buflen); 13511fa71b9SJerome Forissier 13611fa71b9SJerome Forissier /* For the purpose of this API, treat messages with unexpected CID 13711fa71b9SJerome Forissier * as well as such from future epochs as unexpected. */ 13811fa71b9SJerome Forissier if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID || 139*32b31808SJens Wiklander ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { 14011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 14111fa71b9SJerome Forissier } 14211fa71b9SJerome Forissier 14311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record")); 144*32b31808SJens Wiklander return ret; 14511fa71b9SJerome Forissier } 14611fa71b9SJerome Forissier 14711fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0 14811fa71b9SJerome Forissier #define SSL_FORCE_FLUSH 1 14911fa71b9SJerome Forissier 15011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 15111fa71b9SJerome Forissier 15211fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */ 15311fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, 15411fa71b9SJerome Forissier uint8_t slot); 15511fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl); 156039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 15711fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl); 158039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 15911fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl); 160039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 16111fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl); 162039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 16311fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl, 16411fa71b9SJerome Forissier mbedtls_record const *rec); 165039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 16611fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl); 16711fa71b9SJerome Forissier 16811fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl) 16911fa71b9SJerome Forissier { 17011fa71b9SJerome Forissier size_t mtu = mbedtls_ssl_get_current_mtu(ssl); 17111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 17211fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 17311fa71b9SJerome Forissier #else 17411fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 17511fa71b9SJerome Forissier #endif 17611fa71b9SJerome Forissier 177*32b31808SJens Wiklander if (mtu != 0 && mtu < out_buf_len) { 178*32b31808SJens Wiklander return mtu; 179*32b31808SJens Wiklander } 18011fa71b9SJerome Forissier 181*32b31808SJens Wiklander return out_buf_len; 18211fa71b9SJerome Forissier } 18311fa71b9SJerome Forissier 184039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 18511fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl) 18611fa71b9SJerome Forissier { 18711fa71b9SJerome Forissier size_t const bytes_written = ssl->out_left; 18811fa71b9SJerome Forissier size_t const mtu = ssl_get_maximum_datagram_size(ssl); 18911fa71b9SJerome Forissier 19011fa71b9SJerome Forissier /* Double-check that the write-index hasn't gone 19111fa71b9SJerome Forissier * past what we can transmit in a single datagram. */ 192*32b31808SJens Wiklander if (bytes_written > mtu) { 19311fa71b9SJerome Forissier /* Should never happen... */ 194*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 19511fa71b9SJerome Forissier } 19611fa71b9SJerome Forissier 197*32b31808SJens Wiklander return (int) (mtu - bytes_written); 19811fa71b9SJerome Forissier } 19911fa71b9SJerome Forissier 200039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 20111fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl) 20211fa71b9SJerome Forissier { 20311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 20411fa71b9SJerome Forissier size_t remaining, expansion; 20511fa71b9SJerome Forissier size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; 20611fa71b9SJerome Forissier 20711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 20811fa71b9SJerome Forissier const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl); 20911fa71b9SJerome Forissier 210*32b31808SJens Wiklander if (max_len > mfl) { 21111fa71b9SJerome Forissier max_len = mfl; 212*32b31808SJens Wiklander } 21311fa71b9SJerome Forissier 21411fa71b9SJerome Forissier /* By the standard (RFC 6066 Sect. 4), the MFL extension 21511fa71b9SJerome Forissier * only limits the maximum record payload size, so in theory 21611fa71b9SJerome Forissier * we would be allowed to pack multiple records of payload size 21711fa71b9SJerome Forissier * MFL into a single datagram. However, this would mean that there's 21811fa71b9SJerome Forissier * no way to explicitly communicate MTU restrictions to the peer. 21911fa71b9SJerome Forissier * 22011fa71b9SJerome Forissier * The following reduction of max_len makes sure that we never 22111fa71b9SJerome Forissier * write datagrams larger than MFL + Record Expansion Overhead. 22211fa71b9SJerome Forissier */ 223*32b31808SJens Wiklander if (max_len <= ssl->out_left) { 224*32b31808SJens Wiklander return 0; 225*32b31808SJens Wiklander } 22611fa71b9SJerome Forissier 22711fa71b9SJerome Forissier max_len -= ssl->out_left; 22811fa71b9SJerome Forissier #endif 22911fa71b9SJerome Forissier 23011fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram(ssl); 231*32b31808SJens Wiklander if (ret < 0) { 232*32b31808SJens Wiklander return ret; 233*32b31808SJens Wiklander } 23411fa71b9SJerome Forissier remaining = (size_t) ret; 23511fa71b9SJerome Forissier 23611fa71b9SJerome Forissier ret = mbedtls_ssl_get_record_expansion(ssl); 237*32b31808SJens Wiklander if (ret < 0) { 238*32b31808SJens Wiklander return ret; 239*32b31808SJens Wiklander } 24011fa71b9SJerome Forissier expansion = (size_t) ret; 24111fa71b9SJerome Forissier 242*32b31808SJens Wiklander if (remaining <= expansion) { 243*32b31808SJens Wiklander return 0; 244*32b31808SJens Wiklander } 24511fa71b9SJerome Forissier 24611fa71b9SJerome Forissier remaining -= expansion; 247*32b31808SJens Wiklander if (remaining >= max_len) { 24811fa71b9SJerome Forissier remaining = max_len; 249*32b31808SJens Wiklander } 25011fa71b9SJerome Forissier 251*32b31808SJens Wiklander return (int) remaining; 25211fa71b9SJerome Forissier } 25311fa71b9SJerome Forissier 25411fa71b9SJerome Forissier /* 25511fa71b9SJerome Forissier * Double the retransmit timeout value, within the allowed range, 25611fa71b9SJerome Forissier * returning -1 if the maximum value has already been reached. 25711fa71b9SJerome Forissier */ 258039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 25911fa71b9SJerome Forissier static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl) 26011fa71b9SJerome Forissier { 26111fa71b9SJerome Forissier uint32_t new_timeout; 26211fa71b9SJerome Forissier 263*32b31808SJens Wiklander if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max) { 264*32b31808SJens Wiklander return -1; 265*32b31808SJens Wiklander } 26611fa71b9SJerome Forissier 26711fa71b9SJerome Forissier /* Implement the final paragraph of RFC 6347 section 4.1.1.1 26811fa71b9SJerome Forissier * in the following way: after the initial transmission and a first 26911fa71b9SJerome Forissier * retransmission, back off to a temporary estimated MTU of 508 bytes. 27011fa71b9SJerome Forissier * This value is guaranteed to be deliverable (if not guaranteed to be 27111fa71b9SJerome Forissier * delivered) of any compliant IPv4 (and IPv6) network, and should work 27211fa71b9SJerome Forissier * on most non-IP stacks too. */ 273*32b31808SJens Wiklander if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) { 27411fa71b9SJerome Forissier ssl->handshake->mtu = 508; 27511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes", ssl->handshake->mtu)); 27611fa71b9SJerome Forissier } 27711fa71b9SJerome Forissier 27811fa71b9SJerome Forissier new_timeout = 2 * ssl->handshake->retransmit_timeout; 27911fa71b9SJerome Forissier 28011fa71b9SJerome Forissier /* Avoid arithmetic overflow and range overflow */ 28111fa71b9SJerome Forissier if (new_timeout < ssl->handshake->retransmit_timeout || 282*32b31808SJens Wiklander new_timeout > ssl->conf->hs_timeout_max) { 28311fa71b9SJerome Forissier new_timeout = ssl->conf->hs_timeout_max; 28411fa71b9SJerome Forissier } 28511fa71b9SJerome Forissier 28611fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = new_timeout; 2877901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs", 2887901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout)); 28911fa71b9SJerome Forissier 290*32b31808SJens Wiklander return 0; 29111fa71b9SJerome Forissier } 29211fa71b9SJerome Forissier 29311fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl) 29411fa71b9SJerome Forissier { 29511fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; 2967901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs", 2977901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout)); 29811fa71b9SJerome Forissier } 29911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 30011fa71b9SJerome Forissier 30111fa71b9SJerome Forissier /* 30211fa71b9SJerome Forissier * Encryption/decryption functions 30311fa71b9SJerome Forissier */ 30411fa71b9SJerome Forissier 305*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3) 3067901324dSJerome Forissier 3077901324dSJerome Forissier static size_t ssl_compute_padding_length(size_t len, 3087901324dSJerome Forissier size_t granularity) 3097901324dSJerome Forissier { 310*32b31808SJens Wiklander return (granularity - (len + 1) % granularity) % granularity; 3117901324dSJerome Forissier } 3127901324dSJerome Forissier 3137901324dSJerome Forissier /* This functions transforms a (D)TLS plaintext fragment and a record content 3147901324dSJerome Forissier * type into an instance of the (D)TLSInnerPlaintext structure. This is used 3157901324dSJerome Forissier * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect 3167901324dSJerome Forissier * a record's content type. 31711fa71b9SJerome Forissier * 31811fa71b9SJerome Forissier * struct { 31911fa71b9SJerome Forissier * opaque content[DTLSPlaintext.length]; 32011fa71b9SJerome Forissier * ContentType real_type; 32111fa71b9SJerome Forissier * uint8 zeros[length_of_padding]; 3227901324dSJerome Forissier * } (D)TLSInnerPlaintext; 32311fa71b9SJerome Forissier * 32411fa71b9SJerome Forissier * Input: 32511fa71b9SJerome Forissier * - `content`: The beginning of the buffer holding the 32611fa71b9SJerome Forissier * plaintext to be wrapped. 32711fa71b9SJerome Forissier * - `*content_size`: The length of the plaintext in Bytes. 32811fa71b9SJerome Forissier * - `max_len`: The number of Bytes available starting from 32911fa71b9SJerome Forissier * `content`. This must be `>= *content_size`. 33011fa71b9SJerome Forissier * - `rec_type`: The desired record content type. 33111fa71b9SJerome Forissier * 33211fa71b9SJerome Forissier * Output: 3337901324dSJerome Forissier * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure. 3347901324dSJerome Forissier * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure. 33511fa71b9SJerome Forissier * 33611fa71b9SJerome Forissier * Returns: 33711fa71b9SJerome Forissier * - `0` on success. 33811fa71b9SJerome Forissier * - A negative error code if `max_len` didn't offer enough space 33911fa71b9SJerome Forissier * for the expansion. 34011fa71b9SJerome Forissier */ 341039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3427901324dSJerome Forissier static int ssl_build_inner_plaintext(unsigned char *content, 34311fa71b9SJerome Forissier size_t *content_size, 34411fa71b9SJerome Forissier size_t remaining, 3457901324dSJerome Forissier uint8_t rec_type, 3467901324dSJerome Forissier size_t pad) 34711fa71b9SJerome Forissier { 34811fa71b9SJerome Forissier size_t len = *content_size; 34911fa71b9SJerome Forissier 35011fa71b9SJerome Forissier /* Write real content type */ 351*32b31808SJens Wiklander if (remaining == 0) { 352*32b31808SJens Wiklander return -1; 353*32b31808SJens Wiklander } 35411fa71b9SJerome Forissier content[len] = rec_type; 35511fa71b9SJerome Forissier len++; 35611fa71b9SJerome Forissier remaining--; 35711fa71b9SJerome Forissier 358*32b31808SJens Wiklander if (remaining < pad) { 359*32b31808SJens Wiklander return -1; 360*32b31808SJens Wiklander } 36111fa71b9SJerome Forissier memset(content + len, 0, pad); 36211fa71b9SJerome Forissier len += pad; 36311fa71b9SJerome Forissier remaining -= pad; 36411fa71b9SJerome Forissier 36511fa71b9SJerome Forissier *content_size = len; 366*32b31808SJens Wiklander return 0; 36711fa71b9SJerome Forissier } 36811fa71b9SJerome Forissier 3697901324dSJerome Forissier /* This function parses a (D)TLSInnerPlaintext structure. 3707901324dSJerome Forissier * See ssl_build_inner_plaintext() for details. */ 371039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3727901324dSJerome Forissier static int ssl_parse_inner_plaintext(unsigned char const *content, 37311fa71b9SJerome Forissier size_t *content_size, 37411fa71b9SJerome Forissier uint8_t *rec_type) 37511fa71b9SJerome Forissier { 37611fa71b9SJerome Forissier size_t remaining = *content_size; 37711fa71b9SJerome Forissier 37811fa71b9SJerome Forissier /* Determine length of padding by skipping zeroes from the back. */ 379*32b31808SJens Wiklander do { 380*32b31808SJens Wiklander if (remaining == 0) { 381*32b31808SJens Wiklander return -1; 382*32b31808SJens Wiklander } 38311fa71b9SJerome Forissier remaining--; 38411fa71b9SJerome Forissier } while (content[remaining] == 0); 38511fa71b9SJerome Forissier 38611fa71b9SJerome Forissier *content_size = remaining; 38711fa71b9SJerome Forissier *rec_type = content[remaining]; 38811fa71b9SJerome Forissier 389*32b31808SJens Wiklander return 0; 39011fa71b9SJerome Forissier } 391*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */ 39211fa71b9SJerome Forissier 393*32b31808SJens Wiklander /* The size of the `add_data` structure depends on various 394*32b31808SJens Wiklander * factors, namely 395*32b31808SJens Wiklander * 396*32b31808SJens Wiklander * 1) CID functionality disabled 397*32b31808SJens Wiklander * 398*32b31808SJens Wiklander * additional_data = 399*32b31808SJens Wiklander * 8: seq_num + 400*32b31808SJens Wiklander * 1: type + 401*32b31808SJens Wiklander * 2: version + 402*32b31808SJens Wiklander * 2: length of inner plaintext + 403*32b31808SJens Wiklander * 404*32b31808SJens Wiklander * size = 13 bytes 405*32b31808SJens Wiklander * 406*32b31808SJens Wiklander * 2) CID functionality based on RFC 9146 enabled 407*32b31808SJens Wiklander * 408*32b31808SJens Wiklander * size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length 409*32b31808SJens Wiklander * = 23 + CID-length 410*32b31808SJens Wiklander * 411*32b31808SJens Wiklander * 3) CID functionality based on legacy CID version 412*32b31808SJens Wiklander according to draft-ietf-tls-dtls-connection-id-05 413*32b31808SJens Wiklander * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 414*32b31808SJens Wiklander * 415*32b31808SJens Wiklander * size = 13 + 1 + CID-length 416*32b31808SJens Wiklander * 417*32b31808SJens Wiklander * More information about the CID usage: 418*32b31808SJens Wiklander * 419*32b31808SJens Wiklander * Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the 420*32b31808SJens Wiklander * size of the additional data structure is calculated as: 421*32b31808SJens Wiklander * 422*32b31808SJens Wiklander * additional_data = 423*32b31808SJens Wiklander * 8: seq_num + 424*32b31808SJens Wiklander * 1: tls12_cid + 425*32b31808SJens Wiklander * 2: DTLSCipherText.version + 426*32b31808SJens Wiklander * n: cid + 427*32b31808SJens Wiklander * 1: cid_length + 428*32b31808SJens Wiklander * 2: length_of_DTLSInnerPlaintext 429*32b31808SJens Wiklander * 430*32b31808SJens Wiklander * Per RFC 9146 the size of the add_data structure is calculated as: 431*32b31808SJens Wiklander * 432*32b31808SJens Wiklander * additional_data = 433*32b31808SJens Wiklander * 8: seq_num_placeholder + 434*32b31808SJens Wiklander * 1: tls12_cid + 435*32b31808SJens Wiklander * 1: cid_length + 436*32b31808SJens Wiklander * 1: tls12_cid + 437*32b31808SJens Wiklander * 2: DTLSCiphertext.version + 438*32b31808SJens Wiklander * 2: epoch + 439*32b31808SJens Wiklander * 6: sequence_number + 440*32b31808SJens Wiklander * n: cid + 441*32b31808SJens Wiklander * 2: length_of_DTLSInnerPlaintext 442*32b31808SJens Wiklander * 443*32b31808SJens Wiklander */ 44411fa71b9SJerome Forissier static void ssl_extract_add_data_from_record(unsigned char *add_data, 44511fa71b9SJerome Forissier size_t *add_data_len, 4467901324dSJerome Forissier mbedtls_record *rec, 447*32b31808SJens Wiklander mbedtls_ssl_protocol_version 448*32b31808SJens Wiklander tls_version, 449*32b31808SJens Wiklander size_t taglen) 45011fa71b9SJerome Forissier { 451*32b31808SJens Wiklander /* Several types of ciphers have been defined for use with TLS and DTLS, 452*32b31808SJens Wiklander * and the MAC calculations for those ciphers differ slightly. Further 453*32b31808SJens Wiklander * variants were added when the CID functionality was added with RFC 9146. 454*32b31808SJens Wiklander * This implementations also considers the use of a legacy version of the 455*32b31808SJens Wiklander * CID specification published in draft-ietf-tls-dtls-connection-id-05, 456*32b31808SJens Wiklander * which is used in deployments. 457*32b31808SJens Wiklander * 458*32b31808SJens Wiklander * We will distinguish between the non-CID and the CID cases below. 459*32b31808SJens Wiklander * 460*32b31808SJens Wiklander * --- Non-CID cases --- 461*32b31808SJens Wiklander * 462*32b31808SJens Wiklander * Quoting RFC 5246 (TLS 1.2): 46311fa71b9SJerome Forissier * 46411fa71b9SJerome Forissier * additional_data = seq_num + TLSCompressed.type + 46511fa71b9SJerome Forissier * TLSCompressed.version + TLSCompressed.length; 46611fa71b9SJerome Forissier * 4677901324dSJerome Forissier * For TLS 1.3, the record sequence number is dropped from the AAD 4687901324dSJerome Forissier * and encoded within the nonce of the AEAD operation instead. 469*32b31808SJens Wiklander * Moreover, the additional data involves the length of the TLS 470*32b31808SJens Wiklander * ciphertext, not the TLS plaintext as in earlier versions. 471*32b31808SJens Wiklander * Quoting RFC 8446 (TLS 1.3): 472*32b31808SJens Wiklander * 473*32b31808SJens Wiklander * additional_data = TLSCiphertext.opaque_type || 474*32b31808SJens Wiklander * TLSCiphertext.legacy_record_version || 475*32b31808SJens Wiklander * TLSCiphertext.length 476*32b31808SJens Wiklander * 477*32b31808SJens Wiklander * We pass the tag length to this function in order to compute the 478*32b31808SJens Wiklander * ciphertext length from the inner plaintext length rec->data_len via 479*32b31808SJens Wiklander * 480*32b31808SJens Wiklander * TLSCiphertext.length = TLSInnerPlaintext.length + taglen. 481*32b31808SJens Wiklander * 482*32b31808SJens Wiklander * --- CID cases --- 483*32b31808SJens Wiklander * 484*32b31808SJens Wiklander * RFC 9146 uses a common pattern when constructing the data 485*32b31808SJens Wiklander * passed into a MAC / AEAD cipher. 486*32b31808SJens Wiklander * 487*32b31808SJens Wiklander * Data concatenation for MACs used with block ciphers with 488*32b31808SJens Wiklander * Encrypt-then-MAC Processing (with CID): 489*32b31808SJens Wiklander * 490*32b31808SJens Wiklander * data = seq_num_placeholder + 491*32b31808SJens Wiklander * tls12_cid + 492*32b31808SJens Wiklander * cid_length + 493*32b31808SJens Wiklander * tls12_cid + 494*32b31808SJens Wiklander * DTLSCiphertext.version + 495*32b31808SJens Wiklander * epoch + 496*32b31808SJens Wiklander * sequence_number + 497*32b31808SJens Wiklander * cid + 498*32b31808SJens Wiklander * DTLSCiphertext.length + 499*32b31808SJens Wiklander * IV + 500*32b31808SJens Wiklander * ENC(content + padding + padding_length) 501*32b31808SJens Wiklander * 502*32b31808SJens Wiklander * Data concatenation for MACs used with block ciphers (with CID): 503*32b31808SJens Wiklander * 504*32b31808SJens Wiklander * data = seq_num_placeholder + 505*32b31808SJens Wiklander * tls12_cid + 506*32b31808SJens Wiklander * cid_length + 507*32b31808SJens Wiklander * tls12_cid + 508*32b31808SJens Wiklander * DTLSCiphertext.version + 509*32b31808SJens Wiklander * epoch + 510*32b31808SJens Wiklander * sequence_number + 511*32b31808SJens Wiklander * cid + 512*32b31808SJens Wiklander * length_of_DTLSInnerPlaintext + 513*32b31808SJens Wiklander * DTLSInnerPlaintext.content + 514*32b31808SJens Wiklander * DTLSInnerPlaintext.real_type + 515*32b31808SJens Wiklander * DTLSInnerPlaintext.zeros 516*32b31808SJens Wiklander * 517*32b31808SJens Wiklander * AEAD ciphers use the following additional data calculation (with CIDs): 518*32b31808SJens Wiklander * 519*32b31808SJens Wiklander * additional_data = seq_num_placeholder + 520*32b31808SJens Wiklander * tls12_cid + 521*32b31808SJens Wiklander * cid_length + 522*32b31808SJens Wiklander * tls12_cid + 523*32b31808SJens Wiklander * DTLSCiphertext.version + 524*32b31808SJens Wiklander * epoch + 525*32b31808SJens Wiklander * sequence_number + 526*32b31808SJens Wiklander * cid + 527*32b31808SJens Wiklander * length_of_DTLSInnerPlaintext 528*32b31808SJens Wiklander * 529*32b31808SJens Wiklander * Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use) 530*32b31808SJens Wiklander * defines the additional data calculation as follows: 531*32b31808SJens Wiklander * 532*32b31808SJens Wiklander * additional_data = seq_num + 533*32b31808SJens Wiklander * tls12_cid + 534*32b31808SJens Wiklander * DTLSCipherText.version + 535*32b31808SJens Wiklander * cid + 536*32b31808SJens Wiklander * cid_length + 537*32b31808SJens Wiklander * length_of_DTLSInnerPlaintext 53811fa71b9SJerome Forissier */ 53911fa71b9SJerome Forissier 5407901324dSJerome Forissier unsigned char *cur = add_data; 541*32b31808SJens Wiklander size_t ad_len_field = rec->data_len; 5427901324dSJerome Forissier 543*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ 544*32b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 545*32b31808SJens Wiklander const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 546*32b31808SJens Wiklander #endif 547*32b31808SJens Wiklander 548*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 549*32b31808SJens Wiklander if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 550*32b31808SJens Wiklander /* In TLS 1.3, the AAD contains the length of the TLSCiphertext, 551*32b31808SJens Wiklander * which differs from the length of the TLSInnerPlaintext 552*32b31808SJens Wiklander * by the length of the authentication tag. */ 553*32b31808SJens Wiklander ad_len_field += taglen; 554*32b31808SJens Wiklander } else 555*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 5567901324dSJerome Forissier { 557*32b31808SJens Wiklander ((void) tls_version); 558*32b31808SJens Wiklander ((void) taglen); 5597901324dSJerome Forissier 560*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ 561*32b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 562*32b31808SJens Wiklander if (rec->cid_len != 0) { 563*32b31808SJens Wiklander // seq_num_placeholder 564*32b31808SJens Wiklander memcpy(cur, seq_num_placeholder, sizeof(seq_num_placeholder)); 565*32b31808SJens Wiklander cur += sizeof(seq_num_placeholder); 566*32b31808SJens Wiklander 567*32b31808SJens Wiklander // tls12_cid type 5687901324dSJerome Forissier *cur = rec->type; 5697901324dSJerome Forissier cur++; 5707901324dSJerome Forissier 571*32b31808SJens Wiklander // cid_length 572*32b31808SJens Wiklander *cur = rec->cid_len; 573*32b31808SJens Wiklander cur++; 574*32b31808SJens Wiklander } else 575*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 576*32b31808SJens Wiklander { 577*32b31808SJens Wiklander // epoch + sequence number 578*32b31808SJens Wiklander memcpy(cur, rec->ctr, sizeof(rec->ctr)); 579*32b31808SJens Wiklander cur += sizeof(rec->ctr); 580*32b31808SJens Wiklander } 581*32b31808SJens Wiklander } 582*32b31808SJens Wiklander 583*32b31808SJens Wiklander // type 584*32b31808SJens Wiklander *cur = rec->type; 585*32b31808SJens Wiklander cur++; 586*32b31808SJens Wiklander 587*32b31808SJens Wiklander // version 5887901324dSJerome Forissier memcpy(cur, rec->ver, sizeof(rec->ver)); 5897901324dSJerome Forissier cur += sizeof(rec->ver); 59011fa71b9SJerome Forissier 591*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ 592*32b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1 593*32b31808SJens Wiklander 594*32b31808SJens Wiklander if (rec->cid_len != 0) { 595*32b31808SJens Wiklander // CID 5967901324dSJerome Forissier memcpy(cur, rec->cid, rec->cid_len); 5977901324dSJerome Forissier cur += rec->cid_len; 5987901324dSJerome Forissier 599*32b31808SJens Wiklander // cid_length 6007901324dSJerome Forissier *cur = rec->cid_len; 6017901324dSJerome Forissier cur++; 6027901324dSJerome Forissier 603*32b31808SJens Wiklander // length of inner plaintext 604*32b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); 6057901324dSJerome Forissier cur += 2; 606*32b31808SJens Wiklander } else 607*32b31808SJens Wiklander #elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ 608*32b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0 609*32b31808SJens Wiklander 610*32b31808SJens Wiklander if (rec->cid_len != 0) { 611*32b31808SJens Wiklander // epoch + sequence number 612*32b31808SJens Wiklander memcpy(cur, rec->ctr, sizeof(rec->ctr)); 613*32b31808SJens Wiklander cur += sizeof(rec->ctr); 614*32b31808SJens Wiklander 615*32b31808SJens Wiklander // CID 616*32b31808SJens Wiklander memcpy(cur, rec->cid, rec->cid_len); 617*32b31808SJens Wiklander cur += rec->cid_len; 618*32b31808SJens Wiklander 619*32b31808SJens Wiklander // length of inner plaintext 620*32b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); 621*32b31808SJens Wiklander cur += 2; 622*32b31808SJens Wiklander } else 62311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 62411fa71b9SJerome Forissier { 625*32b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0); 6267901324dSJerome Forissier cur += 2; 62711fa71b9SJerome Forissier } 6287901324dSJerome Forissier 6297901324dSJerome Forissier *add_data_len = cur - add_data; 63011fa71b9SJerome Forissier } 63111fa71b9SJerome Forissier 6327901324dSJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 6337901324dSJerome Forissier defined(MBEDTLS_CCM_C) || \ 6347901324dSJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 635039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 6367901324dSJerome Forissier static int ssl_transform_aead_dynamic_iv_is_explicit( 6377901324dSJerome Forissier mbedtls_ssl_transform const *transform) 6387901324dSJerome Forissier { 639*32b31808SJens Wiklander return transform->ivlen != transform->fixed_ivlen; 6407901324dSJerome Forissier } 6417901324dSJerome Forissier 6427901324dSJerome Forissier /* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV ) 6437901324dSJerome Forissier * 6447901324dSJerome Forissier * Concretely, this occurs in two variants: 6457901324dSJerome Forissier * 6467901324dSJerome Forissier * a) Fixed and dynamic IV lengths add up to total IV length, giving 6477901324dSJerome Forissier * IV = fixed_iv || dynamic_iv 6487901324dSJerome Forissier * 6497901324dSJerome Forissier * This variant is used in TLS 1.2 when used with GCM or CCM. 6507901324dSJerome Forissier * 6517901324dSJerome Forissier * b) Fixed IV lengths matches total IV length, giving 6527901324dSJerome Forissier * IV = fixed_iv XOR ( 0 || dynamic_iv ) 6537901324dSJerome Forissier * 6547901324dSJerome Forissier * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly. 6557901324dSJerome Forissier * 6567901324dSJerome Forissier * See also the documentation of mbedtls_ssl_transform. 6577901324dSJerome Forissier * 6587901324dSJerome Forissier * This function has the precondition that 6597901324dSJerome Forissier * 6607901324dSJerome Forissier * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len ) 6617901324dSJerome Forissier * 6627901324dSJerome Forissier * which has to be ensured by the caller. If this precondition 6637901324dSJerome Forissier * violated, the behavior of this function is undefined. 6647901324dSJerome Forissier */ 6657901324dSJerome Forissier static void ssl_build_record_nonce(unsigned char *dst_iv, 6667901324dSJerome Forissier size_t dst_iv_len, 6677901324dSJerome Forissier unsigned char const *fixed_iv, 6687901324dSJerome Forissier size_t fixed_iv_len, 6697901324dSJerome Forissier unsigned char const *dynamic_iv, 6707901324dSJerome Forissier size_t dynamic_iv_len) 6717901324dSJerome Forissier { 6727901324dSJerome Forissier /* Start with Fixed IV || 0 */ 6737901324dSJerome Forissier memset(dst_iv, 0, dst_iv_len); 6747901324dSJerome Forissier memcpy(dst_iv, fixed_iv, fixed_iv_len); 6757901324dSJerome Forissier 6767901324dSJerome Forissier dst_iv += dst_iv_len - dynamic_iv_len; 677*32b31808SJens Wiklander mbedtls_xor(dst_iv, dst_iv, dynamic_iv, dynamic_iv_len); 6787901324dSJerome Forissier } 6797901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 6807901324dSJerome Forissier 68111fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl, 68211fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 68311fa71b9SJerome Forissier mbedtls_record *rec, 68411fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), 68511fa71b9SJerome Forissier void *p_rng) 68611fa71b9SJerome Forissier { 687*32b31808SJens Wiklander mbedtls_ssl_mode_t ssl_mode; 68811fa71b9SJerome Forissier int auth_done = 0; 68911fa71b9SJerome Forissier unsigned char *data; 690*32b31808SJens Wiklander /* For an explanation of the additional data length see 691*32b31808SJens Wiklander * the description of ssl_extract_add_data_from_record(). 692*32b31808SJens Wiklander */ 693*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 694*32b31808SJens Wiklander unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX]; 695*32b31808SJens Wiklander #else 696*32b31808SJens Wiklander unsigned char add_data[13]; 697*32b31808SJens Wiklander #endif 69811fa71b9SJerome Forissier size_t add_data_len; 69911fa71b9SJerome Forissier size_t post_avail; 70011fa71b9SJerome Forissier 70111fa71b9SJerome Forissier /* The SSL context is only used for debugging purposes! */ 70211fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 70311fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 70411fa71b9SJerome Forissier ((void) ssl); 70511fa71b9SJerome Forissier #endif 70611fa71b9SJerome Forissier 70711fa71b9SJerome Forissier /* The PRNG is used for dynamic IV generation that's used 708*32b31808SJens Wiklander * for CBC transformations in TLS 1.2. */ 7097901324dSJerome Forissier #if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ 710*32b31808SJens Wiklander defined(MBEDTLS_SSL_PROTO_TLS1_2)) 71111fa71b9SJerome Forissier ((void) f_rng); 71211fa71b9SJerome Forissier ((void) p_rng); 71311fa71b9SJerome Forissier #endif 71411fa71b9SJerome Forissier 71511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf")); 71611fa71b9SJerome Forissier 717*32b31808SJens Wiklander if (transform == NULL) { 71811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf")); 719*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 72011fa71b9SJerome Forissier } 72111fa71b9SJerome Forissier if (rec == NULL 72211fa71b9SJerome Forissier || rec->buf == NULL 72311fa71b9SJerome Forissier || rec->buf_len < rec->data_offset 72411fa71b9SJerome Forissier || rec->buf_len - rec->data_offset < rec->data_len 72511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 72611fa71b9SJerome Forissier || rec->cid_len != 0 72711fa71b9SJerome Forissier #endif 728*32b31808SJens Wiklander ) { 72911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to encrypt_buf")); 730*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 73111fa71b9SJerome Forissier } 73211fa71b9SJerome Forissier 733*32b31808SJens Wiklander ssl_mode = mbedtls_ssl_get_mode_from_transform(transform); 734*32b31808SJens Wiklander 73511fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 73611fa71b9SJerome Forissier post_avail = rec->buf_len - (rec->data_len + rec->data_offset); 73711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload", 73811fa71b9SJerome Forissier data, rec->data_len); 73911fa71b9SJerome Forissier 740*32b31808SJens Wiklander if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { 7417901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET 7427901324dSJerome Forissier " too large, maximum %" MBEDTLS_PRINTF_SIZET, 7437901324dSJerome Forissier rec->data_len, 7447901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN)); 745*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 74611fa71b9SJerome Forissier } 74711fa71b9SJerome Forissier 7487901324dSJerome Forissier /* The following two code paths implement the (D)TLSInnerPlaintext 7497901324dSJerome Forissier * structure present in TLS 1.3 and DTLS 1.2 + CID. 7507901324dSJerome Forissier * 7517901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 7527901324dSJerome Forissier * 7537901324dSJerome Forissier * Note that this changes `rec->data_len`, and hence 7547901324dSJerome Forissier * `post_avail` needs to be recalculated afterwards. 7557901324dSJerome Forissier * 7567901324dSJerome Forissier * Note also that the two code paths cannot occur simultaneously 7577901324dSJerome Forissier * since they apply to different versions of the protocol. There 7587901324dSJerome Forissier * is hence no risk of double-addition of the inner plaintext. 7597901324dSJerome Forissier */ 760*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 761*32b31808SJens Wiklander if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 7627901324dSJerome Forissier size_t padding = 7637901324dSJerome Forissier ssl_compute_padding_length(rec->data_len, 764*32b31808SJens Wiklander MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); 7657901324dSJerome Forissier if (ssl_build_inner_plaintext(data, 7667901324dSJerome Forissier &rec->data_len, 7677901324dSJerome Forissier post_avail, 7687901324dSJerome Forissier rec->type, 769*32b31808SJens Wiklander padding) != 0) { 770*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 7717901324dSJerome Forissier } 7727901324dSJerome Forissier 7737901324dSJerome Forissier rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA; 7747901324dSJerome Forissier } 775*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 7767901324dSJerome Forissier 77711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 77811fa71b9SJerome Forissier /* 77911fa71b9SJerome Forissier * Add CID information 78011fa71b9SJerome Forissier */ 78111fa71b9SJerome Forissier rec->cid_len = transform->out_cid_len; 78211fa71b9SJerome Forissier memcpy(rec->cid, transform->out_cid, transform->out_cid_len); 78311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len); 78411fa71b9SJerome Forissier 785*32b31808SJens Wiklander if (rec->cid_len != 0) { 7867901324dSJerome Forissier size_t padding = 7877901324dSJerome Forissier ssl_compute_padding_length(rec->data_len, 788*32b31808SJens Wiklander MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY); 78911fa71b9SJerome Forissier /* 79011fa71b9SJerome Forissier * Wrap plaintext into DTLSInnerPlaintext structure. 7917901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 79211fa71b9SJerome Forissier * 79311fa71b9SJerome Forissier * Note that this changes `rec->data_len`, and hence 79411fa71b9SJerome Forissier * `post_avail` needs to be recalculated afterwards. 79511fa71b9SJerome Forissier */ 7967901324dSJerome Forissier if (ssl_build_inner_plaintext(data, 79711fa71b9SJerome Forissier &rec->data_len, 79811fa71b9SJerome Forissier post_avail, 7997901324dSJerome Forissier rec->type, 800*32b31808SJens Wiklander padding) != 0) { 801*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 80211fa71b9SJerome Forissier } 80311fa71b9SJerome Forissier 80411fa71b9SJerome Forissier rec->type = MBEDTLS_SSL_MSG_CID; 80511fa71b9SJerome Forissier } 80611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 80711fa71b9SJerome Forissier 80811fa71b9SJerome Forissier post_avail = rec->buf_len - (rec->data_len + rec->data_offset); 80911fa71b9SJerome Forissier 81011fa71b9SJerome Forissier /* 81111fa71b9SJerome Forissier * Add MAC before if needed 81211fa71b9SJerome Forissier */ 813*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) 814*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM || 815*32b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC) { 816*32b31808SJens Wiklander if (post_avail < transform->maclen) { 81711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 818*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 81911fa71b9SJerome Forissier } 820*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 82111fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 822039e02dfSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 823*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 824*32b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; 825*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 826*32b31808SJens Wiklander size_t sign_mac_length = 0; 827*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 82811fa71b9SJerome Forissier 8297901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec, 830*32b31808SJens Wiklander transform->tls_version, 831*32b31808SJens Wiklander transform->taglen); 83211fa71b9SJerome Forissier 833*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 834*32b31808SJens Wiklander status = psa_mac_sign_setup(&operation, transform->psa_mac_enc, 835*32b31808SJens Wiklander transform->psa_mac_alg); 836*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 837039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 838*32b31808SJens Wiklander } 839*32b31808SJens Wiklander 840*32b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len); 841*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 842039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 843*32b31808SJens Wiklander } 844*32b31808SJens Wiklander 845*32b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len); 846*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 847*32b31808SJens Wiklander goto hmac_failed_etm_disabled; 848*32b31808SJens Wiklander } 849*32b31808SJens Wiklander 850*32b31808SJens Wiklander status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD, 851*32b31808SJens Wiklander &sign_mac_length); 852*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 853*32b31808SJens Wiklander goto hmac_failed_etm_disabled; 854*32b31808SJens Wiklander } 855*32b31808SJens Wiklander #else 856*32b31808SJens Wiklander ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data, 857*32b31808SJens Wiklander add_data_len); 858*32b31808SJens Wiklander if (ret != 0) { 859*32b31808SJens Wiklander goto hmac_failed_etm_disabled; 860*32b31808SJens Wiklander } 861*32b31808SJens Wiklander ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len); 862*32b31808SJens Wiklander if (ret != 0) { 863*32b31808SJens Wiklander goto hmac_failed_etm_disabled; 864*32b31808SJens Wiklander } 865039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac); 866*32b31808SJens Wiklander if (ret != 0) { 867039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 868*32b31808SJens Wiklander } 869039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc); 870*32b31808SJens Wiklander if (ret != 0) { 871039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 872*32b31808SJens Wiklander } 873*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 87411fa71b9SJerome Forissier 87511fa71b9SJerome Forissier memcpy(data + rec->data_len, mac, transform->maclen); 87611fa71b9SJerome Forissier #endif 87711fa71b9SJerome Forissier 87811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len, 87911fa71b9SJerome Forissier transform->maclen); 88011fa71b9SJerome Forissier 88111fa71b9SJerome Forissier rec->data_len += transform->maclen; 88211fa71b9SJerome Forissier post_avail -= transform->maclen; 88311fa71b9SJerome Forissier auth_done++; 884*32b31808SJens Wiklander 885*32b31808SJens Wiklander hmac_failed_etm_disabled: 886*32b31808SJens Wiklander mbedtls_platform_zeroize(mac, transform->maclen); 887*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 888*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 889*32b31808SJens Wiklander status = psa_mac_abort(&operation); 890*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 891*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 89211fa71b9SJerome Forissier } 893*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 894*32b31808SJens Wiklander if (ret != 0) { 895*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_hmac_xxx", ret); 896*32b31808SJens Wiklander return ret; 897*32b31808SJens Wiklander } 898*32b31808SJens Wiklander } 899*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ 90011fa71b9SJerome Forissier 90111fa71b9SJerome Forissier /* 90211fa71b9SJerome Forissier * Encrypt 90311fa71b9SJerome Forissier */ 904*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM) 905*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) { 9067901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 90711fa71b9SJerome Forissier "including %d bytes of padding", 90811fa71b9SJerome Forissier rec->data_len, 0)); 90911fa71b9SJerome Forissier 910*32b31808SJens Wiklander /* The only supported stream cipher is "NULL", 911*32b31808SJens Wiklander * so there's nothing to do here.*/ 912*32b31808SJens Wiklander } else 913*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */ 91411fa71b9SJerome Forissier 91511fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 91611fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 91711fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 918*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { 91911fa71b9SJerome Forissier unsigned char iv[12]; 9207901324dSJerome Forissier unsigned char *dynamic_iv; 9217901324dSJerome Forissier size_t dynamic_iv_len; 9227901324dSJerome Forissier int dynamic_iv_is_explicit = 9237901324dSJerome Forissier ssl_transform_aead_dynamic_iv_is_explicit(transform); 924*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 925*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 926*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 927*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 92811fa71b9SJerome Forissier 9297901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 930*32b31808SJens Wiklander if (post_avail < transform->taglen) { 93111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 932*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 93311fa71b9SJerome Forissier } 93411fa71b9SJerome Forissier 93511fa71b9SJerome Forissier /* 9367901324dSJerome Forissier * Build nonce for AEAD encryption. 9377901324dSJerome Forissier * 9387901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 9397901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 9407901324dSJerome Forissier * can be chosen freely - in particular, it need not 9417901324dSJerome Forissier * agree with the record sequence number. 9427901324dSJerome Forissier * However, since ChaChaPoly as well as all AEAD modes 9437901324dSJerome Forissier * in TLS 1.3 use the record sequence number as the 9447901324dSJerome Forissier * dynamic part of the nonce, we uniformly use the 9457901324dSJerome Forissier * record sequence number here in all cases. 94611fa71b9SJerome Forissier */ 9477901324dSJerome Forissier dynamic_iv = rec->ctr; 9487901324dSJerome Forissier dynamic_iv_len = sizeof(rec->ctr); 94911fa71b9SJerome Forissier 9507901324dSJerome Forissier ssl_build_record_nonce(iv, sizeof(iv), 9517901324dSJerome Forissier transform->iv_enc, 9527901324dSJerome Forissier transform->fixed_ivlen, 9537901324dSJerome Forissier dynamic_iv, 9547901324dSJerome Forissier dynamic_iv_len); 95511fa71b9SJerome Forissier 9567901324dSJerome Forissier /* 9577901324dSJerome Forissier * Build additional data for AEAD encryption. 9587901324dSJerome Forissier * This depends on the TLS version. 9597901324dSJerome Forissier */ 9607901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec, 961*32b31808SJens Wiklander transform->tls_version, 962*32b31808SJens Wiklander transform->taglen); 96311fa71b9SJerome Forissier 96411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)", 96511fa71b9SJerome Forissier iv, transform->ivlen); 96611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)", 9677901324dSJerome Forissier dynamic_iv, 9687901324dSJerome Forissier dynamic_iv_is_explicit ? dynamic_iv_len : 0); 96911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", 97011fa71b9SJerome Forissier add_data, add_data_len); 9717901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 97211fa71b9SJerome Forissier "including 0 bytes of padding", 97311fa71b9SJerome Forissier rec->data_len)); 97411fa71b9SJerome Forissier 97511fa71b9SJerome Forissier /* 97611fa71b9SJerome Forissier * Encrypt and authenticate 97711fa71b9SJerome Forissier */ 978*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 979*32b31808SJens Wiklander status = psa_aead_encrypt(transform->psa_key_enc, 980*32b31808SJens Wiklander transform->psa_alg, 981*32b31808SJens Wiklander iv, transform->ivlen, 982*32b31808SJens Wiklander add_data, add_data_len, 983*32b31808SJens Wiklander data, rec->data_len, 984*32b31808SJens Wiklander data, rec->buf_len - (data - rec->buf), 985*32b31808SJens Wiklander &rec->data_len); 98611fa71b9SJerome Forissier 987*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 988*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 989*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_encrypt_buf", ret); 990*32b31808SJens Wiklander return ret; 991*32b31808SJens Wiklander } 992*32b31808SJens Wiklander #else 9937901324dSJerome Forissier if ((ret = mbedtls_cipher_auth_encrypt_ext(&transform->cipher_ctx_enc, 99411fa71b9SJerome Forissier iv, transform->ivlen, 9957901324dSJerome Forissier add_data, add_data_len, 9967901324dSJerome Forissier data, rec->data_len, /* src */ 9977901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), /* dst */ 9987901324dSJerome Forissier &rec->data_len, 999*32b31808SJens Wiklander transform->taglen)) != 0) { 1000*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret); 1001*32b31808SJens Wiklander return ret; 100211fa71b9SJerome Forissier } 1003*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1004*32b31808SJens Wiklander 100511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag", 10067901324dSJerome Forissier data + rec->data_len - transform->taglen, 10077901324dSJerome Forissier transform->taglen); 10087901324dSJerome Forissier /* Account for authentication tag. */ 100911fa71b9SJerome Forissier post_avail -= transform->taglen; 10107901324dSJerome Forissier 10117901324dSJerome Forissier /* 10127901324dSJerome Forissier * Prefix record content with dynamic IV in case it is explicit. 10137901324dSJerome Forissier */ 1014*32b31808SJens Wiklander if (dynamic_iv_is_explicit != 0) { 1015*32b31808SJens Wiklander if (rec->data_offset < dynamic_iv_len) { 10167901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 1017*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 10187901324dSJerome Forissier } 10197901324dSJerome Forissier 10207901324dSJerome Forissier memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len); 10217901324dSJerome Forissier rec->data_offset -= dynamic_iv_len; 10227901324dSJerome Forissier rec->data_len += dynamic_iv_len; 10237901324dSJerome Forissier } 10247901324dSJerome Forissier 102511fa71b9SJerome Forissier auth_done++; 1026*32b31808SJens Wiklander } else 10277901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 10287901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 1029*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC || 1030*32b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { 103111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 103211fa71b9SJerome Forissier size_t padlen, i; 103311fa71b9SJerome Forissier size_t olen; 1034*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1035*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1036*32b31808SJens Wiklander size_t part_len; 1037*32b31808SJens Wiklander psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; 1038*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 103911fa71b9SJerome Forissier 104011fa71b9SJerome Forissier /* Currently we're always using minimal padding 104111fa71b9SJerome Forissier * (up to 255 bytes would be allowed). */ 104211fa71b9SJerome Forissier padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen; 1043*32b31808SJens Wiklander if (padlen == transform->ivlen) { 104411fa71b9SJerome Forissier padlen = 0; 104511fa71b9SJerome Forissier } 104611fa71b9SJerome Forissier 1047*32b31808SJens Wiklander /* Check there's enough space in the buffer for the padding. */ 1048*32b31808SJens Wiklander if (post_avail < padlen + 1) { 1049*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 1050*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 1051*32b31808SJens Wiklander } 1052*32b31808SJens Wiklander 1053*32b31808SJens Wiklander for (i = 0; i <= padlen; i++) { 105411fa71b9SJerome Forissier data[rec->data_len + i] = (unsigned char) padlen; 1055*32b31808SJens Wiklander } 105611fa71b9SJerome Forissier 105711fa71b9SJerome Forissier rec->data_len += padlen + 1; 105811fa71b9SJerome Forissier post_avail -= padlen + 1; 105911fa71b9SJerome Forissier 1060*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 106111fa71b9SJerome Forissier /* 1062*32b31808SJens Wiklander * Prepend per-record IV for block cipher in TLS v1.2 as per 106311fa71b9SJerome Forissier * Method 1 (6.2.3.2. in RFC4346 and RFC5246) 106411fa71b9SJerome Forissier */ 1065*32b31808SJens Wiklander if (f_rng == NULL) { 106611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("No PRNG provided to encrypt_record routine")); 1067*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 106811fa71b9SJerome Forissier } 106911fa71b9SJerome Forissier 1070*32b31808SJens Wiklander if (rec->data_offset < transform->ivlen) { 107111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 1072*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 107311fa71b9SJerome Forissier } 107411fa71b9SJerome Forissier 107511fa71b9SJerome Forissier /* 107611fa71b9SJerome Forissier * Generate IV 107711fa71b9SJerome Forissier */ 107811fa71b9SJerome Forissier ret = f_rng(p_rng, transform->iv_enc, transform->ivlen); 1079*32b31808SJens Wiklander if (ret != 0) { 1080*32b31808SJens Wiklander return ret; 108111fa71b9SJerome Forissier } 1082*32b31808SJens Wiklander 1083*32b31808SJens Wiklander memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen); 1084*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 108511fa71b9SJerome Forissier 10867901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 1087*32b31808SJens Wiklander "including %" 1088*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 10897901324dSJerome Forissier " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding", 109011fa71b9SJerome Forissier rec->data_len, transform->ivlen, 109111fa71b9SJerome Forissier padlen + 1)); 109211fa71b9SJerome Forissier 1093*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1094*32b31808SJens Wiklander status = psa_cipher_encrypt_setup(&cipher_op, 1095*32b31808SJens Wiklander transform->psa_key_enc, transform->psa_alg); 1096*32b31808SJens Wiklander 1097*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1098*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1099*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_encrypt_setup", ret); 1100*32b31808SJens Wiklander return ret; 1101*32b31808SJens Wiklander } 1102*32b31808SJens Wiklander 1103*32b31808SJens Wiklander status = psa_cipher_set_iv(&cipher_op, transform->iv_enc, transform->ivlen); 1104*32b31808SJens Wiklander 1105*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1106*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1107*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret); 1108*32b31808SJens Wiklander return ret; 1109*32b31808SJens Wiklander 1110*32b31808SJens Wiklander } 1111*32b31808SJens Wiklander 1112*32b31808SJens Wiklander status = psa_cipher_update(&cipher_op, 1113*32b31808SJens Wiklander data, rec->data_len, 1114*32b31808SJens Wiklander data, rec->data_len, &olen); 1115*32b31808SJens Wiklander 1116*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1117*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1118*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret); 1119*32b31808SJens Wiklander return ret; 1120*32b31808SJens Wiklander 1121*32b31808SJens Wiklander } 1122*32b31808SJens Wiklander 1123*32b31808SJens Wiklander status = psa_cipher_finish(&cipher_op, 1124*32b31808SJens Wiklander data + olen, rec->data_len - olen, 1125*32b31808SJens Wiklander &part_len); 1126*32b31808SJens Wiklander 1127*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1128*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1129*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret); 1130*32b31808SJens Wiklander return ret; 1131*32b31808SJens Wiklander 1132*32b31808SJens Wiklander } 1133*32b31808SJens Wiklander 1134*32b31808SJens Wiklander olen += part_len; 1135*32b31808SJens Wiklander #else 113611fa71b9SJerome Forissier if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_enc, 113711fa71b9SJerome Forissier transform->iv_enc, 113811fa71b9SJerome Forissier transform->ivlen, 113911fa71b9SJerome Forissier data, rec->data_len, 1140*32b31808SJens Wiklander data, &olen)) != 0) { 114111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret); 1142*32b31808SJens Wiklander return ret; 114311fa71b9SJerome Forissier } 1144*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 114511fa71b9SJerome Forissier 1146*32b31808SJens Wiklander if (rec->data_len != olen) { 114711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1148*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 114911fa71b9SJerome Forissier } 115011fa71b9SJerome Forissier 115111fa71b9SJerome Forissier data -= transform->ivlen; 115211fa71b9SJerome Forissier rec->data_offset -= transform->ivlen; 115311fa71b9SJerome Forissier rec->data_len += transform->ivlen; 115411fa71b9SJerome Forissier 115511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 1156*32b31808SJens Wiklander if (auth_done == 0) { 115711fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 1158*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1159*32b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; 1160*32b31808SJens Wiklander size_t sign_mac_length = 0; 1161*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 116211fa71b9SJerome Forissier 1163*32b31808SJens Wiklander /* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length)) 116411fa71b9SJerome Forissier */ 116511fa71b9SJerome Forissier 1166*32b31808SJens Wiklander if (post_avail < transform->maclen) { 116711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough")); 1168*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 116911fa71b9SJerome Forissier } 117011fa71b9SJerome Forissier 11717901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, 1172*32b31808SJens Wiklander rec, transform->tls_version, 1173*32b31808SJens Wiklander transform->taglen); 117411fa71b9SJerome Forissier 117511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac")); 117611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, 117711fa71b9SJerome Forissier add_data_len); 1178*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1179*32b31808SJens Wiklander status = psa_mac_sign_setup(&operation, transform->psa_mac_enc, 1180*32b31808SJens Wiklander transform->psa_mac_alg); 1181*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1182*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1183*32b31808SJens Wiklander } 1184*32b31808SJens Wiklander 1185*32b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len); 1186*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1187*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1188*32b31808SJens Wiklander } 1189*32b31808SJens Wiklander 1190*32b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len); 1191*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1192*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1193*32b31808SJens Wiklander } 1194*32b31808SJens Wiklander 1195*32b31808SJens Wiklander status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD, 1196*32b31808SJens Wiklander &sign_mac_length); 1197*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1198*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1199*32b31808SJens Wiklander } 1200*32b31808SJens Wiklander #else 120111fa71b9SJerome Forissier 1202039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data, 120311fa71b9SJerome Forissier add_data_len); 1204*32b31808SJens Wiklander if (ret != 0) { 1205039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1206*32b31808SJens Wiklander } 1207039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, 120811fa71b9SJerome Forissier data, rec->data_len); 1209*32b31808SJens Wiklander if (ret != 0) { 1210039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1211*32b31808SJens Wiklander } 1212039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac); 1213*32b31808SJens Wiklander if (ret != 0) { 1214039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1215*32b31808SJens Wiklander } 1216039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc); 1217*32b31808SJens Wiklander if (ret != 0) { 1218039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1219*32b31808SJens Wiklander } 1220*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 122111fa71b9SJerome Forissier 122211fa71b9SJerome Forissier memcpy(data + rec->data_len, mac, transform->maclen); 122311fa71b9SJerome Forissier 122411fa71b9SJerome Forissier rec->data_len += transform->maclen; 122511fa71b9SJerome Forissier post_avail -= transform->maclen; 122611fa71b9SJerome Forissier auth_done++; 1227039e02dfSJerome Forissier 1228039e02dfSJerome Forissier hmac_failed_etm_enabled: 1229039e02dfSJerome Forissier mbedtls_platform_zeroize(mac, transform->maclen); 1230*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1231*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1232*32b31808SJens Wiklander status = psa_mac_abort(&operation); 1233*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 1234*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1235*32b31808SJens Wiklander } 1236*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1237*32b31808SJens Wiklander if (ret != 0) { 1238039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "HMAC calculation failed", ret); 1239*32b31808SJens Wiklander return ret; 1240039e02dfSJerome Forissier } 124111fa71b9SJerome Forissier } 124211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 1243*32b31808SJens Wiklander } else 12447901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ 124511fa71b9SJerome Forissier { 124611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1247*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 124811fa71b9SJerome Forissier } 124911fa71b9SJerome Forissier 125011fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 1251*32b31808SJens Wiklander if (auth_done != 1) { 125211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1253*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 125411fa71b9SJerome Forissier } 125511fa71b9SJerome Forissier 125611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf")); 125711fa71b9SJerome Forissier 1258*32b31808SJens Wiklander return 0; 125911fa71b9SJerome Forissier } 126011fa71b9SJerome Forissier 126111fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl, 126211fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 126311fa71b9SJerome Forissier mbedtls_record *rec) 126411fa71b9SJerome Forissier { 1265*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_CIPHER_MODE_AEAD) 126611fa71b9SJerome Forissier size_t olen; 1267*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_CIPHER_MODE_AEAD */ 1268*32b31808SJens Wiklander mbedtls_ssl_mode_t ssl_mode; 1269*32b31808SJens Wiklander int ret; 1270*32b31808SJens Wiklander 1271*32b31808SJens Wiklander int auth_done = 0; 1272*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) 127311fa71b9SJerome Forissier size_t padlen = 0, correct = 1; 127411fa71b9SJerome Forissier #endif 127511fa71b9SJerome Forissier unsigned char *data; 1276*32b31808SJens Wiklander /* For an explanation of the additional data length see 1277*32b31808SJens Wiklander * the description of ssl_extract_add_data_from_record(). 1278*32b31808SJens Wiklander */ 1279*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 1280*32b31808SJens Wiklander unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX]; 1281*32b31808SJens Wiklander #else 1282*32b31808SJens Wiklander unsigned char add_data[13]; 1283*32b31808SJens Wiklander #endif 128411fa71b9SJerome Forissier size_t add_data_len; 128511fa71b9SJerome Forissier 128611fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 128711fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 128811fa71b9SJerome Forissier ((void) ssl); 128911fa71b9SJerome Forissier #endif 129011fa71b9SJerome Forissier 129111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf")); 129211fa71b9SJerome Forissier if (rec == NULL || 129311fa71b9SJerome Forissier rec->buf == NULL || 129411fa71b9SJerome Forissier rec->buf_len < rec->data_offset || 1295*32b31808SJens Wiklander rec->buf_len - rec->data_offset < rec->data_len) { 129611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to decrypt_buf")); 1297*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 129811fa71b9SJerome Forissier } 129911fa71b9SJerome Forissier 130011fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 1301*32b31808SJens Wiklander ssl_mode = mbedtls_ssl_get_mode_from_transform(transform); 130211fa71b9SJerome Forissier 130311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 130411fa71b9SJerome Forissier /* 130511fa71b9SJerome Forissier * Match record's CID with incoming CID. 130611fa71b9SJerome Forissier */ 130711fa71b9SJerome Forissier if (rec->cid_len != transform->in_cid_len || 1308*32b31808SJens Wiklander memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) { 1309*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_CID; 131011fa71b9SJerome Forissier } 131111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 131211fa71b9SJerome Forissier 1313*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM) 1314*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) { 1315*32b31808SJens Wiklander /* The only supported stream cipher is "NULL", 1316*32b31808SJens Wiklander * so there's nothing to do here.*/ 1317*32b31808SJens Wiklander } else 1318*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */ 131911fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 132011fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 132111fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 1322*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) { 132311fa71b9SJerome Forissier unsigned char iv[12]; 13247901324dSJerome Forissier unsigned char *dynamic_iv; 13257901324dSJerome Forissier size_t dynamic_iv_len; 1326*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1327*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1328*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 132911fa71b9SJerome Forissier 133011fa71b9SJerome Forissier /* 13317901324dSJerome Forissier * Extract dynamic part of nonce for AEAD decryption. 13327901324dSJerome Forissier * 13337901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 13347901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 13357901324dSJerome Forissier * can be chosen freely - in particular, it need not 13367901324dSJerome Forissier * agree with the record sequence number. 133711fa71b9SJerome Forissier */ 13387901324dSJerome Forissier dynamic_iv_len = sizeof(rec->ctr); 1339*32b31808SJens Wiklander if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) { 1340*32b31808SJens Wiklander if (rec->data_len < dynamic_iv_len) { 13417901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET 13427901324dSJerome Forissier " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ", 13437901324dSJerome Forissier rec->data_len, 13447901324dSJerome Forissier dynamic_iv_len)); 1345*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 134611fa71b9SJerome Forissier } 13477901324dSJerome Forissier dynamic_iv = data; 134811fa71b9SJerome Forissier 13497901324dSJerome Forissier data += dynamic_iv_len; 13507901324dSJerome Forissier rec->data_offset += dynamic_iv_len; 13517901324dSJerome Forissier rec->data_len -= dynamic_iv_len; 1352*32b31808SJens Wiklander } else { 13537901324dSJerome Forissier dynamic_iv = rec->ctr; 135411fa71b9SJerome Forissier } 135511fa71b9SJerome Forissier 13567901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 1357*32b31808SJens Wiklander if (rec->data_len < transform->taglen) { 13587901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET 13597901324dSJerome Forissier ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ", 13607901324dSJerome Forissier rec->data_len, 13617901324dSJerome Forissier transform->taglen)); 1362*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 13637901324dSJerome Forissier } 13647901324dSJerome Forissier rec->data_len -= transform->taglen; 136511fa71b9SJerome Forissier 13667901324dSJerome Forissier /* 13677901324dSJerome Forissier * Prepare nonce from dynamic and static parts. 13687901324dSJerome Forissier */ 13697901324dSJerome Forissier ssl_build_record_nonce(iv, sizeof(iv), 13707901324dSJerome Forissier transform->iv_dec, 13717901324dSJerome Forissier transform->fixed_ivlen, 13727901324dSJerome Forissier dynamic_iv, 13737901324dSJerome Forissier dynamic_iv_len); 13747901324dSJerome Forissier 13757901324dSJerome Forissier /* 13767901324dSJerome Forissier * Build additional data for AEAD encryption. 13777901324dSJerome Forissier * This depends on the TLS version. 13787901324dSJerome Forissier */ 13797901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec, 1380*32b31808SJens Wiklander transform->tls_version, 1381*32b31808SJens Wiklander transform->taglen); 138211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", 138311fa71b9SJerome Forissier add_data, add_data_len); 138411fa71b9SJerome Forissier 138511fa71b9SJerome Forissier /* Because of the check above, we know that there are 1386039e02dfSJerome Forissier * explicit_iv_len Bytes preceding data, and taglen 138711fa71b9SJerome Forissier * bytes following data + data_len. This justifies 138811fa71b9SJerome Forissier * the debug message and the invocation of 1389*32b31808SJens Wiklander * mbedtls_cipher_auth_decrypt_ext() below. */ 139011fa71b9SJerome Forissier 139111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen); 139211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len, 139311fa71b9SJerome Forissier transform->taglen); 139411fa71b9SJerome Forissier 139511fa71b9SJerome Forissier /* 139611fa71b9SJerome Forissier * Decrypt and authenticate 139711fa71b9SJerome Forissier */ 1398*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1399*32b31808SJens Wiklander status = psa_aead_decrypt(transform->psa_key_dec, 1400*32b31808SJens Wiklander transform->psa_alg, 1401*32b31808SJens Wiklander iv, transform->ivlen, 1402*32b31808SJens Wiklander add_data, add_data_len, 1403*32b31808SJens Wiklander data, rec->data_len + transform->taglen, 1404*32b31808SJens Wiklander data, rec->buf_len - (data - rec->buf), 1405*32b31808SJens Wiklander &olen); 1406*32b31808SJens Wiklander 1407*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1408*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1409*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_aead_decrypt", ret); 1410*32b31808SJens Wiklander return ret; 1411*32b31808SJens Wiklander } 1412*32b31808SJens Wiklander #else 14137901324dSJerome Forissier if ((ret = mbedtls_cipher_auth_decrypt_ext(&transform->cipher_ctx_dec, 141411fa71b9SJerome Forissier iv, transform->ivlen, 141511fa71b9SJerome Forissier add_data, add_data_len, 14167901324dSJerome Forissier data, rec->data_len + transform->taglen, /* src */ 14177901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), &olen, /* dst */ 1418*32b31808SJens Wiklander transform->taglen)) != 0) { 1419*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret); 142011fa71b9SJerome Forissier 1421*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) { 1422*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 142311fa71b9SJerome Forissier } 1424*32b31808SJens Wiklander 1425*32b31808SJens Wiklander return ret; 1426*32b31808SJens Wiklander } 1427*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1428*32b31808SJens Wiklander 142911fa71b9SJerome Forissier auth_done++; 143011fa71b9SJerome Forissier 143111fa71b9SJerome Forissier /* Double-check that AEAD decryption doesn't change content length. */ 1432*32b31808SJens Wiklander if (olen != rec->data_len) { 143311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1434*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 143511fa71b9SJerome Forissier } 1436*32b31808SJens Wiklander } else 143711fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ 14387901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 1439*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC || 1440*32b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { 144111fa71b9SJerome Forissier size_t minlen = 0; 1442*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1443*32b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1444*32b31808SJens Wiklander size_t part_len; 1445*32b31808SJens Wiklander psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; 1446*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 144711fa71b9SJerome Forissier 144811fa71b9SJerome Forissier /* 144911fa71b9SJerome Forissier * Check immediate ciphertext sanity 145011fa71b9SJerome Forissier */ 1451*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 145211fa71b9SJerome Forissier /* The ciphertext is prefixed with the CBC IV. */ 145311fa71b9SJerome Forissier minlen += transform->ivlen; 145411fa71b9SJerome Forissier #endif 145511fa71b9SJerome Forissier 145611fa71b9SJerome Forissier /* Size considerations: 145711fa71b9SJerome Forissier * 145811fa71b9SJerome Forissier * - The CBC cipher text must not be empty and hence 145911fa71b9SJerome Forissier * at least of size transform->ivlen. 146011fa71b9SJerome Forissier * 146111fa71b9SJerome Forissier * Together with the potential IV-prefix, this explains 146211fa71b9SJerome Forissier * the first of the two checks below. 146311fa71b9SJerome Forissier * 146411fa71b9SJerome Forissier * - The record must contain a MAC, either in plain or 146511fa71b9SJerome Forissier * encrypted, depending on whether Encrypt-then-MAC 146611fa71b9SJerome Forissier * is used or not. 146711fa71b9SJerome Forissier * - If it is, the message contains the IV-prefix, 146811fa71b9SJerome Forissier * the CBC ciphertext, and the MAC. 146911fa71b9SJerome Forissier * - If it is not, the padded plaintext, and hence 147011fa71b9SJerome Forissier * the CBC ciphertext, has at least length maclen + 1 147111fa71b9SJerome Forissier * because there is at least the padding length byte. 147211fa71b9SJerome Forissier * 147311fa71b9SJerome Forissier * As the CBC ciphertext is not empty, both cases give the 147411fa71b9SJerome Forissier * lower bound minlen + maclen + 1 on the record size, which 147511fa71b9SJerome Forissier * we test for in the second check below. 147611fa71b9SJerome Forissier */ 147711fa71b9SJerome Forissier if (rec->data_len < minlen + transform->ivlen || 1478*32b31808SJens Wiklander rec->data_len < minlen + transform->maclen + 1) { 14797901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET 14807901324dSJerome Forissier ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET 14817901324dSJerome Forissier "), maclen (%" MBEDTLS_PRINTF_SIZET ") " 1482*32b31808SJens Wiklander "+ 1 ) ( + expl IV )", 1483*32b31808SJens Wiklander rec->data_len, 148411fa71b9SJerome Forissier transform->ivlen, 148511fa71b9SJerome Forissier transform->maclen)); 1486*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 148711fa71b9SJerome Forissier } 148811fa71b9SJerome Forissier 148911fa71b9SJerome Forissier /* 149011fa71b9SJerome Forissier * Authenticate before decrypt if enabled 149111fa71b9SJerome Forissier */ 149211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 1493*32b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) { 1494*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1495*32b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; 1496*32b31808SJens Wiklander #else 149711fa71b9SJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; 1498*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 149911fa71b9SJerome Forissier 150011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac")); 150111fa71b9SJerome Forissier 150211fa71b9SJerome Forissier /* Update data_len in tandem with add_data. 150311fa71b9SJerome Forissier * 150411fa71b9SJerome Forissier * The subtraction is safe because of the previous check 150511fa71b9SJerome Forissier * data_len >= minlen + maclen + 1. 150611fa71b9SJerome Forissier * 150711fa71b9SJerome Forissier * Afterwards, we know that data + data_len is followed by at 150811fa71b9SJerome Forissier * least maclen Bytes, which justifies the call to 1509039e02dfSJerome Forissier * mbedtls_ct_memcmp() below. 151011fa71b9SJerome Forissier * 151111fa71b9SJerome Forissier * Further, we still know that data_len > minlen */ 151211fa71b9SJerome Forissier rec->data_len -= transform->maclen; 15137901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec, 1514*32b31808SJens Wiklander transform->tls_version, 1515*32b31808SJens Wiklander transform->taglen); 151611fa71b9SJerome Forissier 151711fa71b9SJerome Forissier /* Calculate expected MAC. */ 151811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, 151911fa71b9SJerome Forissier add_data_len); 1520*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1521*32b31808SJens Wiklander status = psa_mac_verify_setup(&operation, transform->psa_mac_dec, 1522*32b31808SJens Wiklander transform->psa_mac_alg); 1523*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1524*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1525*32b31808SJens Wiklander } 1526*32b31808SJens Wiklander 1527*32b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len); 1528*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1529*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1530*32b31808SJens Wiklander } 1531*32b31808SJens Wiklander 1532*32b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len); 1533*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1534*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1535*32b31808SJens Wiklander } 1536*32b31808SJens Wiklander 1537*32b31808SJens Wiklander /* Compare expected MAC with MAC at the end of the record. */ 1538*32b31808SJens Wiklander status = psa_mac_verify_finish(&operation, data + rec->data_len, 1539*32b31808SJens Wiklander transform->maclen); 1540*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1541*32b31808SJens Wiklander goto hmac_failed_etm_enabled; 1542*32b31808SJens Wiklander } 1543*32b31808SJens Wiklander #else 1544039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data, 154511fa71b9SJerome Forissier add_data_len); 1546*32b31808SJens Wiklander if (ret != 0) { 1547039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1548*32b31808SJens Wiklander } 1549039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, 155011fa71b9SJerome Forissier data, rec->data_len); 1551*32b31808SJens Wiklander if (ret != 0) { 1552039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1553*32b31808SJens Wiklander } 1554039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect); 1555*32b31808SJens Wiklander if (ret != 0) { 1556039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1557*32b31808SJens Wiklander } 1558039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_dec); 1559*32b31808SJens Wiklander if (ret != 0) { 1560039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1561*32b31808SJens Wiklander } 156211fa71b9SJerome Forissier 156311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message mac", data + rec->data_len, 156411fa71b9SJerome Forissier transform->maclen); 156511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, 156611fa71b9SJerome Forissier transform->maclen); 156711fa71b9SJerome Forissier 156811fa71b9SJerome Forissier /* Compare expected MAC with MAC at the end of the record. */ 1569039e02dfSJerome Forissier if (mbedtls_ct_memcmp(data + rec->data_len, mac_expect, 1570*32b31808SJens Wiklander transform->maclen) != 0) { 157111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match")); 1572039e02dfSJerome Forissier ret = MBEDTLS_ERR_SSL_INVALID_MAC; 1573039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 157411fa71b9SJerome Forissier } 1575*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 157611fa71b9SJerome Forissier auth_done++; 1577039e02dfSJerome Forissier 1578039e02dfSJerome Forissier hmac_failed_etm_enabled: 1579*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1580*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1581*32b31808SJens Wiklander status = psa_mac_abort(&operation); 1582*32b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) { 1583*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1584*32b31808SJens Wiklander } 1585*32b31808SJens Wiklander #else 1586039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_expect, transform->maclen); 1587*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1588*32b31808SJens Wiklander if (ret != 0) { 1589*32b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_INVALID_MAC) { 1590039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_hmac_xxx", ret); 1591*32b31808SJens Wiklander } 1592*32b31808SJens Wiklander return ret; 1593039e02dfSJerome Forissier } 159411fa71b9SJerome Forissier } 159511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 159611fa71b9SJerome Forissier 159711fa71b9SJerome Forissier /* 159811fa71b9SJerome Forissier * Check length sanity 159911fa71b9SJerome Forissier */ 160011fa71b9SJerome Forissier 160111fa71b9SJerome Forissier /* We know from above that data_len > minlen >= 0, 160211fa71b9SJerome Forissier * so the following check in particular implies that 160311fa71b9SJerome Forissier * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */ 1604*32b31808SJens Wiklander if (rec->data_len % transform->ivlen != 0) { 16057901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET 16067901324dSJerome Forissier ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0", 160711fa71b9SJerome Forissier rec->data_len, transform->ivlen)); 1608*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 160911fa71b9SJerome Forissier } 161011fa71b9SJerome Forissier 1611*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 161211fa71b9SJerome Forissier /* 1613*32b31808SJens Wiklander * Initialize for prepended IV for block cipher in TLS v1.2 161411fa71b9SJerome Forissier */ 161511fa71b9SJerome Forissier /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */ 161611fa71b9SJerome Forissier memcpy(transform->iv_dec, data, transform->ivlen); 161711fa71b9SJerome Forissier 161811fa71b9SJerome Forissier data += transform->ivlen; 161911fa71b9SJerome Forissier rec->data_offset += transform->ivlen; 162011fa71b9SJerome Forissier rec->data_len -= transform->ivlen; 1621*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 162211fa71b9SJerome Forissier 162311fa71b9SJerome Forissier /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */ 162411fa71b9SJerome Forissier 1625*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1626*32b31808SJens Wiklander status = psa_cipher_decrypt_setup(&cipher_op, 1627*32b31808SJens Wiklander transform->psa_key_dec, transform->psa_alg); 1628*32b31808SJens Wiklander 1629*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1630*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1631*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_decrypt_setup", ret); 1632*32b31808SJens Wiklander return ret; 1633*32b31808SJens Wiklander } 1634*32b31808SJens Wiklander 1635*32b31808SJens Wiklander status = psa_cipher_set_iv(&cipher_op, transform->iv_dec, transform->ivlen); 1636*32b31808SJens Wiklander 1637*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1638*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1639*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret); 1640*32b31808SJens Wiklander return ret; 1641*32b31808SJens Wiklander } 1642*32b31808SJens Wiklander 1643*32b31808SJens Wiklander status = psa_cipher_update(&cipher_op, 1644*32b31808SJens Wiklander data, rec->data_len, 1645*32b31808SJens Wiklander data, rec->data_len, &olen); 1646*32b31808SJens Wiklander 1647*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1648*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1649*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret); 1650*32b31808SJens Wiklander return ret; 1651*32b31808SJens Wiklander } 1652*32b31808SJens Wiklander 1653*32b31808SJens Wiklander status = psa_cipher_finish(&cipher_op, 1654*32b31808SJens Wiklander data + olen, rec->data_len - olen, 1655*32b31808SJens Wiklander &part_len); 1656*32b31808SJens Wiklander 1657*32b31808SJens Wiklander if (status != PSA_SUCCESS) { 1658*32b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status); 1659*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret); 1660*32b31808SJens Wiklander return ret; 1661*32b31808SJens Wiklander } 1662*32b31808SJens Wiklander 1663*32b31808SJens Wiklander olen += part_len; 1664*32b31808SJens Wiklander #else 1665*32b31808SJens Wiklander 166611fa71b9SJerome Forissier if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec, 166711fa71b9SJerome Forissier transform->iv_dec, transform->ivlen, 1668*32b31808SJens Wiklander data, rec->data_len, data, &olen)) != 0) { 166911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret); 1670*32b31808SJens Wiklander return ret; 167111fa71b9SJerome Forissier } 1672*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 167311fa71b9SJerome Forissier 167411fa71b9SJerome Forissier /* Double-check that length hasn't changed during decryption. */ 1675*32b31808SJens Wiklander if (rec->data_len != olen) { 167611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1677*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 167811fa71b9SJerome Forissier } 167911fa71b9SJerome Forissier 168011fa71b9SJerome Forissier /* Safe since data_len >= minlen + maclen + 1, so after having 168111fa71b9SJerome Forissier * subtracted at most minlen and maclen up to this point, 168211fa71b9SJerome Forissier * data_len > 0 (because of data_len % ivlen == 0, it's actually 168311fa71b9SJerome Forissier * >= ivlen ). */ 168411fa71b9SJerome Forissier padlen = data[rec->data_len - 1]; 168511fa71b9SJerome Forissier 1686*32b31808SJens Wiklander if (auth_done == 1) { 1687039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge( 16887901324dSJerome Forissier rec->data_len, 16897901324dSJerome Forissier padlen + 1); 16907901324dSJerome Forissier correct &= mask; 16917901324dSJerome Forissier padlen &= mask; 1692*32b31808SJens Wiklander } else { 169311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 1694*32b31808SJens Wiklander if (rec->data_len < transform->maclen + padlen + 1) { 16957901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET 16967901324dSJerome Forissier ") < maclen (%" MBEDTLS_PRINTF_SIZET 16977901324dSJerome Forissier ") + padlen (%" MBEDTLS_PRINTF_SIZET ")", 169811fa71b9SJerome Forissier rec->data_len, 169911fa71b9SJerome Forissier transform->maclen, 170011fa71b9SJerome Forissier padlen + 1)); 170111fa71b9SJerome Forissier } 170211fa71b9SJerome Forissier #endif 170311fa71b9SJerome Forissier 1704039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge( 17057901324dSJerome Forissier rec->data_len, 17067901324dSJerome Forissier transform->maclen + padlen + 1); 17077901324dSJerome Forissier correct &= mask; 17087901324dSJerome Forissier padlen &= mask; 170911fa71b9SJerome Forissier } 171011fa71b9SJerome Forissier 171111fa71b9SJerome Forissier padlen++; 171211fa71b9SJerome Forissier 171311fa71b9SJerome Forissier /* Regardless of the validity of the padding, 171411fa71b9SJerome Forissier * we have data_len >= padlen here. */ 171511fa71b9SJerome Forissier 1716*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 171711fa71b9SJerome Forissier /* The padding check involves a series of up to 256 171811fa71b9SJerome Forissier * consecutive memory reads at the end of the record 171911fa71b9SJerome Forissier * plaintext buffer. In order to hide the length and 172011fa71b9SJerome Forissier * validity of the padding, always perform exactly 172111fa71b9SJerome Forissier * `min(256,plaintext_len)` reads (but take into account 172211fa71b9SJerome Forissier * only the last `padlen` bytes for the padding check). */ 172311fa71b9SJerome Forissier size_t pad_count = 0; 172411fa71b9SJerome Forissier volatile unsigned char * const check = data; 172511fa71b9SJerome Forissier 172611fa71b9SJerome Forissier /* Index of first padding byte; it has been ensured above 172711fa71b9SJerome Forissier * that the subtraction is safe. */ 172811fa71b9SJerome Forissier size_t const padding_idx = rec->data_len - padlen; 172911fa71b9SJerome Forissier size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256; 173011fa71b9SJerome Forissier size_t const start_idx = rec->data_len - num_checks; 173111fa71b9SJerome Forissier size_t idx; 173211fa71b9SJerome Forissier 1733*32b31808SJens Wiklander for (idx = start_idx; idx < rec->data_len; idx++) { 17347901324dSJerome Forissier /* pad_count += (idx >= padding_idx) && 17357901324dSJerome Forissier * (check[idx] == padlen - 1); 17367901324dSJerome Forissier */ 1737039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge(idx, padding_idx); 1738039e02dfSJerome Forissier const size_t equal = mbedtls_ct_size_bool_eq(check[idx], 17397901324dSJerome Forissier padlen - 1); 17407901324dSJerome Forissier pad_count += mask & equal; 174111fa71b9SJerome Forissier } 1742039e02dfSJerome Forissier correct &= mbedtls_ct_size_bool_eq(pad_count, padlen); 174311fa71b9SJerome Forissier 174411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 1745*32b31808SJens Wiklander if (padlen > 0 && correct == 0) { 174611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected")); 1747*32b31808SJens Wiklander } 174811fa71b9SJerome Forissier #endif 1749039e02dfSJerome Forissier padlen &= mbedtls_ct_size_mask(correct); 1750*32b31808SJens Wiklander 1751*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 175211fa71b9SJerome Forissier 175311fa71b9SJerome Forissier /* If the padding was found to be invalid, padlen == 0 175411fa71b9SJerome Forissier * and the subtraction is safe. If the padding was found valid, 175511fa71b9SJerome Forissier * padlen hasn't been changed and the previous assertion 175611fa71b9SJerome Forissier * data_len >= padlen still holds. */ 175711fa71b9SJerome Forissier rec->data_len -= padlen; 1758*32b31808SJens Wiklander } else 17597901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ 176011fa71b9SJerome Forissier { 176111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1762*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 176311fa71b9SJerome Forissier } 176411fa71b9SJerome Forissier 176511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 176611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption", 176711fa71b9SJerome Forissier data, rec->data_len); 176811fa71b9SJerome Forissier #endif 176911fa71b9SJerome Forissier 177011fa71b9SJerome Forissier /* 177111fa71b9SJerome Forissier * Authenticate if not done yet. 177211fa71b9SJerome Forissier * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). 177311fa71b9SJerome Forissier */ 1774*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) 1775*32b31808SJens Wiklander if (auth_done == 0) { 1776039e02dfSJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 }; 1777039e02dfSJerome Forissier unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 }; 177811fa71b9SJerome Forissier 177911fa71b9SJerome Forissier /* If the initial value of padlen was such that 178011fa71b9SJerome Forissier * data_len < maclen + padlen + 1, then padlen 178111fa71b9SJerome Forissier * got reset to 1, and the initial check 178211fa71b9SJerome Forissier * data_len >= minlen + maclen + 1 178311fa71b9SJerome Forissier * guarantees that at this point we still 178411fa71b9SJerome Forissier * have at least data_len >= maclen. 178511fa71b9SJerome Forissier * 178611fa71b9SJerome Forissier * If the initial value of padlen was such that 178711fa71b9SJerome Forissier * data_len >= maclen + padlen + 1, then we have 178811fa71b9SJerome Forissier * subtracted either padlen + 1 (if the padding was correct) 178911fa71b9SJerome Forissier * or 0 (if the padding was incorrect) since then, 179011fa71b9SJerome Forissier * hence data_len >= maclen in any case. 179111fa71b9SJerome Forissier */ 179211fa71b9SJerome Forissier rec->data_len -= transform->maclen; 17937901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec, 1794*32b31808SJens Wiklander transform->tls_version, 1795*32b31808SJens Wiklander transform->taglen); 179611fa71b9SJerome Forissier 1797*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 179811fa71b9SJerome Forissier /* 179911fa71b9SJerome Forissier * The next two sizes are the minimum and maximum values of 18007901324dSJerome Forissier * data_len over all padlen values. 180111fa71b9SJerome Forissier * 180211fa71b9SJerome Forissier * They're independent of padlen, since we previously did 180311fa71b9SJerome Forissier * data_len -= padlen. 180411fa71b9SJerome Forissier * 180511fa71b9SJerome Forissier * Note that max_len + maclen is never more than the buffer 180611fa71b9SJerome Forissier * length, as we previously did in_msglen -= maclen too. 180711fa71b9SJerome Forissier */ 180811fa71b9SJerome Forissier const size_t max_len = rec->data_len + padlen; 180911fa71b9SJerome Forissier const size_t min_len = (max_len > 256) ? max_len - 256 : 0; 181011fa71b9SJerome Forissier 1811*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 1812*32b31808SJens Wiklander ret = mbedtls_ct_hmac(transform->psa_mac_dec, 1813*32b31808SJens Wiklander transform->psa_mac_alg, 1814*32b31808SJens Wiklander add_data, add_data_len, 1815*32b31808SJens Wiklander data, rec->data_len, min_len, max_len, 1816*32b31808SJens Wiklander mac_expect); 1817*32b31808SJens Wiklander #else 1818039e02dfSJerome Forissier ret = mbedtls_ct_hmac(&transform->md_ctx_dec, 18197901324dSJerome Forissier add_data, add_data_len, 18207901324dSJerome Forissier data, rec->data_len, min_len, max_len, 18217901324dSJerome Forissier mac_expect); 1822*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 1823*32b31808SJens Wiklander if (ret != 0) { 1824039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ct_hmac", ret); 1825039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 182611fa71b9SJerome Forissier } 182711fa71b9SJerome Forissier 1828039e02dfSJerome Forissier mbedtls_ct_memcpy_offset(mac_peer, data, 18297901324dSJerome Forissier rec->data_len, 18307901324dSJerome Forissier min_len, max_len, 18317901324dSJerome Forissier transform->maclen); 1832*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 183311fa71b9SJerome Forissier 183411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 183511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen); 18367901324dSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message mac", mac_peer, transform->maclen); 183711fa71b9SJerome Forissier #endif 183811fa71b9SJerome Forissier 1839039e02dfSJerome Forissier if (mbedtls_ct_memcmp(mac_peer, mac_expect, 1840*32b31808SJens Wiklander transform->maclen) != 0) { 184111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 184211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match")); 184311fa71b9SJerome Forissier #endif 184411fa71b9SJerome Forissier correct = 0; 184511fa71b9SJerome Forissier } 184611fa71b9SJerome Forissier auth_done++; 1847039e02dfSJerome Forissier 1848039e02dfSJerome Forissier hmac_failed_etm_disabled: 1849039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_peer, transform->maclen); 1850039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_expect, transform->maclen); 1851*32b31808SJens Wiklander if (ret != 0) { 1852*32b31808SJens Wiklander return ret; 1853*32b31808SJens Wiklander } 185411fa71b9SJerome Forissier } 185511fa71b9SJerome Forissier 185611fa71b9SJerome Forissier /* 185711fa71b9SJerome Forissier * Finally check the correct flag 185811fa71b9SJerome Forissier */ 1859*32b31808SJens Wiklander if (correct == 0) { 1860*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 1861*32b31808SJens Wiklander } 1862*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */ 186311fa71b9SJerome Forissier 186411fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 1865*32b31808SJens Wiklander if (auth_done != 1) { 186611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1867*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 186811fa71b9SJerome Forissier } 186911fa71b9SJerome Forissier 1870*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 1871*32b31808SJens Wiklander if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 18727901324dSJerome Forissier /* Remove inner padding and infer true content type. */ 18737901324dSJerome Forissier ret = ssl_parse_inner_plaintext(data, &rec->data_len, 18747901324dSJerome Forissier &rec->type); 18757901324dSJerome Forissier 1876*32b31808SJens Wiklander if (ret != 0) { 1877*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 18787901324dSJerome Forissier } 1879*32b31808SJens Wiklander } 1880*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 18817901324dSJerome Forissier 188211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 1883*32b31808SJens Wiklander if (rec->cid_len != 0) { 18847901324dSJerome Forissier ret = ssl_parse_inner_plaintext(data, &rec->data_len, 188511fa71b9SJerome Forissier &rec->type); 1886*32b31808SJens Wiklander if (ret != 0) { 1887*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 1888*32b31808SJens Wiklander } 188911fa71b9SJerome Forissier } 189011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 189111fa71b9SJerome Forissier 189211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf")); 189311fa71b9SJerome Forissier 1894*32b31808SJens Wiklander return 0; 189511fa71b9SJerome Forissier } 189611fa71b9SJerome Forissier 189711fa71b9SJerome Forissier #undef MAC_NONE 189811fa71b9SJerome Forissier #undef MAC_PLAINTEXT 189911fa71b9SJerome Forissier #undef MAC_CIPHERTEXT 190011fa71b9SJerome Forissier 190111fa71b9SJerome Forissier /* 190211fa71b9SJerome Forissier * Fill the input message buffer by appending data to it. 190311fa71b9SJerome Forissier * The amount of data already fetched is in ssl->in_left. 190411fa71b9SJerome Forissier * 190511fa71b9SJerome Forissier * If we return 0, is it guaranteed that (at least) nb_want bytes are 190611fa71b9SJerome Forissier * available (from this read and/or a previous one). Otherwise, an error code 190711fa71b9SJerome Forissier * is returned (possibly EOF or WANT_READ). 190811fa71b9SJerome Forissier * 190911fa71b9SJerome Forissier * With stream transport (TLS) on success ssl->in_left == nb_want, but 191011fa71b9SJerome Forissier * with datagram transport (DTLS) on success ssl->in_left >= nb_want, 191111fa71b9SJerome Forissier * since we always read a whole datagram at once. 191211fa71b9SJerome Forissier * 191311fa71b9SJerome Forissier * For DTLS, it is up to the caller to set ssl->next_record_offset when 191411fa71b9SJerome Forissier * they're done reading a record. 191511fa71b9SJerome Forissier */ 191611fa71b9SJerome Forissier int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want) 191711fa71b9SJerome Forissier { 191811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 191911fa71b9SJerome Forissier size_t len; 192011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 192111fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 192211fa71b9SJerome Forissier #else 192311fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 192411fa71b9SJerome Forissier #endif 192511fa71b9SJerome Forissier 192611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input")); 192711fa71b9SJerome Forissier 1928*32b31808SJens Wiklander if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) { 1929*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() ")); 1930*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 193111fa71b9SJerome Forissier } 193211fa71b9SJerome Forissier 1933*32b31808SJens Wiklander if (nb_want > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) { 193411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits")); 1935*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 193611fa71b9SJerome Forissier } 193711fa71b9SJerome Forissier 193811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 1939*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 194011fa71b9SJerome Forissier uint32_t timeout; 194111fa71b9SJerome Forissier 194211fa71b9SJerome Forissier /* 194311fa71b9SJerome Forissier * The point is, we need to always read a full datagram at once, so we 194411fa71b9SJerome Forissier * sometimes read more then requested, and handle the additional data. 194511fa71b9SJerome Forissier * It could be the rest of the current record (while fetching the 194611fa71b9SJerome Forissier * header) and/or some other records in the same datagram. 194711fa71b9SJerome Forissier */ 194811fa71b9SJerome Forissier 194911fa71b9SJerome Forissier /* 195011fa71b9SJerome Forissier * Move to the next record in the already read datagram if applicable 195111fa71b9SJerome Forissier */ 1952*32b31808SJens Wiklander if (ssl->next_record_offset != 0) { 1953*32b31808SJens Wiklander if (ssl->in_left < ssl->next_record_offset) { 195411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1955*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 195611fa71b9SJerome Forissier } 195711fa71b9SJerome Forissier 195811fa71b9SJerome Forissier ssl->in_left -= ssl->next_record_offset; 195911fa71b9SJerome Forissier 1960*32b31808SJens Wiklander if (ssl->in_left != 0) { 19617901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("next record in same datagram, offset: %" 19627901324dSJerome Forissier MBEDTLS_PRINTF_SIZET, 196311fa71b9SJerome Forissier ssl->next_record_offset)); 196411fa71b9SJerome Forissier memmove(ssl->in_hdr, 196511fa71b9SJerome Forissier ssl->in_hdr + ssl->next_record_offset, 196611fa71b9SJerome Forissier ssl->in_left); 196711fa71b9SJerome Forissier } 196811fa71b9SJerome Forissier 196911fa71b9SJerome Forissier ssl->next_record_offset = 0; 197011fa71b9SJerome Forissier } 197111fa71b9SJerome Forissier 19727901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET 19737901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 197411fa71b9SJerome Forissier ssl->in_left, nb_want)); 197511fa71b9SJerome Forissier 197611fa71b9SJerome Forissier /* 197711fa71b9SJerome Forissier * Done if we already have enough data. 197811fa71b9SJerome Forissier */ 1979*32b31808SJens Wiklander if (nb_want <= ssl->in_left) { 198011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input")); 1981*32b31808SJens Wiklander return 0; 198211fa71b9SJerome Forissier } 198311fa71b9SJerome Forissier 198411fa71b9SJerome Forissier /* 198511fa71b9SJerome Forissier * A record can't be split across datagrams. If we need to read but 198611fa71b9SJerome Forissier * are not at the beginning of a new record, the caller did something 198711fa71b9SJerome Forissier * wrong. 198811fa71b9SJerome Forissier */ 1989*32b31808SJens Wiklander if (ssl->in_left != 0) { 199011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1991*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 199211fa71b9SJerome Forissier } 199311fa71b9SJerome Forissier 199411fa71b9SJerome Forissier /* 199511fa71b9SJerome Forissier * Don't even try to read if time's out already. 199611fa71b9SJerome Forissier * This avoids by-passing the timer when repeatedly receiving messages 199711fa71b9SJerome Forissier * that will end up being dropped. 199811fa71b9SJerome Forissier */ 1999*32b31808SJens Wiklander if (mbedtls_ssl_check_timer(ssl) != 0) { 200011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired")); 200111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 2002*32b31808SJens Wiklander } else { 200311fa71b9SJerome Forissier len = in_buf_len - (ssl->in_hdr - ssl->in_buf); 200411fa71b9SJerome Forissier 2005*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0) { 200611fa71b9SJerome Forissier timeout = ssl->handshake->retransmit_timeout; 2007*32b31808SJens Wiklander } else { 200811fa71b9SJerome Forissier timeout = ssl->conf->read_timeout; 2009*32b31808SJens Wiklander } 201011fa71b9SJerome Forissier 20117901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms", (unsigned long) timeout)); 201211fa71b9SJerome Forissier 2013*32b31808SJens Wiklander if (ssl->f_recv_timeout != NULL) { 201411fa71b9SJerome Forissier ret = ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len, 201511fa71b9SJerome Forissier timeout); 2016*32b31808SJens Wiklander } else { 201711fa71b9SJerome Forissier ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len); 2018*32b31808SJens Wiklander } 201911fa71b9SJerome Forissier 202011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret); 202111fa71b9SJerome Forissier 2022*32b31808SJens Wiklander if (ret == 0) { 2023*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONN_EOF; 2024*32b31808SJens Wiklander } 202511fa71b9SJerome Forissier } 202611fa71b9SJerome Forissier 2027*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_TIMEOUT) { 202811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("timeout")); 202911fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0); 203011fa71b9SJerome Forissier 2031*32b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { 2032*32b31808SJens Wiklander if (ssl_double_retransmit_timeout(ssl) != 0) { 203311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout")); 2034*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_TIMEOUT; 203511fa71b9SJerome Forissier } 203611fa71b9SJerome Forissier 2037*32b31808SJens Wiklander if ((ret = mbedtls_ssl_resend(ssl)) != 0) { 203811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret); 2039*32b31808SJens Wiklander return ret; 204011fa71b9SJerome Forissier } 204111fa71b9SJerome Forissier 2042*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ; 204311fa71b9SJerome Forissier } 204411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 204511fa71b9SJerome Forissier else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 2046*32b31808SJens Wiklander ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { 2047*32b31808SJens Wiklander if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) { 204811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request", 204911fa71b9SJerome Forissier ret); 2050*32b31808SJens Wiklander return ret; 205111fa71b9SJerome Forissier } 205211fa71b9SJerome Forissier 2053*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ; 205411fa71b9SJerome Forissier } 205511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 205611fa71b9SJerome Forissier } 205711fa71b9SJerome Forissier 2058*32b31808SJens Wiklander if (ret < 0) { 2059*32b31808SJens Wiklander return ret; 2060*32b31808SJens Wiklander } 206111fa71b9SJerome Forissier 206211fa71b9SJerome Forissier ssl->in_left = ret; 2063*32b31808SJens Wiklander } else 206411fa71b9SJerome Forissier #endif 206511fa71b9SJerome Forissier { 20667901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET 20677901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 206811fa71b9SJerome Forissier ssl->in_left, nb_want)); 206911fa71b9SJerome Forissier 2070*32b31808SJens Wiklander while (ssl->in_left < nb_want) { 207111fa71b9SJerome Forissier len = nb_want - ssl->in_left; 207211fa71b9SJerome Forissier 2073*32b31808SJens Wiklander if (mbedtls_ssl_check_timer(ssl) != 0) { 207411fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 2075*32b31808SJens Wiklander } else { 2076*32b31808SJens Wiklander if (ssl->f_recv_timeout != NULL) { 207711fa71b9SJerome Forissier ret = ssl->f_recv_timeout(ssl->p_bio, 207811fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len, 207911fa71b9SJerome Forissier ssl->conf->read_timeout); 2080*32b31808SJens Wiklander } else { 208111fa71b9SJerome Forissier ret = ssl->f_recv(ssl->p_bio, 208211fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len); 208311fa71b9SJerome Forissier } 208411fa71b9SJerome Forissier } 208511fa71b9SJerome Forissier 20867901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET 20877901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 208811fa71b9SJerome Forissier ssl->in_left, nb_want)); 208911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret); 209011fa71b9SJerome Forissier 2091*32b31808SJens Wiklander if (ret == 0) { 2092*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONN_EOF; 2093*32b31808SJens Wiklander } 209411fa71b9SJerome Forissier 2095*32b31808SJens Wiklander if (ret < 0) { 2096*32b31808SJens Wiklander return ret; 2097*32b31808SJens Wiklander } 209811fa71b9SJerome Forissier 2099*32b31808SJens Wiklander if ((size_t) ret > len) { 210011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, 2101*32b31808SJens Wiklander ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET 2102*32b31808SJens Wiklander " were requested", 21037901324dSJerome Forissier ret, len)); 2104*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 210511fa71b9SJerome Forissier } 210611fa71b9SJerome Forissier 210711fa71b9SJerome Forissier ssl->in_left += ret; 210811fa71b9SJerome Forissier } 210911fa71b9SJerome Forissier } 211011fa71b9SJerome Forissier 211111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input")); 211211fa71b9SJerome Forissier 2113*32b31808SJens Wiklander return 0; 211411fa71b9SJerome Forissier } 211511fa71b9SJerome Forissier 211611fa71b9SJerome Forissier /* 211711fa71b9SJerome Forissier * Flush any data not yet written 211811fa71b9SJerome Forissier */ 211911fa71b9SJerome Forissier int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl) 212011fa71b9SJerome Forissier { 212111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 212211fa71b9SJerome Forissier unsigned char *buf; 212311fa71b9SJerome Forissier 212411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output")); 212511fa71b9SJerome Forissier 2126*32b31808SJens Wiklander if (ssl->f_send == NULL) { 2127*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() ")); 2128*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 212911fa71b9SJerome Forissier } 213011fa71b9SJerome Forissier 213111fa71b9SJerome Forissier /* Avoid incrementing counter if data is flushed */ 2132*32b31808SJens Wiklander if (ssl->out_left == 0) { 213311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output")); 2134*32b31808SJens Wiklander return 0; 213511fa71b9SJerome Forissier } 213611fa71b9SJerome Forissier 2137*32b31808SJens Wiklander while (ssl->out_left > 0) { 21387901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("message length: %" MBEDTLS_PRINTF_SIZET 21397901324dSJerome Forissier ", out_left: %" MBEDTLS_PRINTF_SIZET, 214011fa71b9SJerome Forissier mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left)); 214111fa71b9SJerome Forissier 214211fa71b9SJerome Forissier buf = ssl->out_hdr - ssl->out_left; 214311fa71b9SJerome Forissier ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left); 214411fa71b9SJerome Forissier 214511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret); 214611fa71b9SJerome Forissier 2147*32b31808SJens Wiklander if (ret <= 0) { 2148*32b31808SJens Wiklander return ret; 2149*32b31808SJens Wiklander } 215011fa71b9SJerome Forissier 2151*32b31808SJens Wiklander if ((size_t) ret > ssl->out_left) { 215211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, 2153*32b31808SJens Wiklander ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET 2154*32b31808SJens Wiklander " bytes were sent", 21557901324dSJerome Forissier ret, ssl->out_left)); 2156*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 215711fa71b9SJerome Forissier } 215811fa71b9SJerome Forissier 215911fa71b9SJerome Forissier ssl->out_left -= ret; 216011fa71b9SJerome Forissier } 216111fa71b9SJerome Forissier 216211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 2163*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 216411fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 2165*32b31808SJens Wiklander } else 216611fa71b9SJerome Forissier #endif 216711fa71b9SJerome Forissier { 216811fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 216911fa71b9SJerome Forissier } 217011fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); 217111fa71b9SJerome Forissier 217211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output")); 217311fa71b9SJerome Forissier 2174*32b31808SJens Wiklander return 0; 217511fa71b9SJerome Forissier } 217611fa71b9SJerome Forissier 217711fa71b9SJerome Forissier /* 217811fa71b9SJerome Forissier * Functions to handle the DTLS retransmission state machine 217911fa71b9SJerome Forissier */ 218011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 218111fa71b9SJerome Forissier /* 218211fa71b9SJerome Forissier * Append current handshake message to current outgoing flight 218311fa71b9SJerome Forissier */ 2184039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 218511fa71b9SJerome Forissier static int ssl_flight_append(mbedtls_ssl_context *ssl) 218611fa71b9SJerome Forissier { 218711fa71b9SJerome Forissier mbedtls_ssl_flight_item *msg; 218811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append")); 218911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight", 219011fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen); 219111fa71b9SJerome Forissier 219211fa71b9SJerome Forissier /* Allocate space for current message */ 2193*32b31808SJens Wiklander if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) { 21947901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 219511fa71b9SJerome Forissier sizeof(mbedtls_ssl_flight_item))); 2196*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED; 219711fa71b9SJerome Forissier } 219811fa71b9SJerome Forissier 2199*32b31808SJens Wiklander if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) { 22007901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 22017901324dSJerome Forissier ssl->out_msglen)); 220211fa71b9SJerome Forissier mbedtls_free(msg); 2203*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED; 220411fa71b9SJerome Forissier } 220511fa71b9SJerome Forissier 220611fa71b9SJerome Forissier /* Copy current handshake message with headers */ 220711fa71b9SJerome Forissier memcpy(msg->p, ssl->out_msg, ssl->out_msglen); 220811fa71b9SJerome Forissier msg->len = ssl->out_msglen; 220911fa71b9SJerome Forissier msg->type = ssl->out_msgtype; 221011fa71b9SJerome Forissier msg->next = NULL; 221111fa71b9SJerome Forissier 221211fa71b9SJerome Forissier /* Append to the current flight */ 2213*32b31808SJens Wiklander if (ssl->handshake->flight == NULL) { 221411fa71b9SJerome Forissier ssl->handshake->flight = msg; 2215*32b31808SJens Wiklander } else { 221611fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = ssl->handshake->flight; 2217*32b31808SJens Wiklander while (cur->next != NULL) { 221811fa71b9SJerome Forissier cur = cur->next; 2219*32b31808SJens Wiklander } 222011fa71b9SJerome Forissier cur->next = msg; 222111fa71b9SJerome Forissier } 222211fa71b9SJerome Forissier 222311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append")); 2224*32b31808SJens Wiklander return 0; 222511fa71b9SJerome Forissier } 222611fa71b9SJerome Forissier 222711fa71b9SJerome Forissier /* 222811fa71b9SJerome Forissier * Free the current flight of handshake messages 222911fa71b9SJerome Forissier */ 223011fa71b9SJerome Forissier void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight) 223111fa71b9SJerome Forissier { 223211fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = flight; 223311fa71b9SJerome Forissier mbedtls_ssl_flight_item *next; 223411fa71b9SJerome Forissier 2235*32b31808SJens Wiklander while (cur != NULL) { 223611fa71b9SJerome Forissier next = cur->next; 223711fa71b9SJerome Forissier 223811fa71b9SJerome Forissier mbedtls_free(cur->p); 223911fa71b9SJerome Forissier mbedtls_free(cur); 224011fa71b9SJerome Forissier 224111fa71b9SJerome Forissier cur = next; 224211fa71b9SJerome Forissier } 224311fa71b9SJerome Forissier } 224411fa71b9SJerome Forissier 224511fa71b9SJerome Forissier /* 224611fa71b9SJerome Forissier * Swap transform_out and out_ctr with the alternative ones 224711fa71b9SJerome Forissier */ 2248039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 224911fa71b9SJerome Forissier static int ssl_swap_epochs(mbedtls_ssl_context *ssl) 225011fa71b9SJerome Forissier { 225111fa71b9SJerome Forissier mbedtls_ssl_transform *tmp_transform; 2252*32b31808SJens Wiklander unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN]; 225311fa71b9SJerome Forissier 2254*32b31808SJens Wiklander if (ssl->transform_out == ssl->handshake->alt_transform_out) { 225511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs")); 2256*32b31808SJens Wiklander return 0; 225711fa71b9SJerome Forissier } 225811fa71b9SJerome Forissier 225911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs")); 226011fa71b9SJerome Forissier 226111fa71b9SJerome Forissier /* Swap transforms */ 226211fa71b9SJerome Forissier tmp_transform = ssl->transform_out; 226311fa71b9SJerome Forissier ssl->transform_out = ssl->handshake->alt_transform_out; 226411fa71b9SJerome Forissier ssl->handshake->alt_transform_out = tmp_transform; 226511fa71b9SJerome Forissier 226611fa71b9SJerome Forissier /* Swap epoch + sequence_number */ 2267*32b31808SJens Wiklander memcpy(tmp_out_ctr, ssl->cur_out_ctr, sizeof(tmp_out_ctr)); 2268*32b31808SJens Wiklander memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 2269*32b31808SJens Wiklander sizeof(ssl->cur_out_ctr)); 2270*32b31808SJens Wiklander memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr, 2271*32b31808SJens Wiklander sizeof(ssl->handshake->alt_out_ctr)); 227211fa71b9SJerome Forissier 227311fa71b9SJerome Forissier /* Adjust to the newly activated transform */ 227411fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); 227511fa71b9SJerome Forissier 2276*32b31808SJens Wiklander return 0; 227711fa71b9SJerome Forissier } 227811fa71b9SJerome Forissier 227911fa71b9SJerome Forissier /* 228011fa71b9SJerome Forissier * Retransmit the current flight of messages. 228111fa71b9SJerome Forissier */ 228211fa71b9SJerome Forissier int mbedtls_ssl_resend(mbedtls_ssl_context *ssl) 228311fa71b9SJerome Forissier { 228411fa71b9SJerome Forissier int ret = 0; 228511fa71b9SJerome Forissier 228611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend")); 228711fa71b9SJerome Forissier 228811fa71b9SJerome Forissier ret = mbedtls_ssl_flight_transmit(ssl); 228911fa71b9SJerome Forissier 229011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend")); 229111fa71b9SJerome Forissier 2292*32b31808SJens Wiklander return ret; 229311fa71b9SJerome Forissier } 229411fa71b9SJerome Forissier 229511fa71b9SJerome Forissier /* 229611fa71b9SJerome Forissier * Transmit or retransmit the current flight of messages. 229711fa71b9SJerome Forissier * 229811fa71b9SJerome Forissier * Need to remember the current message in case flush_output returns 229911fa71b9SJerome Forissier * WANT_WRITE, causing us to exit this function and come back later. 230011fa71b9SJerome Forissier * This function must be called until state is no longer SENDING. 230111fa71b9SJerome Forissier */ 230211fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl) 230311fa71b9SJerome Forissier { 230411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 230511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit")); 230611fa71b9SJerome Forissier 2307*32b31808SJens Wiklander if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) { 230811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission")); 230911fa71b9SJerome Forissier 231011fa71b9SJerome Forissier ssl->handshake->cur_msg = ssl->handshake->flight; 231111fa71b9SJerome Forissier ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; 231211fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl); 2313*32b31808SJens Wiklander if (ret != 0) { 2314*32b31808SJens Wiklander return ret; 2315*32b31808SJens Wiklander } 231611fa71b9SJerome Forissier 231711fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; 231811fa71b9SJerome Forissier } 231911fa71b9SJerome Forissier 2320*32b31808SJens Wiklander while (ssl->handshake->cur_msg != NULL) { 232111fa71b9SJerome Forissier size_t max_frag_len; 232211fa71b9SJerome Forissier const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; 232311fa71b9SJerome Forissier 232411fa71b9SJerome Forissier int const is_finished = 232511fa71b9SJerome Forissier (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && 232611fa71b9SJerome Forissier cur->p[0] == MBEDTLS_SSL_HS_FINISHED); 232711fa71b9SJerome Forissier 2328*32b31808SJens Wiklander int const force_flush = ssl->disable_datagram_packing == 1 ? 232911fa71b9SJerome Forissier SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; 233011fa71b9SJerome Forissier 233111fa71b9SJerome Forissier /* Swap epochs before sending Finished: we can't do it after 233211fa71b9SJerome Forissier * sending ChangeCipherSpec, in case write returns WANT_READ. 233311fa71b9SJerome Forissier * Must be done before copying, may change out_msg pointer */ 2334*32b31808SJens Wiklander if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) { 233511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message")); 233611fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl); 2337*32b31808SJens Wiklander if (ret != 0) { 2338*32b31808SJens Wiklander return ret; 2339*32b31808SJens Wiklander } 234011fa71b9SJerome Forissier } 234111fa71b9SJerome Forissier 234211fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram(ssl); 2343*32b31808SJens Wiklander if (ret < 0) { 2344*32b31808SJens Wiklander return ret; 2345*32b31808SJens Wiklander } 234611fa71b9SJerome Forissier max_frag_len = (size_t) ret; 234711fa71b9SJerome Forissier 234811fa71b9SJerome Forissier /* CCS is copied as is, while HS messages may need fragmentation */ 2349*32b31808SJens Wiklander if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { 2350*32b31808SJens Wiklander if (max_frag_len == 0) { 2351*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { 2352*32b31808SJens Wiklander return ret; 2353*32b31808SJens Wiklander } 235411fa71b9SJerome Forissier 235511fa71b9SJerome Forissier continue; 235611fa71b9SJerome Forissier } 235711fa71b9SJerome Forissier 235811fa71b9SJerome Forissier memcpy(ssl->out_msg, cur->p, cur->len); 235911fa71b9SJerome Forissier ssl->out_msglen = cur->len; 236011fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 236111fa71b9SJerome Forissier 236211fa71b9SJerome Forissier /* Update position inside current message */ 236311fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur->len; 2364*32b31808SJens Wiklander } else { 236511fa71b9SJerome Forissier const unsigned char * const p = ssl->handshake->cur_msg_p; 236611fa71b9SJerome Forissier const size_t hs_len = cur->len - 12; 236711fa71b9SJerome Forissier const size_t frag_off = p - (cur->p + 12); 236811fa71b9SJerome Forissier const size_t rem_len = hs_len - frag_off; 236911fa71b9SJerome Forissier size_t cur_hs_frag_len, max_hs_frag_len; 237011fa71b9SJerome Forissier 2371*32b31808SJens Wiklander if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) { 2372*32b31808SJens Wiklander if (is_finished) { 237311fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl); 2374*32b31808SJens Wiklander if (ret != 0) { 2375*32b31808SJens Wiklander return ret; 2376*32b31808SJens Wiklander } 237711fa71b9SJerome Forissier } 237811fa71b9SJerome Forissier 2379*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { 2380*32b31808SJens Wiklander return ret; 2381*32b31808SJens Wiklander } 238211fa71b9SJerome Forissier 238311fa71b9SJerome Forissier continue; 238411fa71b9SJerome Forissier } 238511fa71b9SJerome Forissier max_hs_frag_len = max_frag_len - 12; 238611fa71b9SJerome Forissier 238711fa71b9SJerome Forissier cur_hs_frag_len = rem_len > max_hs_frag_len ? 238811fa71b9SJerome Forissier max_hs_frag_len : rem_len; 238911fa71b9SJerome Forissier 2390*32b31808SJens Wiklander if (frag_off == 0 && cur_hs_frag_len != hs_len) { 239111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting handshake message (%u > %u)", 239211fa71b9SJerome Forissier (unsigned) cur_hs_frag_len, 239311fa71b9SJerome Forissier (unsigned) max_hs_frag_len)); 239411fa71b9SJerome Forissier } 239511fa71b9SJerome Forissier 239611fa71b9SJerome Forissier /* Messages are stored with handshake headers as if not fragmented, 239711fa71b9SJerome Forissier * copy beginning of headers then fill fragmentation fields. 239811fa71b9SJerome Forissier * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ 239911fa71b9SJerome Forissier memcpy(ssl->out_msg, cur->p, 6); 240011fa71b9SJerome Forissier 2401039e02dfSJerome Forissier ssl->out_msg[6] = MBEDTLS_BYTE_2(frag_off); 2402039e02dfSJerome Forissier ssl->out_msg[7] = MBEDTLS_BYTE_1(frag_off); 2403039e02dfSJerome Forissier ssl->out_msg[8] = MBEDTLS_BYTE_0(frag_off); 240411fa71b9SJerome Forissier 2405039e02dfSJerome Forissier ssl->out_msg[9] = MBEDTLS_BYTE_2(cur_hs_frag_len); 2406039e02dfSJerome Forissier ssl->out_msg[10] = MBEDTLS_BYTE_1(cur_hs_frag_len); 2407039e02dfSJerome Forissier ssl->out_msg[11] = MBEDTLS_BYTE_0(cur_hs_frag_len); 240811fa71b9SJerome Forissier 240911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12); 241011fa71b9SJerome Forissier 241111fa71b9SJerome Forissier /* Copy the handshake message content and set records fields */ 241211fa71b9SJerome Forissier memcpy(ssl->out_msg + 12, p, cur_hs_frag_len); 241311fa71b9SJerome Forissier ssl->out_msglen = cur_hs_frag_len + 12; 241411fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 241511fa71b9SJerome Forissier 241611fa71b9SJerome Forissier /* Update position inside current message */ 241711fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur_hs_frag_len; 241811fa71b9SJerome Forissier } 241911fa71b9SJerome Forissier 242011fa71b9SJerome Forissier /* If done with the current message move to the next one if any */ 2421*32b31808SJens Wiklander if (ssl->handshake->cur_msg_p >= cur->p + cur->len) { 2422*32b31808SJens Wiklander if (cur->next != NULL) { 242311fa71b9SJerome Forissier ssl->handshake->cur_msg = cur->next; 242411fa71b9SJerome Forissier ssl->handshake->cur_msg_p = cur->next->p + 12; 2425*32b31808SJens Wiklander } else { 242611fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 242711fa71b9SJerome Forissier ssl->handshake->cur_msg_p = NULL; 242811fa71b9SJerome Forissier } 242911fa71b9SJerome Forissier } 243011fa71b9SJerome Forissier 243111fa71b9SJerome Forissier /* Actually send the message out */ 2432*32b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) { 243311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); 2434*32b31808SJens Wiklander return ret; 243511fa71b9SJerome Forissier } 243611fa71b9SJerome Forissier } 243711fa71b9SJerome Forissier 2438*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { 2439*32b31808SJens Wiklander return ret; 2440*32b31808SJens Wiklander } 244111fa71b9SJerome Forissier 244211fa71b9SJerome Forissier /* Update state and set timer */ 2443*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) { 244411fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 2445*32b31808SJens Wiklander } else { 244611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 244711fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout); 244811fa71b9SJerome Forissier } 244911fa71b9SJerome Forissier 245011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit")); 245111fa71b9SJerome Forissier 2452*32b31808SJens Wiklander return 0; 245311fa71b9SJerome Forissier } 245411fa71b9SJerome Forissier 245511fa71b9SJerome Forissier /* 245611fa71b9SJerome Forissier * To be called when the last message of an incoming flight is received. 245711fa71b9SJerome Forissier */ 245811fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl) 245911fa71b9SJerome Forissier { 246011fa71b9SJerome Forissier /* We won't need to resend that one any more */ 246111fa71b9SJerome Forissier mbedtls_ssl_flight_free(ssl->handshake->flight); 246211fa71b9SJerome Forissier ssl->handshake->flight = NULL; 246311fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 246411fa71b9SJerome Forissier 246511fa71b9SJerome Forissier /* The next incoming flight will start with this msg_seq */ 246611fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; 246711fa71b9SJerome Forissier 246811fa71b9SJerome Forissier /* We don't want to remember CCS's across flight boundaries. */ 246911fa71b9SJerome Forissier ssl->handshake->buffering.seen_ccs = 0; 247011fa71b9SJerome Forissier 247111fa71b9SJerome Forissier /* Clear future message buffering structure. */ 247211fa71b9SJerome Forissier mbedtls_ssl_buffering_free(ssl); 247311fa71b9SJerome Forissier 247411fa71b9SJerome Forissier /* Cancel timer */ 247511fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0); 247611fa71b9SJerome Forissier 247711fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 2478*32b31808SJens Wiklander ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) { 247911fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 2480*32b31808SJens Wiklander } else { 248111fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; 248211fa71b9SJerome Forissier } 2483*32b31808SJens Wiklander } 248411fa71b9SJerome Forissier 248511fa71b9SJerome Forissier /* 248611fa71b9SJerome Forissier * To be called when the last message of an outgoing flight is send. 248711fa71b9SJerome Forissier */ 248811fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl) 248911fa71b9SJerome Forissier { 249011fa71b9SJerome Forissier ssl_reset_retransmit_timeout(ssl); 249111fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout); 249211fa71b9SJerome Forissier 249311fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 2494*32b31808SJens Wiklander ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) { 249511fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 2496*32b31808SJens Wiklander } else { 249711fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 249811fa71b9SJerome Forissier } 2499*32b31808SJens Wiklander } 250011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 250111fa71b9SJerome Forissier 250211fa71b9SJerome Forissier /* 250311fa71b9SJerome Forissier * Handshake layer functions 250411fa71b9SJerome Forissier */ 2505*32b31808SJens Wiklander int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned hs_type, 2506*32b31808SJens Wiklander unsigned char **buf, size_t *buf_len) 2507*32b31808SJens Wiklander { 2508*32b31808SJens Wiklander /* 2509*32b31808SJens Wiklander * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 ) 2510*32b31808SJens Wiklander * ... 2511*32b31808SJens Wiklander * HandshakeType msg_type; 2512*32b31808SJens Wiklander * uint24 length; 2513*32b31808SJens Wiklander * ... 2514*32b31808SJens Wiklander */ 2515*32b31808SJens Wiklander *buf = ssl->out_msg + 4; 2516*32b31808SJens Wiklander *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4; 2517*32b31808SJens Wiklander 2518*32b31808SJens Wiklander ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 2519*32b31808SJens Wiklander ssl->out_msg[0] = hs_type; 2520*32b31808SJens Wiklander 2521*32b31808SJens Wiklander return 0; 2522*32b31808SJens Wiklander } 252311fa71b9SJerome Forissier 252411fa71b9SJerome Forissier /* 252511fa71b9SJerome Forissier * Write (DTLS: or queue) current handshake (including CCS) message. 252611fa71b9SJerome Forissier * 252711fa71b9SJerome Forissier * - fill in handshake headers 252811fa71b9SJerome Forissier * - update handshake checksum 252911fa71b9SJerome Forissier * - DTLS: save message for resending 253011fa71b9SJerome Forissier * - then pass to the record layer 253111fa71b9SJerome Forissier * 253211fa71b9SJerome Forissier * DTLS: except for HelloRequest, messages are only queued, and will only be 253311fa71b9SJerome Forissier * actually sent when calling flight_transmit() or resend(). 253411fa71b9SJerome Forissier * 253511fa71b9SJerome Forissier * Inputs: 253611fa71b9SJerome Forissier * - ssl->out_msglen: 4 + actual handshake message len 253711fa71b9SJerome Forissier * (4 is the size of handshake headers for TLS) 253811fa71b9SJerome Forissier * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) 253911fa71b9SJerome Forissier * - ssl->out_msg + 4: the handshake message body 254011fa71b9SJerome Forissier * 254111fa71b9SJerome Forissier * Outputs, ie state before passing to flight_append() or write_record(): 254211fa71b9SJerome Forissier * - ssl->out_msglen: the length of the record contents 254311fa71b9SJerome Forissier * (including handshake headers but excluding record headers) 254411fa71b9SJerome Forissier * - ssl->out_msg: the record contents (handshake headers + content) 254511fa71b9SJerome Forissier */ 2546*32b31808SJens Wiklander int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl, 2547*32b31808SJens Wiklander int update_checksum, 2548*32b31808SJens Wiklander int force_flush) 254911fa71b9SJerome Forissier { 255011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 255111fa71b9SJerome Forissier const size_t hs_len = ssl->out_msglen - 4; 255211fa71b9SJerome Forissier const unsigned char hs_type = ssl->out_msg[0]; 255311fa71b9SJerome Forissier 255411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message")); 255511fa71b9SJerome Forissier 255611fa71b9SJerome Forissier /* 255711fa71b9SJerome Forissier * Sanity checks 255811fa71b9SJerome Forissier */ 255911fa71b9SJerome Forissier if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && 2560*32b31808SJens Wiklander ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { 256111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2562*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 256311fa71b9SJerome Forissier } 256411fa71b9SJerome Forissier 256511fa71b9SJerome Forissier /* Whenever we send anything different from a 256611fa71b9SJerome Forissier * HelloRequest we should be in a handshake - double check. */ 256711fa71b9SJerome Forissier if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 256811fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST) && 2569*32b31808SJens Wiklander ssl->handshake == NULL) { 257011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2571*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 257211fa71b9SJerome Forissier } 257311fa71b9SJerome Forissier 257411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 257511fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 257611fa71b9SJerome Forissier ssl->handshake != NULL && 2577*32b31808SJens Wiklander ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) { 257811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2579*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 258011fa71b9SJerome Forissier } 258111fa71b9SJerome Forissier #endif 258211fa71b9SJerome Forissier 258311fa71b9SJerome Forissier /* Double-check that we did not exceed the bounds 258411fa71b9SJerome Forissier * of the outgoing record buffer. 258511fa71b9SJerome Forissier * This should never fail as the various message 258611fa71b9SJerome Forissier * writing functions must obey the bounds of the 258711fa71b9SJerome Forissier * outgoing record buffer, but better be safe. 258811fa71b9SJerome Forissier * 258911fa71b9SJerome Forissier * Note: We deliberately do not check for the MTU or MFL here. 259011fa71b9SJerome Forissier */ 2591*32b31808SJens Wiklander if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) { 259211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: " 25937901324dSJerome Forissier "size %" MBEDTLS_PRINTF_SIZET 25947901324dSJerome Forissier ", maximum %" MBEDTLS_PRINTF_SIZET, 25957901324dSJerome Forissier ssl->out_msglen, 25967901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN)); 2597*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 259811fa71b9SJerome Forissier } 259911fa71b9SJerome Forissier 260011fa71b9SJerome Forissier /* 260111fa71b9SJerome Forissier * Fill handshake headers 260211fa71b9SJerome Forissier */ 2603*32b31808SJens Wiklander if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { 2604039e02dfSJerome Forissier ssl->out_msg[1] = MBEDTLS_BYTE_2(hs_len); 2605039e02dfSJerome Forissier ssl->out_msg[2] = MBEDTLS_BYTE_1(hs_len); 2606039e02dfSJerome Forissier ssl->out_msg[3] = MBEDTLS_BYTE_0(hs_len); 260711fa71b9SJerome Forissier 260811fa71b9SJerome Forissier /* 260911fa71b9SJerome Forissier * DTLS has additional fields in the Handshake layer, 261011fa71b9SJerome Forissier * between the length field and the actual payload: 261111fa71b9SJerome Forissier * uint16 message_seq; 261211fa71b9SJerome Forissier * uint24 fragment_offset; 261311fa71b9SJerome Forissier * uint24 fragment_length; 261411fa71b9SJerome Forissier */ 261511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 2616*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 261711fa71b9SJerome Forissier /* Make room for the additional DTLS fields */ 2618*32b31808SJens Wiklander if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) { 261911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS handshake message too large: " 2620*32b31808SJens Wiklander "size %" MBEDTLS_PRINTF_SIZET ", maximum %" 2621*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET, 26227901324dSJerome Forissier hs_len, 26237901324dSJerome Forissier (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - 12))); 2624*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 262511fa71b9SJerome Forissier } 262611fa71b9SJerome Forissier 262711fa71b9SJerome Forissier memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len); 262811fa71b9SJerome Forissier ssl->out_msglen += 8; 262911fa71b9SJerome Forissier 263011fa71b9SJerome Forissier /* Write message_seq and update it, except for HelloRequest */ 2631*32b31808SJens Wiklander if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) { 2632039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(ssl->handshake->out_msg_seq, ssl->out_msg, 4); 263311fa71b9SJerome Forissier ++(ssl->handshake->out_msg_seq); 2634*32b31808SJens Wiklander } else { 263511fa71b9SJerome Forissier ssl->out_msg[4] = 0; 263611fa71b9SJerome Forissier ssl->out_msg[5] = 0; 263711fa71b9SJerome Forissier } 263811fa71b9SJerome Forissier 263911fa71b9SJerome Forissier /* Handshake hashes are computed without fragmentation, 264011fa71b9SJerome Forissier * so set frag_offset = 0 and frag_len = hs_len for now */ 264111fa71b9SJerome Forissier memset(ssl->out_msg + 6, 0x00, 3); 264211fa71b9SJerome Forissier memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3); 264311fa71b9SJerome Forissier } 264411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 264511fa71b9SJerome Forissier 264611fa71b9SJerome Forissier /* Update running hashes of handshake messages seen */ 2647*32b31808SJens Wiklander if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) { 2648*32b31808SJens Wiklander ret = ssl->handshake->update_checksum(ssl, ssl->out_msg, 2649*32b31808SJens Wiklander ssl->out_msglen); 2650*32b31808SJens Wiklander if (ret != 0) { 2651*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); 2652*32b31808SJens Wiklander return ret; 2653*32b31808SJens Wiklander } 2654*32b31808SJens Wiklander } 265511fa71b9SJerome Forissier } 265611fa71b9SJerome Forissier 265711fa71b9SJerome Forissier /* Either send now, or just save to be sent (and resent) later */ 265811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 265911fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 266011fa71b9SJerome Forissier !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 2661*32b31808SJens Wiklander hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST)) { 2662*32b31808SJens Wiklander if ((ret = ssl_flight_append(ssl)) != 0) { 266311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret); 2664*32b31808SJens Wiklander return ret; 266511fa71b9SJerome Forissier } 2666*32b31808SJens Wiklander } else 266711fa71b9SJerome Forissier #endif 266811fa71b9SJerome Forissier { 2669*32b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) { 267011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret); 2671*32b31808SJens Wiklander return ret; 267211fa71b9SJerome Forissier } 267311fa71b9SJerome Forissier } 267411fa71b9SJerome Forissier 267511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message")); 267611fa71b9SJerome Forissier 2677*32b31808SJens Wiklander return 0; 2678*32b31808SJens Wiklander } 2679*32b31808SJens Wiklander 2680*32b31808SJens Wiklander int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl, 2681*32b31808SJens Wiklander size_t buf_len, size_t msg_len) 2682*32b31808SJens Wiklander { 2683*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2684*32b31808SJens Wiklander size_t msg_with_header_len; 2685*32b31808SJens Wiklander ((void) buf_len); 2686*32b31808SJens Wiklander 2687*32b31808SJens Wiklander /* Add reserved 4 bytes for handshake header */ 2688*32b31808SJens Wiklander msg_with_header_len = msg_len + 4; 2689*32b31808SJens Wiklander ssl->out_msglen = msg_with_header_len; 2690*32b31808SJens Wiklander MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_handshake_msg_ext(ssl, 0, 0)); 2691*32b31808SJens Wiklander 2692*32b31808SJens Wiklander cleanup: 2693*32b31808SJens Wiklander return ret; 269411fa71b9SJerome Forissier } 269511fa71b9SJerome Forissier 269611fa71b9SJerome Forissier /* 269711fa71b9SJerome Forissier * Record layer functions 269811fa71b9SJerome Forissier */ 269911fa71b9SJerome Forissier 270011fa71b9SJerome Forissier /* 270111fa71b9SJerome Forissier * Write current record. 270211fa71b9SJerome Forissier * 270311fa71b9SJerome Forissier * Uses: 270411fa71b9SJerome Forissier * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) 270511fa71b9SJerome Forissier * - ssl->out_msglen: length of the record content (excl headers) 270611fa71b9SJerome Forissier * - ssl->out_msg: record content 270711fa71b9SJerome Forissier */ 2708*32b31808SJens Wiklander int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush) 270911fa71b9SJerome Forissier { 271011fa71b9SJerome Forissier int ret, done = 0; 271111fa71b9SJerome Forissier size_t len = ssl->out_msglen; 2712*32b31808SJens Wiklander int flush = force_flush; 271311fa71b9SJerome Forissier 271411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record")); 271511fa71b9SJerome Forissier 2716*32b31808SJens Wiklander if (!done) { 271711fa71b9SJerome Forissier unsigned i; 271811fa71b9SJerome Forissier size_t protected_record_size; 271911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 272011fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 272111fa71b9SJerome Forissier #else 272211fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 272311fa71b9SJerome Forissier #endif 272411fa71b9SJerome Forissier /* Skip writing the record content type to after the encryption, 272511fa71b9SJerome Forissier * as it may change when using the CID extension. */ 2726*32b31808SJens Wiklander mbedtls_ssl_protocol_version tls_ver = ssl->tls_version; 2727*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 2728*32b31808SJens Wiklander /* TLS 1.3 still uses the TLS 1.2 version identifier 2729*32b31808SJens Wiklander * for backwards compatibility. */ 2730*32b31808SJens Wiklander if (tls_ver == MBEDTLS_SSL_VERSION_TLS1_3) { 2731*32b31808SJens Wiklander tls_ver = MBEDTLS_SSL_VERSION_TLS1_2; 2732*32b31808SJens Wiklander } 2733*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 2734*32b31808SJens Wiklander mbedtls_ssl_write_version(ssl->out_hdr + 1, ssl->conf->transport, 2735*32b31808SJens Wiklander tls_ver); 273611fa71b9SJerome Forissier 2737*32b31808SJens Wiklander memcpy(ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); 2738039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(len, ssl->out_len, 0); 273911fa71b9SJerome Forissier 2740*32b31808SJens Wiklander if (ssl->transform_out != NULL) { 274111fa71b9SJerome Forissier mbedtls_record rec; 274211fa71b9SJerome Forissier 274311fa71b9SJerome Forissier rec.buf = ssl->out_iv; 274411fa71b9SJerome Forissier rec.buf_len = out_buf_len - (ssl->out_iv - ssl->out_buf); 274511fa71b9SJerome Forissier rec.data_len = ssl->out_msglen; 274611fa71b9SJerome Forissier rec.data_offset = ssl->out_msg - rec.buf; 274711fa71b9SJerome Forissier 2748*32b31808SJens Wiklander memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr)); 2749*32b31808SJens Wiklander mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver); 275011fa71b9SJerome Forissier rec.type = ssl->out_msgtype; 275111fa71b9SJerome Forissier 275211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 275311fa71b9SJerome Forissier /* The CID is set by mbedtls_ssl_encrypt_buf(). */ 275411fa71b9SJerome Forissier rec.cid_len = 0; 275511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 275611fa71b9SJerome Forissier 275711fa71b9SJerome Forissier if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec, 2758*32b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 275911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret); 2760*32b31808SJens Wiklander return ret; 276111fa71b9SJerome Forissier } 276211fa71b9SJerome Forissier 2763*32b31808SJens Wiklander if (rec.data_offset != 0) { 276411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2765*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 276611fa71b9SJerome Forissier } 276711fa71b9SJerome Forissier 276811fa71b9SJerome Forissier /* Update the record content type and CID. */ 276911fa71b9SJerome Forissier ssl->out_msgtype = rec.type; 277011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 277111fa71b9SJerome Forissier memcpy(ssl->out_cid, rec.cid, rec.cid_len); 277211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 277311fa71b9SJerome Forissier ssl->out_msglen = len = rec.data_len; 2774039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->out_len, 0); 277511fa71b9SJerome Forissier } 277611fa71b9SJerome Forissier 277711fa71b9SJerome Forissier protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl); 277811fa71b9SJerome Forissier 277911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 278011fa71b9SJerome Forissier /* In case of DTLS, double-check that we don't exceed 278111fa71b9SJerome Forissier * the remaining space in the datagram. */ 2782*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 278311fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram(ssl); 2784*32b31808SJens Wiklander if (ret < 0) { 2785*32b31808SJens Wiklander return ret; 2786*32b31808SJens Wiklander } 278711fa71b9SJerome Forissier 2788*32b31808SJens Wiklander if (protected_record_size > (size_t) ret) { 278911fa71b9SJerome Forissier /* Should never happen */ 2790*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 279111fa71b9SJerome Forissier } 279211fa71b9SJerome Forissier } 279311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 279411fa71b9SJerome Forissier 279511fa71b9SJerome Forissier /* Now write the potentially updated record content type. */ 279611fa71b9SJerome Forissier ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; 279711fa71b9SJerome Forissier 27987901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("output record: msgtype = %u, " 27997901324dSJerome Forissier "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET, 280011fa71b9SJerome Forissier ssl->out_hdr[0], ssl->out_hdr[1], 280111fa71b9SJerome Forissier ssl->out_hdr[2], len)); 280211fa71b9SJerome Forissier 280311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", 280411fa71b9SJerome Forissier ssl->out_hdr, protected_record_size); 280511fa71b9SJerome Forissier 280611fa71b9SJerome Forissier ssl->out_left += protected_record_size; 280711fa71b9SJerome Forissier ssl->out_hdr += protected_record_size; 280811fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out); 280911fa71b9SJerome Forissier 2810*32b31808SJens Wiklander for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--) { 2811*32b31808SJens Wiklander if (++ssl->cur_out_ctr[i - 1] != 0) { 281211fa71b9SJerome Forissier break; 2813*32b31808SJens Wiklander } 2814*32b31808SJens Wiklander } 281511fa71b9SJerome Forissier 2816*32b31808SJens Wiklander /* The loop goes to its end if the counter is wrapping */ 2817*32b31808SJens Wiklander if (i == mbedtls_ssl_ep_len(ssl)) { 281811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap")); 2819*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; 282011fa71b9SJerome Forissier } 282111fa71b9SJerome Forissier } 282211fa71b9SJerome Forissier 282311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 282411fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 2825*32b31808SJens Wiklander flush == SSL_DONT_FORCE_FLUSH) { 282611fa71b9SJerome Forissier size_t remaining; 282711fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram(ssl); 2828*32b31808SJens Wiklander if (ret < 0) { 282911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram", 283011fa71b9SJerome Forissier ret); 2831*32b31808SJens Wiklander return ret; 283211fa71b9SJerome Forissier } 283311fa71b9SJerome Forissier 283411fa71b9SJerome Forissier remaining = (size_t) ret; 2835*32b31808SJens Wiklander if (remaining == 0) { 283611fa71b9SJerome Forissier flush = SSL_FORCE_FLUSH; 2837*32b31808SJens Wiklander } else { 2838*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 2839*32b31808SJens Wiklander ("Still %u bytes available in current datagram", 2840*32b31808SJens Wiklander (unsigned) remaining)); 284111fa71b9SJerome Forissier } 284211fa71b9SJerome Forissier } 284311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 284411fa71b9SJerome Forissier 284511fa71b9SJerome Forissier if ((flush == SSL_FORCE_FLUSH) && 2846*32b31808SJens Wiklander (ret = mbedtls_ssl_flush_output(ssl)) != 0) { 284711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); 2848*32b31808SJens Wiklander return ret; 284911fa71b9SJerome Forissier } 285011fa71b9SJerome Forissier 285111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record")); 285211fa71b9SJerome Forissier 2853*32b31808SJens Wiklander return 0; 285411fa71b9SJerome Forissier } 285511fa71b9SJerome Forissier 285611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 285711fa71b9SJerome Forissier 2858039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 285911fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl) 286011fa71b9SJerome Forissier { 286111fa71b9SJerome Forissier if (ssl->in_msglen < ssl->in_hslen || 286211fa71b9SJerome Forissier memcmp(ssl->in_msg + 6, "\0\0\0", 3) != 0 || 2863*32b31808SJens Wiklander memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) { 2864*32b31808SJens Wiklander return 1; 286511fa71b9SJerome Forissier } 2866*32b31808SJens Wiklander return 0; 286711fa71b9SJerome Forissier } 286811fa71b9SJerome Forissier 286911fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl) 287011fa71b9SJerome Forissier { 2871*32b31808SJens Wiklander return (ssl->in_msg[9] << 16) | 287211fa71b9SJerome Forissier (ssl->in_msg[10] << 8) | 2873*32b31808SJens Wiklander ssl->in_msg[11]; 287411fa71b9SJerome Forissier } 287511fa71b9SJerome Forissier 287611fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl) 287711fa71b9SJerome Forissier { 2878*32b31808SJens Wiklander return (ssl->in_msg[6] << 16) | 287911fa71b9SJerome Forissier (ssl->in_msg[7] << 8) | 2880*32b31808SJens Wiklander ssl->in_msg[8]; 288111fa71b9SJerome Forissier } 288211fa71b9SJerome Forissier 2883039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 288411fa71b9SJerome Forissier static int ssl_check_hs_header(mbedtls_ssl_context const *ssl) 288511fa71b9SJerome Forissier { 288611fa71b9SJerome Forissier uint32_t msg_len, frag_off, frag_len; 288711fa71b9SJerome Forissier 288811fa71b9SJerome Forissier msg_len = ssl_get_hs_total_len(ssl); 288911fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off(ssl); 289011fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len(ssl); 289111fa71b9SJerome Forissier 2892*32b31808SJens Wiklander if (frag_off > msg_len) { 2893*32b31808SJens Wiklander return -1; 2894*32b31808SJens Wiklander } 289511fa71b9SJerome Forissier 2896*32b31808SJens Wiklander if (frag_len > msg_len - frag_off) { 2897*32b31808SJens Wiklander return -1; 2898*32b31808SJens Wiklander } 289911fa71b9SJerome Forissier 2900*32b31808SJens Wiklander if (frag_len + 12 > ssl->in_msglen) { 2901*32b31808SJens Wiklander return -1; 2902*32b31808SJens Wiklander } 290311fa71b9SJerome Forissier 2904*32b31808SJens Wiklander return 0; 290511fa71b9SJerome Forissier } 290611fa71b9SJerome Forissier 290711fa71b9SJerome Forissier /* 290811fa71b9SJerome Forissier * Mark bits in bitmask (used for DTLS HS reassembly) 290911fa71b9SJerome Forissier */ 291011fa71b9SJerome Forissier static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len) 291111fa71b9SJerome Forissier { 291211fa71b9SJerome Forissier unsigned int start_bits, end_bits; 291311fa71b9SJerome Forissier 291411fa71b9SJerome Forissier start_bits = 8 - (offset % 8); 2915*32b31808SJens Wiklander if (start_bits != 8) { 291611fa71b9SJerome Forissier size_t first_byte_idx = offset / 8; 291711fa71b9SJerome Forissier 291811fa71b9SJerome Forissier /* Special case */ 2919*32b31808SJens Wiklander if (len <= start_bits) { 2920*32b31808SJens Wiklander for (; len != 0; len--) { 292111fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << (start_bits - len); 2922*32b31808SJens Wiklander } 292311fa71b9SJerome Forissier 292411fa71b9SJerome Forissier /* Avoid potential issues with offset or len becoming invalid */ 292511fa71b9SJerome Forissier return; 292611fa71b9SJerome Forissier } 292711fa71b9SJerome Forissier 292811fa71b9SJerome Forissier offset += start_bits; /* Now offset % 8 == 0 */ 292911fa71b9SJerome Forissier len -= start_bits; 293011fa71b9SJerome Forissier 2931*32b31808SJens Wiklander for (; start_bits != 0; start_bits--) { 293211fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << (start_bits - 1); 293311fa71b9SJerome Forissier } 2934*32b31808SJens Wiklander } 293511fa71b9SJerome Forissier 293611fa71b9SJerome Forissier end_bits = len % 8; 2937*32b31808SJens Wiklander if (end_bits != 0) { 293811fa71b9SJerome Forissier size_t last_byte_idx = (offset + len) / 8; 293911fa71b9SJerome Forissier 294011fa71b9SJerome Forissier len -= end_bits; /* Now len % 8 == 0 */ 294111fa71b9SJerome Forissier 2942*32b31808SJens Wiklander for (; end_bits != 0; end_bits--) { 294311fa71b9SJerome Forissier mask[last_byte_idx] |= 1 << (8 - end_bits); 294411fa71b9SJerome Forissier } 2945*32b31808SJens Wiklander } 294611fa71b9SJerome Forissier 294711fa71b9SJerome Forissier memset(mask + offset / 8, 0xFF, len / 8); 294811fa71b9SJerome Forissier } 294911fa71b9SJerome Forissier 295011fa71b9SJerome Forissier /* 295111fa71b9SJerome Forissier * Check that bitmask is full 295211fa71b9SJerome Forissier */ 2953039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 295411fa71b9SJerome Forissier static int ssl_bitmask_check(unsigned char *mask, size_t len) 295511fa71b9SJerome Forissier { 295611fa71b9SJerome Forissier size_t i; 295711fa71b9SJerome Forissier 2958*32b31808SJens Wiklander for (i = 0; i < len / 8; i++) { 2959*32b31808SJens Wiklander if (mask[i] != 0xFF) { 2960*32b31808SJens Wiklander return -1; 2961*32b31808SJens Wiklander } 2962*32b31808SJens Wiklander } 296311fa71b9SJerome Forissier 2964*32b31808SJens Wiklander for (i = 0; i < len % 8; i++) { 2965*32b31808SJens Wiklander if ((mask[len / 8] & (1 << (7 - i))) == 0) { 2966*32b31808SJens Wiklander return -1; 2967*32b31808SJens Wiklander } 2968*32b31808SJens Wiklander } 296911fa71b9SJerome Forissier 2970*32b31808SJens Wiklander return 0; 297111fa71b9SJerome Forissier } 297211fa71b9SJerome Forissier 297311fa71b9SJerome Forissier /* msg_len does not include the handshake header */ 297411fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size(size_t msg_len, 297511fa71b9SJerome Forissier unsigned add_bitmap) 297611fa71b9SJerome Forissier { 297711fa71b9SJerome Forissier size_t alloc_len; 297811fa71b9SJerome Forissier 297911fa71b9SJerome Forissier alloc_len = 12; /* Handshake header */ 298011fa71b9SJerome Forissier alloc_len += msg_len; /* Content buffer */ 298111fa71b9SJerome Forissier 2982*32b31808SJens Wiklander if (add_bitmap) { 298311fa71b9SJerome Forissier alloc_len += msg_len / 8 + (msg_len % 8 != 0); /* Bitmap */ 298411fa71b9SJerome Forissier 2985*32b31808SJens Wiklander } 2986*32b31808SJens Wiklander return alloc_len; 298711fa71b9SJerome Forissier } 298811fa71b9SJerome Forissier 298911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 299011fa71b9SJerome Forissier 299111fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl) 299211fa71b9SJerome Forissier { 2993*32b31808SJens Wiklander return (ssl->in_msg[1] << 16) | 299411fa71b9SJerome Forissier (ssl->in_msg[2] << 8) | 2995*32b31808SJens Wiklander ssl->in_msg[3]; 299611fa71b9SJerome Forissier } 299711fa71b9SJerome Forissier 299811fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) 299911fa71b9SJerome Forissier { 3000*32b31808SJens Wiklander if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) { 30017901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET, 300211fa71b9SJerome Forissier ssl->in_msglen)); 3003*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 300411fa71b9SJerome Forissier } 300511fa71b9SJerome Forissier 300611fa71b9SJerome Forissier ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl); 300711fa71b9SJerome Forissier 300811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen =" 3009*32b31808SJens Wiklander " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" 3010*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET, 301111fa71b9SJerome Forissier ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen)); 301211fa71b9SJerome Forissier 301311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3014*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 301511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 301611fa71b9SJerome Forissier unsigned int recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5]; 301711fa71b9SJerome Forissier 3018*32b31808SJens Wiklander if (ssl_check_hs_header(ssl) != 0) { 301911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header")); 3020*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 302111fa71b9SJerome Forissier } 302211fa71b9SJerome Forissier 302311fa71b9SJerome Forissier if (ssl->handshake != NULL && 3024*32b31808SJens Wiklander ((mbedtls_ssl_is_handshake_over(ssl) == 0 && 302511fa71b9SJerome Forissier recv_msg_seq != ssl->handshake->in_msg_seq) || 3026*32b31808SJens Wiklander (mbedtls_ssl_is_handshake_over(ssl) == 1 && 3027*32b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) { 3028*32b31808SJens Wiklander if (recv_msg_seq > ssl->handshake->in_msg_seq) { 3029*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 3030*32b31808SJens Wiklander ( 3031*32b31808SJens Wiklander "received future handshake message of sequence number %u (next %u)", 303211fa71b9SJerome Forissier recv_msg_seq, 303311fa71b9SJerome Forissier ssl->handshake->in_msg_seq)); 3034*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE; 303511fa71b9SJerome Forissier } 303611fa71b9SJerome Forissier 303711fa71b9SJerome Forissier /* Retransmit only on last message from previous flight, to avoid 303811fa71b9SJerome Forissier * too many retransmissions. 303911fa71b9SJerome Forissier * Besides, No sane server ever retransmits HelloVerifyRequest */ 304011fa71b9SJerome Forissier if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && 3041*32b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) { 304211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("received message from last flight, " 30437901324dSJerome Forissier "message_seq = %u, start_of_flight = %u", 304411fa71b9SJerome Forissier recv_msg_seq, 304511fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq)); 304611fa71b9SJerome Forissier 3047*32b31808SJens Wiklander if ((ret = mbedtls_ssl_resend(ssl)) != 0) { 304811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret); 3049*32b31808SJens Wiklander return ret; 305011fa71b9SJerome Forissier } 3051*32b31808SJens Wiklander } else { 305211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: " 30537901324dSJerome Forissier "message_seq = %u, expected = %u", 305411fa71b9SJerome Forissier recv_msg_seq, 305511fa71b9SJerome Forissier ssl->handshake->in_msg_seq)); 305611fa71b9SJerome Forissier } 305711fa71b9SJerome Forissier 3058*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 305911fa71b9SJerome Forissier } 306011fa71b9SJerome Forissier /* Wait until message completion to increment in_msg_seq */ 306111fa71b9SJerome Forissier 306211fa71b9SJerome Forissier /* Message reassembly is handled alongside buffering of future 306311fa71b9SJerome Forissier * messages; the commonality is that both handshake fragments and 306411fa71b9SJerome Forissier * future messages cannot be forwarded immediately to the 306511fa71b9SJerome Forissier * handshake logic layer. */ 3066*32b31808SJens Wiklander if (ssl_hs_is_proper_fragment(ssl) == 1) { 306711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("found fragmented DTLS handshake message")); 3068*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE; 306911fa71b9SJerome Forissier } 3070*32b31808SJens Wiklander } else 307111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 307211fa71b9SJerome Forissier /* With TLS we don't handle fragmentation (for now) */ 3073*32b31808SJens Wiklander if (ssl->in_msglen < ssl->in_hslen) { 307411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported")); 3075*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 307611fa71b9SJerome Forissier } 307711fa71b9SJerome Forissier 3078*32b31808SJens Wiklander return 0; 307911fa71b9SJerome Forissier } 308011fa71b9SJerome Forissier 3081*32b31808SJens Wiklander int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) 308211fa71b9SJerome Forissier { 3083*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 308411fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 308511fa71b9SJerome Forissier 3086*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) { 3087*32b31808SJens Wiklander ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen); 3088*32b31808SJens Wiklander if (ret != 0) { 3089*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); 3090*32b31808SJens Wiklander return ret; 3091*32b31808SJens Wiklander } 309211fa71b9SJerome Forissier } 309311fa71b9SJerome Forissier 309411fa71b9SJerome Forissier /* Handshake message is complete, increment counter */ 309511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 309611fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 3097*32b31808SJens Wiklander ssl->handshake != NULL) { 309811fa71b9SJerome Forissier unsigned offset; 309911fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 310011fa71b9SJerome Forissier 310111fa71b9SJerome Forissier /* Increment handshake sequence number */ 310211fa71b9SJerome Forissier hs->in_msg_seq++; 310311fa71b9SJerome Forissier 310411fa71b9SJerome Forissier /* 310511fa71b9SJerome Forissier * Clear up handshake buffering and reassembly structure. 310611fa71b9SJerome Forissier */ 310711fa71b9SJerome Forissier 310811fa71b9SJerome Forissier /* Free first entry */ 310911fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, 0); 311011fa71b9SJerome Forissier 311111fa71b9SJerome Forissier /* Shift all other entries */ 311211fa71b9SJerome Forissier for (offset = 0, hs_buf = &hs->buffering.hs[0]; 311311fa71b9SJerome Forissier offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; 3114*32b31808SJens Wiklander offset++, hs_buf++) { 311511fa71b9SJerome Forissier *hs_buf = *(hs_buf + 1); 311611fa71b9SJerome Forissier } 311711fa71b9SJerome Forissier 311811fa71b9SJerome Forissier /* Create a fresh last entry */ 311911fa71b9SJerome Forissier memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); 312011fa71b9SJerome Forissier } 312111fa71b9SJerome Forissier #endif 3122*32b31808SJens Wiklander return 0; 312311fa71b9SJerome Forissier } 312411fa71b9SJerome Forissier 312511fa71b9SJerome Forissier /* 312611fa71b9SJerome Forissier * DTLS anti-replay: RFC 6347 4.1.2.6 312711fa71b9SJerome Forissier * 312811fa71b9SJerome Forissier * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). 312911fa71b9SJerome Forissier * Bit n is set iff record number in_window_top - n has been seen. 313011fa71b9SJerome Forissier * 313111fa71b9SJerome Forissier * Usually, in_window_top is the last record number seen and the lsb of 313211fa71b9SJerome Forissier * in_window is set. The only exception is the initial state (record number 0 313311fa71b9SJerome Forissier * not seen yet). 313411fa71b9SJerome Forissier */ 313511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 313611fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl) 313711fa71b9SJerome Forissier { 313811fa71b9SJerome Forissier ssl->in_window_top = 0; 313911fa71b9SJerome Forissier ssl->in_window = 0; 314011fa71b9SJerome Forissier } 314111fa71b9SJerome Forissier 314211fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes(unsigned char *buf) 314311fa71b9SJerome Forissier { 3144*32b31808SJens Wiklander return ((uint64_t) buf[0] << 40) | 314511fa71b9SJerome Forissier ((uint64_t) buf[1] << 32) | 314611fa71b9SJerome Forissier ((uint64_t) buf[2] << 24) | 314711fa71b9SJerome Forissier ((uint64_t) buf[3] << 16) | 314811fa71b9SJerome Forissier ((uint64_t) buf[4] << 8) | 3149*32b31808SJens Wiklander ((uint64_t) buf[5]); 315011fa71b9SJerome Forissier } 315111fa71b9SJerome Forissier 3152039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 315311fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr) 315411fa71b9SJerome Forissier { 315511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 315611fa71b9SJerome Forissier unsigned char *original_in_ctr; 315711fa71b9SJerome Forissier 315811fa71b9SJerome Forissier // save original in_ctr 315911fa71b9SJerome Forissier original_in_ctr = ssl->in_ctr; 316011fa71b9SJerome Forissier 316111fa71b9SJerome Forissier // use counter from record 316211fa71b9SJerome Forissier ssl->in_ctr = record_in_ctr; 316311fa71b9SJerome Forissier 316411fa71b9SJerome Forissier ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *) ssl); 316511fa71b9SJerome Forissier 316611fa71b9SJerome Forissier // restore the counter 316711fa71b9SJerome Forissier ssl->in_ctr = original_in_ctr; 316811fa71b9SJerome Forissier 316911fa71b9SJerome Forissier return ret; 317011fa71b9SJerome Forissier } 317111fa71b9SJerome Forissier 317211fa71b9SJerome Forissier /* 317311fa71b9SJerome Forissier * Return 0 if sequence number is acceptable, -1 otherwise 317411fa71b9SJerome Forissier */ 317511fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl) 317611fa71b9SJerome Forissier { 317711fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2); 317811fa71b9SJerome Forissier uint64_t bit; 317911fa71b9SJerome Forissier 3180*32b31808SJens Wiklander if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) { 3181*32b31808SJens Wiklander return 0; 3182*32b31808SJens Wiklander } 318311fa71b9SJerome Forissier 3184*32b31808SJens Wiklander if (rec_seqnum > ssl->in_window_top) { 3185*32b31808SJens Wiklander return 0; 3186*32b31808SJens Wiklander } 318711fa71b9SJerome Forissier 318811fa71b9SJerome Forissier bit = ssl->in_window_top - rec_seqnum; 318911fa71b9SJerome Forissier 3190*32b31808SJens Wiklander if (bit >= 64) { 3191*32b31808SJens Wiklander return -1; 3192*32b31808SJens Wiklander } 319311fa71b9SJerome Forissier 3194*32b31808SJens Wiklander if ((ssl->in_window & ((uint64_t) 1 << bit)) != 0) { 3195*32b31808SJens Wiklander return -1; 3196*32b31808SJens Wiklander } 319711fa71b9SJerome Forissier 3198*32b31808SJens Wiklander return 0; 319911fa71b9SJerome Forissier } 320011fa71b9SJerome Forissier 320111fa71b9SJerome Forissier /* 320211fa71b9SJerome Forissier * Update replay window on new validated record 320311fa71b9SJerome Forissier */ 320411fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl) 320511fa71b9SJerome Forissier { 320611fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2); 320711fa71b9SJerome Forissier 3208*32b31808SJens Wiklander if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) { 320911fa71b9SJerome Forissier return; 3210*32b31808SJens Wiklander } 321111fa71b9SJerome Forissier 3212*32b31808SJens Wiklander if (rec_seqnum > ssl->in_window_top) { 321311fa71b9SJerome Forissier /* Update window_top and the contents of the window */ 321411fa71b9SJerome Forissier uint64_t shift = rec_seqnum - ssl->in_window_top; 321511fa71b9SJerome Forissier 3216*32b31808SJens Wiklander if (shift >= 64) { 321711fa71b9SJerome Forissier ssl->in_window = 1; 3218*32b31808SJens Wiklander } else { 321911fa71b9SJerome Forissier ssl->in_window <<= shift; 322011fa71b9SJerome Forissier ssl->in_window |= 1; 322111fa71b9SJerome Forissier } 322211fa71b9SJerome Forissier 322311fa71b9SJerome Forissier ssl->in_window_top = rec_seqnum; 3224*32b31808SJens Wiklander } else { 322511fa71b9SJerome Forissier /* Mark that number as seen in the current window */ 322611fa71b9SJerome Forissier uint64_t bit = ssl->in_window_top - rec_seqnum; 322711fa71b9SJerome Forissier 3228*32b31808SJens Wiklander if (bit < 64) { /* Always true, but be extra sure */ 322911fa71b9SJerome Forissier ssl->in_window |= (uint64_t) 1 << bit; 323011fa71b9SJerome Forissier } 323111fa71b9SJerome Forissier } 3232*32b31808SJens Wiklander } 323311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ 323411fa71b9SJerome Forissier 323511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 323611fa71b9SJerome Forissier /* 3237039e02dfSJerome Forissier * Check if a datagram looks like a ClientHello with a valid cookie, 3238039e02dfSJerome Forissier * and if it doesn't, generate a HelloVerifyRequest message. 323911fa71b9SJerome Forissier * Both input and output include full DTLS headers. 324011fa71b9SJerome Forissier * 324111fa71b9SJerome Forissier * - if cookie is valid, return 0 324211fa71b9SJerome Forissier * - if ClientHello looks superficially valid but cookie is not, 324311fa71b9SJerome Forissier * fill obuf and set olen, then 324411fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED 324511fa71b9SJerome Forissier * - otherwise return a specific error code 324611fa71b9SJerome Forissier */ 3247039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3248039e02dfSJerome Forissier MBEDTLS_STATIC_TESTABLE 3249039e02dfSJerome Forissier int mbedtls_ssl_check_dtls_clihlo_cookie( 3250039e02dfSJerome Forissier mbedtls_ssl_context *ssl, 325111fa71b9SJerome Forissier const unsigned char *cli_id, size_t cli_id_len, 325211fa71b9SJerome Forissier const unsigned char *in, size_t in_len, 325311fa71b9SJerome Forissier unsigned char *obuf, size_t buf_len, size_t *olen) 325411fa71b9SJerome Forissier { 3255*32b31808SJens Wiklander size_t sid_len, cookie_len, epoch, fragment_offset; 325611fa71b9SJerome Forissier unsigned char *p; 325711fa71b9SJerome Forissier 325811fa71b9SJerome Forissier /* 325911fa71b9SJerome Forissier * Structure of ClientHello with record and handshake headers, 326011fa71b9SJerome Forissier * and expected values. We don't need to check a lot, more checks will be 326111fa71b9SJerome Forissier * done when actually parsing the ClientHello - skipping those checks 326211fa71b9SJerome Forissier * avoids code duplication and does not make cookie forging any easier. 326311fa71b9SJerome Forissier * 326411fa71b9SJerome Forissier * 0-0 ContentType type; copied, must be handshake 326511fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 326611fa71b9SJerome Forissier * 3-4 uint16 epoch; copied, must be 0 326711fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 326811fa71b9SJerome Forissier * 11-12 uint16 length; (ignored) 326911fa71b9SJerome Forissier * 327011fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; (ignored) 327111fa71b9SJerome Forissier * 14-16 uint24 length; (ignored) 327211fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 327311fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied, must be 0 327411fa71b9SJerome Forissier * 22-24 uint24 fragment_length; (ignored) 327511fa71b9SJerome Forissier * 327611fa71b9SJerome Forissier * 25-26 ProtocolVersion client_version; (ignored) 327711fa71b9SJerome Forissier * 27-58 Random random; (ignored) 327811fa71b9SJerome Forissier * 59-xx SessionID session_id; 1 byte len + sid_len content 327911fa71b9SJerome Forissier * 60+ opaque cookie<0..2^8-1>; 1 byte len + content 328011fa71b9SJerome Forissier * ... 328111fa71b9SJerome Forissier * 328211fa71b9SJerome Forissier * Minimum length is 61 bytes. 328311fa71b9SJerome Forissier */ 3284039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: in_len=%u", 3285039e02dfSJerome Forissier (unsigned) in_len)); 3286039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "cli_id", cli_id, cli_id_len); 3287*32b31808SJens Wiklander if (in_len < 61) { 3288039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: record too short")); 3289*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 3290039e02dfSJerome Forissier } 3291*32b31808SJens Wiklander 3292*32b31808SJens Wiklander epoch = MBEDTLS_GET_UINT16_BE(in, 3); 3293*32b31808SJens Wiklander fragment_offset = MBEDTLS_GET_UINT24_BE(in, 19); 3294*32b31808SJens Wiklander 3295*32b31808SJens Wiklander if (in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 || 3296*32b31808SJens Wiklander fragment_offset != 0) { 3297039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: not a good ClientHello")); 3298039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, (" type=%u epoch=%u fragment_offset=%u", 3299*32b31808SJens Wiklander in[0], (unsigned) epoch, 3300*32b31808SJens Wiklander (unsigned) fragment_offset)); 3301*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 330211fa71b9SJerome Forissier } 330311fa71b9SJerome Forissier 330411fa71b9SJerome Forissier sid_len = in[59]; 3305*32b31808SJens Wiklander if (59 + 1 + sid_len + 1 > in_len) { 3306039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: sid_len=%u > %u", 3307039e02dfSJerome Forissier (unsigned) sid_len, 3308039e02dfSJerome Forissier (unsigned) in_len - 61)); 3309*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 3310039e02dfSJerome Forissier } 3311039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "sid received from network", 3312039e02dfSJerome Forissier in + 60, sid_len); 331311fa71b9SJerome Forissier 331411fa71b9SJerome Forissier cookie_len = in[60 + sid_len]; 3315*32b31808SJens Wiklander if (59 + 1 + sid_len + 1 + cookie_len > in_len) { 3316039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: cookie_len=%u > %u", 3317039e02dfSJerome Forissier (unsigned) cookie_len, 3318039e02dfSJerome Forissier (unsigned) (in_len - sid_len - 61))); 3319*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR; 3320039e02dfSJerome Forissier } 332111fa71b9SJerome Forissier 3322039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "cookie received from network", 3323039e02dfSJerome Forissier in + sid_len + 61, cookie_len); 3324039e02dfSJerome Forissier if (ssl->conf->f_cookie_check(ssl->conf->p_cookie, 3325039e02dfSJerome Forissier in + sid_len + 61, cookie_len, 3326*32b31808SJens Wiklander cli_id, cli_id_len) == 0) { 3327039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: valid")); 3328*32b31808SJens Wiklander return 0; 332911fa71b9SJerome Forissier } 333011fa71b9SJerome Forissier 333111fa71b9SJerome Forissier /* 333211fa71b9SJerome Forissier * If we get here, we've got an invalid cookie, let's prepare HVR. 333311fa71b9SJerome Forissier * 333411fa71b9SJerome Forissier * 0-0 ContentType type; copied 333511fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 333611fa71b9SJerome Forissier * 3-4 uint16 epoch; copied 333711fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 333811fa71b9SJerome Forissier * 11-12 uint16 length; olen - 13 333911fa71b9SJerome Forissier * 334011fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; hello_verify_request 334111fa71b9SJerome Forissier * 14-16 uint24 length; olen - 25 334211fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 334311fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied 334411fa71b9SJerome Forissier * 22-24 uint24 fragment_length; olen - 25 334511fa71b9SJerome Forissier * 334611fa71b9SJerome Forissier * 25-26 ProtocolVersion server_version; 0xfe 0xff 334711fa71b9SJerome Forissier * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie 334811fa71b9SJerome Forissier * 334911fa71b9SJerome Forissier * Minimum length is 28. 335011fa71b9SJerome Forissier */ 3351*32b31808SJens Wiklander if (buf_len < 28) { 3352*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 3353*32b31808SJens Wiklander } 335411fa71b9SJerome Forissier 335511fa71b9SJerome Forissier /* Copy most fields and adapt others */ 335611fa71b9SJerome Forissier memcpy(obuf, in, 25); 335711fa71b9SJerome Forissier obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; 335811fa71b9SJerome Forissier obuf[25] = 0xfe; 335911fa71b9SJerome Forissier obuf[26] = 0xff; 336011fa71b9SJerome Forissier 336111fa71b9SJerome Forissier /* Generate and write actual cookie */ 336211fa71b9SJerome Forissier p = obuf + 28; 3363039e02dfSJerome Forissier if (ssl->conf->f_cookie_write(ssl->conf->p_cookie, 3364039e02dfSJerome Forissier &p, obuf + buf_len, 3365*32b31808SJens Wiklander cli_id, cli_id_len) != 0) { 3366*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 336711fa71b9SJerome Forissier } 336811fa71b9SJerome Forissier 336911fa71b9SJerome Forissier *olen = p - obuf; 337011fa71b9SJerome Forissier 337111fa71b9SJerome Forissier /* Go back and fill length fields */ 337211fa71b9SJerome Forissier obuf[27] = (unsigned char) (*olen - 28); 337311fa71b9SJerome Forissier 3374039e02dfSJerome Forissier obuf[14] = obuf[22] = MBEDTLS_BYTE_2(*olen - 25); 3375039e02dfSJerome Forissier obuf[15] = obuf[23] = MBEDTLS_BYTE_1(*olen - 25); 3376039e02dfSJerome Forissier obuf[16] = obuf[24] = MBEDTLS_BYTE_0(*olen - 25); 337711fa71b9SJerome Forissier 3378039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(*olen - 13, obuf, 11); 337911fa71b9SJerome Forissier 3380*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED; 338111fa71b9SJerome Forissier } 338211fa71b9SJerome Forissier 338311fa71b9SJerome Forissier /* 338411fa71b9SJerome Forissier * Handle possible client reconnect with the same UDP quadruplet 338511fa71b9SJerome Forissier * (RFC 6347 Section 4.2.8). 338611fa71b9SJerome Forissier * 338711fa71b9SJerome Forissier * Called by ssl_parse_record_header() in case we receive an epoch 0 record 338811fa71b9SJerome Forissier * that looks like a ClientHello. 338911fa71b9SJerome Forissier * 339011fa71b9SJerome Forissier * - if the input looks like a ClientHello without cookies, 339111fa71b9SJerome Forissier * send back HelloVerifyRequest, then return 0 339211fa71b9SJerome Forissier * - if the input looks like a ClientHello with a valid cookie, 339311fa71b9SJerome Forissier * reset the session of the current context, and 339411fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT 339511fa71b9SJerome Forissier * - if anything goes wrong, return a specific error code 339611fa71b9SJerome Forissier * 339711fa71b9SJerome Forissier * This function is called (through ssl_check_client_reconnect()) when an 339811fa71b9SJerome Forissier * unexpected record is found in ssl_get_next_record(), which will discard the 339911fa71b9SJerome Forissier * record if we return 0, and bubble up the return value otherwise (this 340011fa71b9SJerome Forissier * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected 340111fa71b9SJerome Forissier * errors, and is the right thing to do in both cases). 340211fa71b9SJerome Forissier */ 3403039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 340411fa71b9SJerome Forissier static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl) 340511fa71b9SJerome Forissier { 340611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 340711fa71b9SJerome Forissier size_t len; 340811fa71b9SJerome Forissier 340911fa71b9SJerome Forissier if (ssl->conf->f_cookie_write == NULL || 3410*32b31808SJens Wiklander ssl->conf->f_cookie_check == NULL) { 341111fa71b9SJerome Forissier /* If we can't use cookies to verify reachability of the peer, 341211fa71b9SJerome Forissier * drop the record. */ 341311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, " 341411fa71b9SJerome Forissier "can't check reconnect validity")); 3415*32b31808SJens Wiklander return 0; 341611fa71b9SJerome Forissier } 341711fa71b9SJerome Forissier 3418039e02dfSJerome Forissier ret = mbedtls_ssl_check_dtls_clihlo_cookie( 3419039e02dfSJerome Forissier ssl, 342011fa71b9SJerome Forissier ssl->cli_id, ssl->cli_id_len, 342111fa71b9SJerome Forissier ssl->in_buf, ssl->in_left, 342211fa71b9SJerome Forissier ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len); 342311fa71b9SJerome Forissier 3424039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret); 342511fa71b9SJerome Forissier 3426*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) { 342711fa71b9SJerome Forissier int send_ret; 342811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest")); 342911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", 343011fa71b9SJerome Forissier ssl->out_buf, len); 343111fa71b9SJerome Forissier /* Don't check write errors as we can't do anything here. 343211fa71b9SJerome Forissier * If the error is permanent we'll catch it later, 343311fa71b9SJerome Forissier * if it's not, then hopefully it'll work next time. */ 343411fa71b9SJerome Forissier send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len); 343511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret); 343611fa71b9SJerome Forissier (void) send_ret; 343711fa71b9SJerome Forissier 3438*32b31808SJens Wiklander return 0; 343911fa71b9SJerome Forissier } 344011fa71b9SJerome Forissier 3441*32b31808SJens Wiklander if (ret == 0) { 344211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context")); 3443*32b31808SJens Wiklander if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) { 344411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "reset", ret); 3445*32b31808SJens Wiklander return ret; 344611fa71b9SJerome Forissier } 344711fa71b9SJerome Forissier 3448*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CLIENT_RECONNECT; 344911fa71b9SJerome Forissier } 345011fa71b9SJerome Forissier 3451*32b31808SJens Wiklander return ret; 345211fa71b9SJerome Forissier } 345311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 345411fa71b9SJerome Forissier 3455039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 345611fa71b9SJerome Forissier static int ssl_check_record_type(uint8_t record_type) 345711fa71b9SJerome Forissier { 345811fa71b9SJerome Forissier if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE && 345911fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_ALERT && 346011fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && 3461*32b31808SJens Wiklander record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) { 3462*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 346311fa71b9SJerome Forissier } 346411fa71b9SJerome Forissier 3465*32b31808SJens Wiklander return 0; 346611fa71b9SJerome Forissier } 346711fa71b9SJerome Forissier 346811fa71b9SJerome Forissier /* 346911fa71b9SJerome Forissier * ContentType type; 347011fa71b9SJerome Forissier * ProtocolVersion version; 347111fa71b9SJerome Forissier * uint16 epoch; // DTLS only 347211fa71b9SJerome Forissier * uint48 sequence_number; // DTLS only 347311fa71b9SJerome Forissier * uint16 length; 347411fa71b9SJerome Forissier * 347511fa71b9SJerome Forissier * Return 0 if header looks sane (and, for DTLS, the record is expected) 347611fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, 347711fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. 347811fa71b9SJerome Forissier * 347911fa71b9SJerome Forissier * With DTLS, mbedtls_ssl_read_record() will: 348011fa71b9SJerome Forissier * 1. proceed with the record if this function returns 0 348111fa71b9SJerome Forissier * 2. drop only the current record if this function returns UNEXPECTED_RECORD 348211fa71b9SJerome Forissier * 3. return CLIENT_RECONNECT if this function return that value 348311fa71b9SJerome Forissier * 4. drop the whole datagram if this function returns anything else. 348411fa71b9SJerome Forissier * Point 2 is needed when the peer is resending, and we have already received 348511fa71b9SJerome Forissier * the first record from a datagram but are still waiting for the others. 348611fa71b9SJerome Forissier */ 3487039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 348811fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl, 348911fa71b9SJerome Forissier unsigned char *buf, 349011fa71b9SJerome Forissier size_t len, 349111fa71b9SJerome Forissier mbedtls_record *rec) 349211fa71b9SJerome Forissier { 3493*32b31808SJens Wiklander mbedtls_ssl_protocol_version tls_version; 349411fa71b9SJerome Forissier 349511fa71b9SJerome Forissier size_t const rec_hdr_type_offset = 0; 349611fa71b9SJerome Forissier size_t const rec_hdr_type_len = 1; 349711fa71b9SJerome Forissier 349811fa71b9SJerome Forissier size_t const rec_hdr_version_offset = rec_hdr_type_offset + 349911fa71b9SJerome Forissier rec_hdr_type_len; 350011fa71b9SJerome Forissier size_t const rec_hdr_version_len = 2; 350111fa71b9SJerome Forissier 350211fa71b9SJerome Forissier size_t const rec_hdr_ctr_len = 8; 350311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 350411fa71b9SJerome Forissier uint32_t rec_epoch; 350511fa71b9SJerome Forissier size_t const rec_hdr_ctr_offset = rec_hdr_version_offset + 350611fa71b9SJerome Forissier rec_hdr_version_len; 350711fa71b9SJerome Forissier 350811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 350911fa71b9SJerome Forissier size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + 351011fa71b9SJerome Forissier rec_hdr_ctr_len; 351111fa71b9SJerome Forissier size_t rec_hdr_cid_len = 0; 351211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 351311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 351411fa71b9SJerome Forissier 351511fa71b9SJerome Forissier size_t rec_hdr_len_offset; /* To be determined */ 351611fa71b9SJerome Forissier size_t const rec_hdr_len_len = 2; 351711fa71b9SJerome Forissier 351811fa71b9SJerome Forissier /* 351911fa71b9SJerome Forissier * Check minimum lengths for record header. 352011fa71b9SJerome Forissier */ 352111fa71b9SJerome Forissier 352211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3523*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 352411fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len; 3525*32b31808SJens Wiklander } else 352611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 352711fa71b9SJerome Forissier { 352811fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len; 352911fa71b9SJerome Forissier } 353011fa71b9SJerome Forissier 3531*32b31808SJens Wiklander if (len < rec_hdr_len_offset + rec_hdr_len_len) { 3532*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 3533*32b31808SJens Wiklander ( 3534*32b31808SJens Wiklander "datagram of length %u too small to hold DTLS record header of length %u", 353511fa71b9SJerome Forissier (unsigned) len, 353611fa71b9SJerome Forissier (unsigned) (rec_hdr_len_len + rec_hdr_len_len))); 3537*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 353811fa71b9SJerome Forissier } 353911fa71b9SJerome Forissier 354011fa71b9SJerome Forissier /* 354111fa71b9SJerome Forissier * Parse and validate record content type 354211fa71b9SJerome Forissier */ 354311fa71b9SJerome Forissier 354411fa71b9SJerome Forissier rec->type = buf[rec_hdr_type_offset]; 354511fa71b9SJerome Forissier 354611fa71b9SJerome Forissier /* Check record content type */ 354711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 354811fa71b9SJerome Forissier rec->cid_len = 0; 354911fa71b9SJerome Forissier 355011fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 355111fa71b9SJerome Forissier ssl->conf->cid_len != 0 && 3552*32b31808SJens Wiklander rec->type == MBEDTLS_SSL_MSG_CID) { 355311fa71b9SJerome Forissier /* Shift pointers to account for record header including CID 355411fa71b9SJerome Forissier * struct { 3555*32b31808SJens Wiklander * ContentType outer_type = tls12_cid; 355611fa71b9SJerome Forissier * ProtocolVersion version; 355711fa71b9SJerome Forissier * uint16 epoch; 355811fa71b9SJerome Forissier * uint48 sequence_number; 355911fa71b9SJerome Forissier * opaque cid[cid_length]; // Additional field compared to 356011fa71b9SJerome Forissier * // default DTLS record format 356111fa71b9SJerome Forissier * uint16 length; 356211fa71b9SJerome Forissier * opaque enc_content[DTLSCiphertext.length]; 356311fa71b9SJerome Forissier * } DTLSCiphertext; 356411fa71b9SJerome Forissier */ 356511fa71b9SJerome Forissier 356611fa71b9SJerome Forissier /* So far, we only support static CID lengths 356711fa71b9SJerome Forissier * fixed in the configuration. */ 356811fa71b9SJerome Forissier rec_hdr_cid_len = ssl->conf->cid_len; 356911fa71b9SJerome Forissier rec_hdr_len_offset += rec_hdr_cid_len; 357011fa71b9SJerome Forissier 3571*32b31808SJens Wiklander if (len < rec_hdr_len_offset + rec_hdr_len_len) { 3572*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 3573*32b31808SJens Wiklander ( 3574*32b31808SJens Wiklander "datagram of length %u too small to hold DTLS record header including CID, length %u", 357511fa71b9SJerome Forissier (unsigned) len, 357611fa71b9SJerome Forissier (unsigned) (rec_hdr_len_offset + rec_hdr_len_len))); 3577*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 357811fa71b9SJerome Forissier } 357911fa71b9SJerome Forissier 358011fa71b9SJerome Forissier /* configured CID len is guaranteed at most 255, see 358111fa71b9SJerome Forissier * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */ 358211fa71b9SJerome Forissier rec->cid_len = (uint8_t) rec_hdr_cid_len; 358311fa71b9SJerome Forissier memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len); 3584*32b31808SJens Wiklander } else 358511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 358611fa71b9SJerome Forissier { 3587*32b31808SJens Wiklander if (ssl_check_record_type(rec->type)) { 358811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u", 358911fa71b9SJerome Forissier (unsigned) rec->type)); 3590*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 359111fa71b9SJerome Forissier } 359211fa71b9SJerome Forissier } 359311fa71b9SJerome Forissier 359411fa71b9SJerome Forissier /* 359511fa71b9SJerome Forissier * Parse and validate record version 359611fa71b9SJerome Forissier */ 359711fa71b9SJerome Forissier rec->ver[0] = buf[rec_hdr_version_offset + 0]; 359811fa71b9SJerome Forissier rec->ver[1] = buf[rec_hdr_version_offset + 1]; 3599*32b31808SJens Wiklander tls_version = mbedtls_ssl_read_version(buf + rec_hdr_version_offset, 3600*32b31808SJens Wiklander ssl->conf->transport); 360111fa71b9SJerome Forissier 3602*32b31808SJens Wiklander if (tls_version > ssl->conf->max_tls_version) { 3603*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u", 3604*32b31808SJens Wiklander (unsigned) tls_version, 3605*32b31808SJens Wiklander (unsigned) ssl->conf->max_tls_version)); 360611fa71b9SJerome Forissier 3607*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 360811fa71b9SJerome Forissier } 360911fa71b9SJerome Forissier /* 361011fa71b9SJerome Forissier * Parse/Copy record sequence number. 361111fa71b9SJerome Forissier */ 361211fa71b9SJerome Forissier 361311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3614*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 361511fa71b9SJerome Forissier /* Copy explicit record sequence number from input buffer. */ 361611fa71b9SJerome Forissier memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset, 361711fa71b9SJerome Forissier rec_hdr_ctr_len); 3618*32b31808SJens Wiklander } else 361911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 362011fa71b9SJerome Forissier { 362111fa71b9SJerome Forissier /* Copy implicit record sequence number from SSL context structure. */ 362211fa71b9SJerome Forissier memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len); 362311fa71b9SJerome Forissier } 362411fa71b9SJerome Forissier 362511fa71b9SJerome Forissier /* 362611fa71b9SJerome Forissier * Parse record length. 362711fa71b9SJerome Forissier */ 362811fa71b9SJerome Forissier 362911fa71b9SJerome Forissier rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len; 363011fa71b9SJerome Forissier rec->data_len = ((size_t) buf[rec_hdr_len_offset + 0] << 8) | 363111fa71b9SJerome Forissier ((size_t) buf[rec_hdr_len_offset + 1] << 0); 363211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset); 363311fa71b9SJerome Forissier 36347901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, " 3635*32b31808SJens Wiklander "version = [0x%x], msglen = %" MBEDTLS_PRINTF_SIZET, 3636*32b31808SJens Wiklander rec->type, (unsigned) tls_version, rec->data_len)); 363711fa71b9SJerome Forissier 363811fa71b9SJerome Forissier rec->buf = buf; 363911fa71b9SJerome Forissier rec->buf_len = rec->data_offset + rec->data_len; 364011fa71b9SJerome Forissier 3641*32b31808SJens Wiklander if (rec->data_len == 0) { 3642*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 3643*32b31808SJens Wiklander } 364411fa71b9SJerome Forissier 364511fa71b9SJerome Forissier /* 364611fa71b9SJerome Forissier * DTLS-related tests. 364711fa71b9SJerome Forissier * Check epoch before checking length constraint because 364811fa71b9SJerome Forissier * the latter varies with the epoch. E.g., if a ChangeCipherSpec 364911fa71b9SJerome Forissier * message gets duplicated before the corresponding Finished message, 365011fa71b9SJerome Forissier * the second ChangeCipherSpec should be discarded because it belongs 365111fa71b9SJerome Forissier * to an old epoch, but not because its length is shorter than 365211fa71b9SJerome Forissier * the minimum record length for packets using the new record transform. 365311fa71b9SJerome Forissier * Note that these two kinds of failures are handled differently, 365411fa71b9SJerome Forissier * as an unexpected record is silently skipped but an invalid 365511fa71b9SJerome Forissier * record leads to the entire datagram being dropped. 365611fa71b9SJerome Forissier */ 365711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3658*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 365911fa71b9SJerome Forissier rec_epoch = (rec->ctr[0] << 8) | rec->ctr[1]; 366011fa71b9SJerome Forissier 366111fa71b9SJerome Forissier /* Check that the datagram is large enough to contain a record 366211fa71b9SJerome Forissier * of the advertised length. */ 3663*32b31808SJens Wiklander if (len < rec->data_offset + rec->data_len) { 3664*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 3665*32b31808SJens Wiklander ( 3666*32b31808SJens Wiklander "Datagram of length %u too small to contain record of advertised length %u.", 366711fa71b9SJerome Forissier (unsigned) len, 366811fa71b9SJerome Forissier (unsigned) (rec->data_offset + rec->data_len))); 3669*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 367011fa71b9SJerome Forissier } 367111fa71b9SJerome Forissier 367211fa71b9SJerome Forissier /* Records from other, non-matching epochs are silently discarded. 367311fa71b9SJerome Forissier * (The case of same-port Client reconnects must be considered in 367411fa71b9SJerome Forissier * the caller). */ 3675*32b31808SJens Wiklander if (rec_epoch != ssl->in_epoch) { 367611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: " 36777901324dSJerome Forissier "expected %u, received %lu", 36787901324dSJerome Forissier ssl->in_epoch, (unsigned long) rec_epoch)); 367911fa71b9SJerome Forissier 368011fa71b9SJerome Forissier /* Records from the next epoch are considered for buffering 368111fa71b9SJerome Forissier * (concretely: early Finished messages). */ 3682*32b31808SJens Wiklander if (rec_epoch == (unsigned) ssl->in_epoch + 1) { 368311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering")); 3684*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE; 368511fa71b9SJerome Forissier } 368611fa71b9SJerome Forissier 3687*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 368811fa71b9SJerome Forissier } 368911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 369011fa71b9SJerome Forissier /* For records from the correct epoch, check whether their 369111fa71b9SJerome Forissier * sequence number has been seen before. */ 369211fa71b9SJerome Forissier else if (mbedtls_ssl_dtls_record_replay_check((mbedtls_ssl_context *) ssl, 3693*32b31808SJens Wiklander &rec->ctr[0]) != 0) { 369411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record")); 3695*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 369611fa71b9SJerome Forissier } 369711fa71b9SJerome Forissier #endif 369811fa71b9SJerome Forissier } 369911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 370011fa71b9SJerome Forissier 3701*32b31808SJens Wiklander return 0; 370211fa71b9SJerome Forissier } 370311fa71b9SJerome Forissier 370411fa71b9SJerome Forissier 370511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 3706039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 370711fa71b9SJerome Forissier static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl) 370811fa71b9SJerome Forissier { 370911fa71b9SJerome Forissier unsigned int rec_epoch = (ssl->in_ctr[0] << 8) | ssl->in_ctr[1]; 371011fa71b9SJerome Forissier 371111fa71b9SJerome Forissier /* 371211fa71b9SJerome Forissier * Check for an epoch 0 ClientHello. We can't use in_msg here to 371311fa71b9SJerome Forissier * access the first byte of record content (handshake type), as we 371411fa71b9SJerome Forissier * have an active transform (possibly iv_len != 0), so use the 371511fa71b9SJerome Forissier * fact that the record header len is 13 instead. 371611fa71b9SJerome Forissier */ 371711fa71b9SJerome Forissier if (rec_epoch == 0 && 371811fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 3719*32b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 1 && 372011fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 372111fa71b9SJerome Forissier ssl->in_left > 13 && 3722*32b31808SJens Wiklander ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) { 372311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect " 372411fa71b9SJerome Forissier "from the same port")); 3725*32b31808SJens Wiklander return ssl_handle_possible_reconnect(ssl); 372611fa71b9SJerome Forissier } 372711fa71b9SJerome Forissier 3728*32b31808SJens Wiklander return 0; 372911fa71b9SJerome Forissier } 373011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 373111fa71b9SJerome Forissier 373211fa71b9SJerome Forissier /* 373311fa71b9SJerome Forissier * If applicable, decrypt record content 373411fa71b9SJerome Forissier */ 3735039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 373611fa71b9SJerome Forissier static int ssl_prepare_record_content(mbedtls_ssl_context *ssl, 373711fa71b9SJerome Forissier mbedtls_record *rec) 373811fa71b9SJerome Forissier { 373911fa71b9SJerome Forissier int ret, done = 0; 374011fa71b9SJerome Forissier 374111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input record from network", 374211fa71b9SJerome Forissier rec->buf, rec->buf_len); 374311fa71b9SJerome Forissier 3744*32b31808SJens Wiklander /* 3745*32b31808SJens Wiklander * In TLS 1.3, always treat ChangeCipherSpec records 3746*32b31808SJens Wiklander * as unencrypted. The only thing we do with them is 3747*32b31808SJens Wiklander * check the length and content and ignore them. 3748*32b31808SJens Wiklander */ 3749*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 3750*32b31808SJens Wiklander if (ssl->transform_in != NULL && 3751*32b31808SJens Wiklander ssl->transform_in->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 3752*32b31808SJens Wiklander if (rec->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { 375311fa71b9SJerome Forissier done = 1; 375411fa71b9SJerome Forissier } 3755*32b31808SJens Wiklander } 3756*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 3757*32b31808SJens Wiklander 3758*32b31808SJens Wiklander if (!done && ssl->transform_in != NULL) { 375911fa71b9SJerome Forissier unsigned char const old_msg_type = rec->type; 376011fa71b9SJerome Forissier 376111fa71b9SJerome Forissier if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, 3762*32b31808SJens Wiklander rec)) != 0) { 376311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret); 376411fa71b9SJerome Forissier 376511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 376611fa71b9SJerome Forissier if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && 376711fa71b9SJerome Forissier ssl->conf->ignore_unexpected_cid 3768*32b31808SJens Wiklander == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) { 376911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID")); 377011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 377111fa71b9SJerome Forissier } 377211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 377311fa71b9SJerome Forissier 3774*32b31808SJens Wiklander return ret; 377511fa71b9SJerome Forissier } 377611fa71b9SJerome Forissier 3777*32b31808SJens Wiklander if (old_msg_type != rec->type) { 377811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d", 377911fa71b9SJerome Forissier old_msg_type, rec->type)); 378011fa71b9SJerome Forissier } 378111fa71b9SJerome Forissier 378211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt", 378311fa71b9SJerome Forissier rec->buf + rec->data_offset, rec->data_len); 378411fa71b9SJerome Forissier 378511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 378611fa71b9SJerome Forissier /* We have already checked the record content type 378711fa71b9SJerome Forissier * in ssl_parse_record_header(), failing or silently 378811fa71b9SJerome Forissier * dropping the record in the case of an unknown type. 378911fa71b9SJerome Forissier * 379011fa71b9SJerome Forissier * Since with the use of CIDs, the record content type 379111fa71b9SJerome Forissier * might change during decryption, re-check the record 379211fa71b9SJerome Forissier * content type, but treat a failure as fatal this time. */ 3793*32b31808SJens Wiklander if (ssl_check_record_type(rec->type)) { 379411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type")); 3795*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 379611fa71b9SJerome Forissier } 379711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 379811fa71b9SJerome Forissier 3799*32b31808SJens Wiklander if (rec->data_len == 0) { 380011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 3801*32b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2 3802*32b31808SJens Wiklander && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) { 380311fa71b9SJerome Forissier /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ 380411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid zero-length message type: %d", ssl->in_msgtype)); 3805*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 380611fa71b9SJerome Forissier } 380711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 380811fa71b9SJerome Forissier 380911fa71b9SJerome Forissier ssl->nb_zero++; 381011fa71b9SJerome Forissier 381111fa71b9SJerome Forissier /* 381211fa71b9SJerome Forissier * Three or more empty messages may be a DoS attack 381311fa71b9SJerome Forissier * (excessive CPU consumption). 381411fa71b9SJerome Forissier */ 3815*32b31808SJens Wiklander if (ssl->nb_zero > 3) { 381611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty " 381711fa71b9SJerome Forissier "messages, possible DoS attack")); 381811fa71b9SJerome Forissier /* Treat the records as if they were not properly authenticated, 381911fa71b9SJerome Forissier * thereby failing the connection if we see more than allowed 382011fa71b9SJerome Forissier * by the configured bad MAC threshold. */ 3821*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 382211fa71b9SJerome Forissier } 3823*32b31808SJens Wiklander } else { 382411fa71b9SJerome Forissier ssl->nb_zero = 0; 3825*32b31808SJens Wiklander } 382611fa71b9SJerome Forissier 382711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3828*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 382911fa71b9SJerome Forissier ; /* in_ctr read from peer, not maintained internally */ 3830*32b31808SJens Wiklander } else 383111fa71b9SJerome Forissier #endif 383211fa71b9SJerome Forissier { 383311fa71b9SJerome Forissier unsigned i; 3834*32b31808SJens Wiklander for (i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 3835*32b31808SJens Wiklander i > mbedtls_ssl_ep_len(ssl); i--) { 3836*32b31808SJens Wiklander if (++ssl->in_ctr[i - 1] != 0) { 383711fa71b9SJerome Forissier break; 3838*32b31808SJens Wiklander } 3839*32b31808SJens Wiklander } 384011fa71b9SJerome Forissier 384111fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */ 3842*32b31808SJens Wiklander if (i == mbedtls_ssl_ep_len(ssl)) { 384311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("incoming message counter would wrap")); 3844*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; 384511fa71b9SJerome Forissier } 384611fa71b9SJerome Forissier } 384711fa71b9SJerome Forissier 384811fa71b9SJerome Forissier } 384911fa71b9SJerome Forissier 385011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 3851*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 385211fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_update(ssl); 385311fa71b9SJerome Forissier } 385411fa71b9SJerome Forissier #endif 385511fa71b9SJerome Forissier 385611fa71b9SJerome Forissier /* Check actual (decrypted) record content length against 385711fa71b9SJerome Forissier * configured maximum. */ 3858*32b31808SJens Wiklander if (rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN) { 385911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length")); 3860*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 386111fa71b9SJerome Forissier } 386211fa71b9SJerome Forissier 3863*32b31808SJens Wiklander return 0; 386411fa71b9SJerome Forissier } 386511fa71b9SJerome Forissier 386611fa71b9SJerome Forissier /* 386711fa71b9SJerome Forissier * Read a record. 386811fa71b9SJerome Forissier * 386911fa71b9SJerome Forissier * Silently ignore non-fatal alert (and for DTLS, invalid records as well, 387011fa71b9SJerome Forissier * RFC 6347 4.1.2.7) and continue reading until a valid record is found. 387111fa71b9SJerome Forissier * 387211fa71b9SJerome Forissier */ 387311fa71b9SJerome Forissier 387411fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */ 3875039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 387611fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl); 3877039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 387811fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl); 3879039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 388011fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl); 388111fa71b9SJerome Forissier 388211fa71b9SJerome Forissier int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl, 388311fa71b9SJerome Forissier unsigned update_hs_digest) 388411fa71b9SJerome Forissier { 388511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 388611fa71b9SJerome Forissier 388711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record")); 388811fa71b9SJerome Forissier 3889*32b31808SJens Wiklander if (ssl->keep_current_message == 0) { 389011fa71b9SJerome Forissier do { 389111fa71b9SJerome Forissier 389211fa71b9SJerome Forissier ret = ssl_consume_current_message(ssl); 3893*32b31808SJens Wiklander if (ret != 0) { 3894*32b31808SJens Wiklander return ret; 3895*32b31808SJens Wiklander } 389611fa71b9SJerome Forissier 3897*32b31808SJens Wiklander if (ssl_record_is_in_progress(ssl) == 0) { 3898*32b31808SJens Wiklander int dtls_have_buffered = 0; 389911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 390011fa71b9SJerome Forissier 390111fa71b9SJerome Forissier /* We only check for buffered messages if the 390211fa71b9SJerome Forissier * current datagram is fully consumed. */ 390311fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 3904*32b31808SJens Wiklander ssl_next_record_is_in_datagram(ssl) == 0) { 3905*32b31808SJens Wiklander if (ssl_load_buffered_message(ssl) == 0) { 3906*32b31808SJens Wiklander dtls_have_buffered = 1; 3907*32b31808SJens Wiklander } 390811fa71b9SJerome Forissier } 390911fa71b9SJerome Forissier 391011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 3911*32b31808SJens Wiklander if (dtls_have_buffered == 0) { 391211fa71b9SJerome Forissier ret = ssl_get_next_record(ssl); 3913*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) { 391411fa71b9SJerome Forissier continue; 3915*32b31808SJens Wiklander } 391611fa71b9SJerome Forissier 3917*32b31808SJens Wiklander if (ret != 0) { 391811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret); 3919*32b31808SJens Wiklander return ret; 392011fa71b9SJerome Forissier } 392111fa71b9SJerome Forissier } 392211fa71b9SJerome Forissier } 392311fa71b9SJerome Forissier 392411fa71b9SJerome Forissier ret = mbedtls_ssl_handle_message_type(ssl); 392511fa71b9SJerome Forissier 392611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3927*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { 392811fa71b9SJerome Forissier /* Buffer future message */ 392911fa71b9SJerome Forissier ret = ssl_buffer_message(ssl); 3930*32b31808SJens Wiklander if (ret != 0) { 3931*32b31808SJens Wiklander return ret; 3932*32b31808SJens Wiklander } 393311fa71b9SJerome Forissier 393411fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 393511fa71b9SJerome Forissier } 393611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 393711fa71b9SJerome Forissier 393811fa71b9SJerome Forissier } while (MBEDTLS_ERR_SSL_NON_FATAL == ret || 393911fa71b9SJerome Forissier MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret); 394011fa71b9SJerome Forissier 3941*32b31808SJens Wiklander if (0 != ret) { 394211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret); 3943*32b31808SJens Wiklander return ret; 394411fa71b9SJerome Forissier } 394511fa71b9SJerome Forissier 394611fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 3947*32b31808SJens Wiklander update_hs_digest == 1) { 3948*32b31808SJens Wiklander ret = mbedtls_ssl_update_handshake_status(ssl); 3949*32b31808SJens Wiklander if (0 != ret) { 3950*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); 3951*32b31808SJens Wiklander return ret; 395211fa71b9SJerome Forissier } 395311fa71b9SJerome Forissier } 3954*32b31808SJens Wiklander } else { 395511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message")); 395611fa71b9SJerome Forissier ssl->keep_current_message = 0; 395711fa71b9SJerome Forissier } 395811fa71b9SJerome Forissier 395911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record")); 396011fa71b9SJerome Forissier 3961*32b31808SJens Wiklander return 0; 396211fa71b9SJerome Forissier } 396311fa71b9SJerome Forissier 396411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 3965039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 396611fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl) 396711fa71b9SJerome Forissier { 3968*32b31808SJens Wiklander if (ssl->in_left > ssl->next_record_offset) { 3969*32b31808SJens Wiklander return 1; 3970*32b31808SJens Wiklander } 397111fa71b9SJerome Forissier 3972*32b31808SJens Wiklander return 0; 397311fa71b9SJerome Forissier } 397411fa71b9SJerome Forissier 3975039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 397611fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl) 397711fa71b9SJerome Forissier { 397811fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 397911fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 398011fa71b9SJerome Forissier int ret = 0; 398111fa71b9SJerome Forissier 3982*32b31808SJens Wiklander if (hs == NULL) { 3983*32b31808SJens Wiklander return -1; 3984*32b31808SJens Wiklander } 398511fa71b9SJerome Forissier 3986*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_message")); 398711fa71b9SJerome Forissier 398811fa71b9SJerome Forissier if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || 3989*32b31808SJens Wiklander ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) { 399011fa71b9SJerome Forissier /* Check if we have seen a ChangeCipherSpec before. 399111fa71b9SJerome Forissier * If yes, synthesize a CCS record. */ 3992*32b31808SJens Wiklander if (!hs->buffering.seen_ccs) { 399311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight")); 399411fa71b9SJerome Forissier ret = -1; 399511fa71b9SJerome Forissier goto exit; 399611fa71b9SJerome Forissier } 399711fa71b9SJerome Forissier 399811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message")); 399911fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 400011fa71b9SJerome Forissier ssl->in_msglen = 1; 400111fa71b9SJerome Forissier ssl->in_msg[0] = 1; 400211fa71b9SJerome Forissier 400311fa71b9SJerome Forissier /* As long as they are equal, the exact value doesn't matter. */ 400411fa71b9SJerome Forissier ssl->in_left = 0; 400511fa71b9SJerome Forissier ssl->next_record_offset = 0; 400611fa71b9SJerome Forissier 400711fa71b9SJerome Forissier hs->buffering.seen_ccs = 0; 400811fa71b9SJerome Forissier goto exit; 400911fa71b9SJerome Forissier } 401011fa71b9SJerome Forissier 401111fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C) 401211fa71b9SJerome Forissier /* Debug only */ 401311fa71b9SJerome Forissier { 401411fa71b9SJerome Forissier unsigned offset; 4015*32b31808SJens Wiklander for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { 401611fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[offset]; 4017*32b31808SJens Wiklander if (hs_buf->is_valid == 1) { 401811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Future message with sequence number %u %s buffered.", 401911fa71b9SJerome Forissier hs->in_msg_seq + offset, 402011fa71b9SJerome Forissier hs_buf->is_complete ? "fully" : "partially")); 402111fa71b9SJerome Forissier } 402211fa71b9SJerome Forissier } 402311fa71b9SJerome Forissier } 402411fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */ 402511fa71b9SJerome Forissier 402611fa71b9SJerome Forissier /* Check if we have buffered and/or fully reassembled the 402711fa71b9SJerome Forissier * next handshake message. */ 402811fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[0]; 4029*32b31808SJens Wiklander if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) { 403011fa71b9SJerome Forissier /* Synthesize a record containing the buffered HS message. */ 403111fa71b9SJerome Forissier size_t msg_len = (hs_buf->data[1] << 16) | 403211fa71b9SJerome Forissier (hs_buf->data[2] << 8) | 403311fa71b9SJerome Forissier hs_buf->data[3]; 403411fa71b9SJerome Forissier 403511fa71b9SJerome Forissier /* Double-check that we haven't accidentally buffered 403611fa71b9SJerome Forissier * a message that doesn't fit into the input buffer. */ 4037*32b31808SJens Wiklander if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) { 403811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4039*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 404011fa71b9SJerome Forissier } 404111fa71b9SJerome Forissier 404211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message has been buffered - load")); 404311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)", 404411fa71b9SJerome Forissier hs_buf->data, msg_len + 12); 404511fa71b9SJerome Forissier 404611fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 404711fa71b9SJerome Forissier ssl->in_hslen = msg_len + 12; 404811fa71b9SJerome Forissier ssl->in_msglen = msg_len + 12; 404911fa71b9SJerome Forissier memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen); 405011fa71b9SJerome Forissier 405111fa71b9SJerome Forissier ret = 0; 405211fa71b9SJerome Forissier goto exit; 4053*32b31808SJens Wiklander } else { 405411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially bufffered", 405511fa71b9SJerome Forissier hs->in_msg_seq)); 405611fa71b9SJerome Forissier } 405711fa71b9SJerome Forissier 405811fa71b9SJerome Forissier ret = -1; 405911fa71b9SJerome Forissier 406011fa71b9SJerome Forissier exit: 406111fa71b9SJerome Forissier 406211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message")); 4063*32b31808SJens Wiklander return ret; 406411fa71b9SJerome Forissier } 406511fa71b9SJerome Forissier 4066039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 406711fa71b9SJerome Forissier static int ssl_buffer_make_space(mbedtls_ssl_context *ssl, 406811fa71b9SJerome Forissier size_t desired) 406911fa71b9SJerome Forissier { 407011fa71b9SJerome Forissier int offset; 407111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 407211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Attempt to free buffered messages to have %u bytes available", 407311fa71b9SJerome Forissier (unsigned) desired)); 407411fa71b9SJerome Forissier 407511fa71b9SJerome Forissier /* Get rid of future records epoch first, if such exist. */ 407611fa71b9SJerome Forissier ssl_free_buffered_record(ssl); 407711fa71b9SJerome Forissier 407811fa71b9SJerome Forissier /* Check if we have enough space available now. */ 407911fa71b9SJerome Forissier if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING - 4080*32b31808SJens Wiklander hs->buffering.total_bytes_buffered)) { 408111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing future epoch record")); 4082*32b31808SJens Wiklander return 0; 408311fa71b9SJerome Forissier } 408411fa71b9SJerome Forissier 408511fa71b9SJerome Forissier /* We don't have enough space to buffer the next expected handshake 408611fa71b9SJerome Forissier * message. Remove buffers used for future messages to gain space, 408711fa71b9SJerome Forissier * starting with the most distant one. */ 408811fa71b9SJerome Forissier for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; 4089*32b31808SJens Wiklander offset >= 0; offset--) { 4090*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 4091*32b31808SJens Wiklander ( 4092*32b31808SJens Wiklander "Free buffering slot %d to make space for reassembly of next handshake message", 409311fa71b9SJerome Forissier offset)); 409411fa71b9SJerome Forissier 409511fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, (uint8_t) offset); 409611fa71b9SJerome Forissier 409711fa71b9SJerome Forissier /* Check if we have enough space available now. */ 409811fa71b9SJerome Forissier if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING - 4099*32b31808SJens Wiklander hs->buffering.total_bytes_buffered)) { 410011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing buffered HS messages")); 4101*32b31808SJens Wiklander return 0; 410211fa71b9SJerome Forissier } 410311fa71b9SJerome Forissier } 410411fa71b9SJerome Forissier 4105*32b31808SJens Wiklander return -1; 410611fa71b9SJerome Forissier } 410711fa71b9SJerome Forissier 4108039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 410911fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl) 411011fa71b9SJerome Forissier { 411111fa71b9SJerome Forissier int ret = 0; 411211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 411311fa71b9SJerome Forissier 4114*32b31808SJens Wiklander if (hs == NULL) { 4115*32b31808SJens Wiklander return 0; 4116*32b31808SJens Wiklander } 411711fa71b9SJerome Forissier 411811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message")); 411911fa71b9SJerome Forissier 4120*32b31808SJens Wiklander switch (ssl->in_msgtype) { 412111fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: 412211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message")); 412311fa71b9SJerome Forissier 412411fa71b9SJerome Forissier hs->buffering.seen_ccs = 1; 412511fa71b9SJerome Forissier break; 412611fa71b9SJerome Forissier 412711fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_HANDSHAKE: 412811fa71b9SJerome Forissier { 412911fa71b9SJerome Forissier unsigned recv_msg_seq_offset; 413011fa71b9SJerome Forissier unsigned recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5]; 413111fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 413211fa71b9SJerome Forissier size_t msg_len = ssl->in_hslen - 12; 413311fa71b9SJerome Forissier 413411fa71b9SJerome Forissier /* We should never receive an old handshake 413511fa71b9SJerome Forissier * message - double-check nonetheless. */ 4136*32b31808SJens Wiklander if (recv_msg_seq < ssl->handshake->in_msg_seq) { 413711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4138*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 413911fa71b9SJerome Forissier } 414011fa71b9SJerome Forissier 414111fa71b9SJerome Forissier recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; 4142*32b31808SJens Wiklander if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) { 414311fa71b9SJerome Forissier /* Silently ignore -- message too far in the future */ 414411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, 414511fa71b9SJerome Forissier ("Ignore future HS message with sequence number %u, " 414611fa71b9SJerome Forissier "buffering window %u - %u", 414711fa71b9SJerome Forissier recv_msg_seq, ssl->handshake->in_msg_seq, 4148*32b31808SJens Wiklander ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 4149*32b31808SJens Wiklander 1)); 415011fa71b9SJerome Forissier 415111fa71b9SJerome Forissier goto exit; 415211fa71b9SJerome Forissier } 415311fa71b9SJerome Forissier 415411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering HS message with sequence number %u, offset %u ", 415511fa71b9SJerome Forissier recv_msg_seq, recv_msg_seq_offset)); 415611fa71b9SJerome Forissier 415711fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[recv_msg_seq_offset]; 415811fa71b9SJerome Forissier 415911fa71b9SJerome Forissier /* Check if the buffering for this seq nr has already commenced. */ 4160*32b31808SJens Wiklander if (!hs_buf->is_valid) { 416111fa71b9SJerome Forissier size_t reassembly_buf_sz; 416211fa71b9SJerome Forissier 416311fa71b9SJerome Forissier hs_buf->is_fragmented = 416411fa71b9SJerome Forissier (ssl_hs_is_proper_fragment(ssl) == 1); 416511fa71b9SJerome Forissier 416611fa71b9SJerome Forissier /* We copy the message back into the input buffer 416711fa71b9SJerome Forissier * after reassembly, so check that it's not too large. 416811fa71b9SJerome Forissier * This is an implementation-specific limitation 416911fa71b9SJerome Forissier * and not one from the standard, hence it is not 417011fa71b9SJerome Forissier * checked in ssl_check_hs_header(). */ 4171*32b31808SJens Wiklander if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) { 417211fa71b9SJerome Forissier /* Ignore message */ 417311fa71b9SJerome Forissier goto exit; 417411fa71b9SJerome Forissier } 417511fa71b9SJerome Forissier 417611fa71b9SJerome Forissier /* Check if we have enough space to buffer the message. */ 417711fa71b9SJerome Forissier if (hs->buffering.total_bytes_buffered > 4178*32b31808SJens Wiklander MBEDTLS_SSL_DTLS_MAX_BUFFERING) { 417911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4180*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 418111fa71b9SJerome Forissier } 418211fa71b9SJerome Forissier 418311fa71b9SJerome Forissier reassembly_buf_sz = ssl_get_reassembly_buffer_size(msg_len, 418411fa71b9SJerome Forissier hs_buf->is_fragmented); 418511fa71b9SJerome Forissier 418611fa71b9SJerome Forissier if (reassembly_buf_sz > (MBEDTLS_SSL_DTLS_MAX_BUFFERING - 4187*32b31808SJens Wiklander hs->buffering.total_bytes_buffered)) { 4188*32b31808SJens Wiklander if (recv_msg_seq_offset > 0) { 418911fa71b9SJerome Forissier /* If we can't buffer a future message because 419011fa71b9SJerome Forissier * of space limitations -- ignore. */ 4191*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 4192*32b31808SJens Wiklander ("Buffering of future message of size %" 4193*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 4194*32b31808SJens Wiklander " would exceed the compile-time limit %" 4195*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 41967901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 41977901324dSJerome Forissier " bytes buffered) -- ignore\n", 41987901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 41997901324dSJerome Forissier hs->buffering.total_bytes_buffered)); 420011fa71b9SJerome Forissier goto exit; 4201*32b31808SJens Wiklander } else { 4202*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 4203*32b31808SJens Wiklander ("Buffering of future message of size %" 4204*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 4205*32b31808SJens Wiklander " would exceed the compile-time limit %" 4206*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 42077901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 42087901324dSJerome Forissier " bytes buffered) -- attempt to make space by freeing buffered future messages\n", 42097901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 42107901324dSJerome Forissier hs->buffering.total_bytes_buffered)); 421111fa71b9SJerome Forissier } 421211fa71b9SJerome Forissier 4213*32b31808SJens Wiklander if (ssl_buffer_make_space(ssl, reassembly_buf_sz) != 0) { 4214*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 4215*32b31808SJens Wiklander ("Reassembly of next message of size %" 4216*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 4217*32b31808SJens Wiklander " (%" MBEDTLS_PRINTF_SIZET 4218*32b31808SJens Wiklander " with bitmap) would exceed" 4219*32b31808SJens Wiklander " the compile-time limit %" 4220*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET 42217901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 42227901324dSJerome Forissier " bytes buffered) -- fail\n", 42237901324dSJerome Forissier msg_len, 42247901324dSJerome Forissier reassembly_buf_sz, 42257901324dSJerome Forissier (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 42267901324dSJerome Forissier hs->buffering.total_bytes_buffered)); 422711fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 422811fa71b9SJerome Forissier goto exit; 422911fa71b9SJerome Forissier } 423011fa71b9SJerome Forissier } 423111fa71b9SJerome Forissier 4232*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, 4233*32b31808SJens Wiklander ("initialize reassembly, total length = %" 4234*32b31808SJens Wiklander MBEDTLS_PRINTF_SIZET, 423511fa71b9SJerome Forissier msg_len)); 423611fa71b9SJerome Forissier 423711fa71b9SJerome Forissier hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz); 4238*32b31808SJens Wiklander if (hs_buf->data == NULL) { 423911fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 424011fa71b9SJerome Forissier goto exit; 424111fa71b9SJerome Forissier } 424211fa71b9SJerome Forissier hs_buf->data_len = reassembly_buf_sz; 424311fa71b9SJerome Forissier 424411fa71b9SJerome Forissier /* Prepare final header: copy msg_type, length and message_seq, 424511fa71b9SJerome Forissier * then add standardised fragment_offset and fragment_length */ 424611fa71b9SJerome Forissier memcpy(hs_buf->data, ssl->in_msg, 6); 424711fa71b9SJerome Forissier memset(hs_buf->data + 6, 0, 3); 424811fa71b9SJerome Forissier memcpy(hs_buf->data + 9, hs_buf->data + 1, 3); 424911fa71b9SJerome Forissier 425011fa71b9SJerome Forissier hs_buf->is_valid = 1; 425111fa71b9SJerome Forissier 425211fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += reassembly_buf_sz; 4253*32b31808SJens Wiklander } else { 425411fa71b9SJerome Forissier /* Make sure msg_type and length are consistent */ 4255*32b31808SJens Wiklander if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) { 425611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Fragment header mismatch - ignore")); 425711fa71b9SJerome Forissier /* Ignore */ 425811fa71b9SJerome Forissier goto exit; 425911fa71b9SJerome Forissier } 426011fa71b9SJerome Forissier } 426111fa71b9SJerome Forissier 4262*32b31808SJens Wiklander if (!hs_buf->is_complete) { 426311fa71b9SJerome Forissier size_t frag_len, frag_off; 426411fa71b9SJerome Forissier unsigned char * const msg = hs_buf->data + 12; 426511fa71b9SJerome Forissier 426611fa71b9SJerome Forissier /* 426711fa71b9SJerome Forissier * Check and copy current fragment 426811fa71b9SJerome Forissier */ 426911fa71b9SJerome Forissier 427011fa71b9SJerome Forissier /* Validation of header fields already done in 427111fa71b9SJerome Forissier * mbedtls_ssl_prepare_handshake_record(). */ 427211fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off(ssl); 427311fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len(ssl); 427411fa71b9SJerome Forissier 42757901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET 42767901324dSJerome Forissier ", length = %" MBEDTLS_PRINTF_SIZET, 427711fa71b9SJerome Forissier frag_off, frag_len)); 427811fa71b9SJerome Forissier memcpy(msg + frag_off, ssl->in_msg + 12, frag_len); 427911fa71b9SJerome Forissier 4280*32b31808SJens Wiklander if (hs_buf->is_fragmented) { 428111fa71b9SJerome Forissier unsigned char * const bitmask = msg + msg_len; 428211fa71b9SJerome Forissier ssl_bitmask_set(bitmask, frag_off, frag_len); 428311fa71b9SJerome Forissier hs_buf->is_complete = (ssl_bitmask_check(bitmask, 428411fa71b9SJerome Forissier msg_len) == 0); 4285*32b31808SJens Wiklander } else { 428611fa71b9SJerome Forissier hs_buf->is_complete = 1; 428711fa71b9SJerome Forissier } 428811fa71b9SJerome Forissier 428911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("message %scomplete", 429011fa71b9SJerome Forissier hs_buf->is_complete ? "" : "not yet ")); 429111fa71b9SJerome Forissier } 429211fa71b9SJerome Forissier 429311fa71b9SJerome Forissier break; 429411fa71b9SJerome Forissier } 429511fa71b9SJerome Forissier 429611fa71b9SJerome Forissier default: 429711fa71b9SJerome Forissier /* We don't buffer other types of messages. */ 429811fa71b9SJerome Forissier break; 429911fa71b9SJerome Forissier } 430011fa71b9SJerome Forissier 430111fa71b9SJerome Forissier exit: 430211fa71b9SJerome Forissier 430311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message")); 4304*32b31808SJens Wiklander return ret; 430511fa71b9SJerome Forissier } 430611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 430711fa71b9SJerome Forissier 4308039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 430911fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl) 431011fa71b9SJerome Forissier { 431111fa71b9SJerome Forissier /* 431211fa71b9SJerome Forissier * Consume last content-layer message and potentially 431311fa71b9SJerome Forissier * update in_msglen which keeps track of the contents' 431411fa71b9SJerome Forissier * consumption state. 431511fa71b9SJerome Forissier * 431611fa71b9SJerome Forissier * (1) Handshake messages: 431711fa71b9SJerome Forissier * Remove last handshake message, move content 431811fa71b9SJerome Forissier * and adapt in_msglen. 431911fa71b9SJerome Forissier * 432011fa71b9SJerome Forissier * (2) Alert messages: 432111fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 432211fa71b9SJerome Forissier * 432311fa71b9SJerome Forissier * (3) Change cipher spec: 432411fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 432511fa71b9SJerome Forissier * 432611fa71b9SJerome Forissier * (4) Application data: 432711fa71b9SJerome Forissier * Don't do anything - the record layer provides 432811fa71b9SJerome Forissier * the application data as a stream transport 432911fa71b9SJerome Forissier * and consumes through mbedtls_ssl_read only. 433011fa71b9SJerome Forissier * 433111fa71b9SJerome Forissier */ 433211fa71b9SJerome Forissier 433311fa71b9SJerome Forissier /* Case (1): Handshake messages */ 4334*32b31808SJens Wiklander if (ssl->in_hslen != 0) { 433511fa71b9SJerome Forissier /* Hard assertion to be sure that no application data 433611fa71b9SJerome Forissier * is in flight, as corrupting ssl->in_msglen during 433711fa71b9SJerome Forissier * ssl->in_offt != NULL is fatal. */ 4338*32b31808SJens Wiklander if (ssl->in_offt != NULL) { 433911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4340*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 434111fa71b9SJerome Forissier } 434211fa71b9SJerome Forissier 434311fa71b9SJerome Forissier /* 434411fa71b9SJerome Forissier * Get next Handshake message in the current record 434511fa71b9SJerome Forissier */ 434611fa71b9SJerome Forissier 434711fa71b9SJerome Forissier /* Notes: 434811fa71b9SJerome Forissier * (1) in_hslen is not necessarily the size of the 434911fa71b9SJerome Forissier * current handshake content: If DTLS handshake 435011fa71b9SJerome Forissier * fragmentation is used, that's the fragment 435111fa71b9SJerome Forissier * size instead. Using the total handshake message 435211fa71b9SJerome Forissier * size here is faulty and should be changed at 435311fa71b9SJerome Forissier * some point. 435411fa71b9SJerome Forissier * (2) While it doesn't seem to cause problems, one 435511fa71b9SJerome Forissier * has to be very careful not to assume that in_hslen 435611fa71b9SJerome Forissier * is always <= in_msglen in a sensible communication. 435711fa71b9SJerome Forissier * Again, it's wrong for DTLS handshake fragmentation. 435811fa71b9SJerome Forissier * The following check is therefore mandatory, and 435911fa71b9SJerome Forissier * should not be treated as a silently corrected assertion. 436011fa71b9SJerome Forissier * Additionally, ssl->in_hslen might be arbitrarily out of 436111fa71b9SJerome Forissier * bounds after handling a DTLS message with an unexpected 436211fa71b9SJerome Forissier * sequence number, see mbedtls_ssl_prepare_handshake_record. 436311fa71b9SJerome Forissier */ 4364*32b31808SJens Wiklander if (ssl->in_hslen < ssl->in_msglen) { 436511fa71b9SJerome Forissier ssl->in_msglen -= ssl->in_hslen; 436611fa71b9SJerome Forissier memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen, 436711fa71b9SJerome Forissier ssl->in_msglen); 436811fa71b9SJerome Forissier 436911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record", 437011fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen); 4371*32b31808SJens Wiklander } else { 437211fa71b9SJerome Forissier ssl->in_msglen = 0; 437311fa71b9SJerome Forissier } 437411fa71b9SJerome Forissier 437511fa71b9SJerome Forissier ssl->in_hslen = 0; 437611fa71b9SJerome Forissier } 437711fa71b9SJerome Forissier /* Case (4): Application data */ 4378*32b31808SJens Wiklander else if (ssl->in_offt != NULL) { 4379*32b31808SJens Wiklander return 0; 438011fa71b9SJerome Forissier } 438111fa71b9SJerome Forissier /* Everything else (CCS & Alerts) */ 4382*32b31808SJens Wiklander else { 438311fa71b9SJerome Forissier ssl->in_msglen = 0; 438411fa71b9SJerome Forissier } 438511fa71b9SJerome Forissier 4386*32b31808SJens Wiklander return 0; 438711fa71b9SJerome Forissier } 438811fa71b9SJerome Forissier 4389039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 439011fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl) 439111fa71b9SJerome Forissier { 4392*32b31808SJens Wiklander if (ssl->in_msglen > 0) { 4393*32b31808SJens Wiklander return 1; 4394*32b31808SJens Wiklander } 439511fa71b9SJerome Forissier 4396*32b31808SJens Wiklander return 0; 439711fa71b9SJerome Forissier } 439811fa71b9SJerome Forissier 439911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 440011fa71b9SJerome Forissier 440111fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl) 440211fa71b9SJerome Forissier { 440311fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 4404*32b31808SJens Wiklander if (hs == NULL) { 440511fa71b9SJerome Forissier return; 4406*32b31808SJens Wiklander } 440711fa71b9SJerome Forissier 4408*32b31808SJens Wiklander if (hs->buffering.future_record.data != NULL) { 440911fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= 441011fa71b9SJerome Forissier hs->buffering.future_record.len; 441111fa71b9SJerome Forissier 441211fa71b9SJerome Forissier mbedtls_free(hs->buffering.future_record.data); 441311fa71b9SJerome Forissier hs->buffering.future_record.data = NULL; 441411fa71b9SJerome Forissier } 441511fa71b9SJerome Forissier } 441611fa71b9SJerome Forissier 4417039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 441811fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl) 441911fa71b9SJerome Forissier { 442011fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 442111fa71b9SJerome Forissier unsigned char *rec; 442211fa71b9SJerome Forissier size_t rec_len; 442311fa71b9SJerome Forissier unsigned rec_epoch; 442411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 442511fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 442611fa71b9SJerome Forissier #else 442711fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 442811fa71b9SJerome Forissier #endif 4429*32b31808SJens Wiklander if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 4430*32b31808SJens Wiklander return 0; 4431*32b31808SJens Wiklander } 443211fa71b9SJerome Forissier 4433*32b31808SJens Wiklander if (hs == NULL) { 4434*32b31808SJens Wiklander return 0; 4435*32b31808SJens Wiklander } 443611fa71b9SJerome Forissier 443711fa71b9SJerome Forissier rec = hs->buffering.future_record.data; 443811fa71b9SJerome Forissier rec_len = hs->buffering.future_record.len; 443911fa71b9SJerome Forissier rec_epoch = hs->buffering.future_record.epoch; 444011fa71b9SJerome Forissier 4441*32b31808SJens Wiklander if (rec == NULL) { 4442*32b31808SJens Wiklander return 0; 4443*32b31808SJens Wiklander } 444411fa71b9SJerome Forissier 444511fa71b9SJerome Forissier /* Only consider loading future records if the 444611fa71b9SJerome Forissier * input buffer is empty. */ 4447*32b31808SJens Wiklander if (ssl_next_record_is_in_datagram(ssl) == 1) { 4448*32b31808SJens Wiklander return 0; 4449*32b31808SJens Wiklander } 445011fa71b9SJerome Forissier 445111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record")); 445211fa71b9SJerome Forissier 4453*32b31808SJens Wiklander if (rec_epoch != ssl->in_epoch) { 445411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch.")); 445511fa71b9SJerome Forissier goto exit; 445611fa71b9SJerome Forissier } 445711fa71b9SJerome Forissier 445811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Found buffered record from current epoch - load")); 445911fa71b9SJerome Forissier 446011fa71b9SJerome Forissier /* Double-check that the record is not too large */ 4461*32b31808SJens Wiklander if (rec_len > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) { 446211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4463*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 446411fa71b9SJerome Forissier } 446511fa71b9SJerome Forissier 446611fa71b9SJerome Forissier memcpy(ssl->in_hdr, rec, rec_len); 446711fa71b9SJerome Forissier ssl->in_left = rec_len; 446811fa71b9SJerome Forissier ssl->next_record_offset = 0; 446911fa71b9SJerome Forissier 447011fa71b9SJerome Forissier ssl_free_buffered_record(ssl); 447111fa71b9SJerome Forissier 447211fa71b9SJerome Forissier exit: 447311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record")); 4474*32b31808SJens Wiklander return 0; 447511fa71b9SJerome Forissier } 447611fa71b9SJerome Forissier 4477039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 447811fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl, 447911fa71b9SJerome Forissier mbedtls_record const *rec) 448011fa71b9SJerome Forissier { 448111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 448211fa71b9SJerome Forissier 448311fa71b9SJerome Forissier /* Don't buffer future records outside handshakes. */ 4484*32b31808SJens Wiklander if (hs == NULL) { 4485*32b31808SJens Wiklander return 0; 4486*32b31808SJens Wiklander } 448711fa71b9SJerome Forissier 448811fa71b9SJerome Forissier /* Only buffer handshake records (we are only interested 448911fa71b9SJerome Forissier * in Finished messages). */ 4490*32b31808SJens Wiklander if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE) { 4491*32b31808SJens Wiklander return 0; 4492*32b31808SJens Wiklander } 449311fa71b9SJerome Forissier 449411fa71b9SJerome Forissier /* Don't buffer more than one future epoch record. */ 4495*32b31808SJens Wiklander if (hs->buffering.future_record.data != NULL) { 4496*32b31808SJens Wiklander return 0; 4497*32b31808SJens Wiklander } 449811fa71b9SJerome Forissier 449911fa71b9SJerome Forissier /* Don't buffer record if there's not enough buffering space remaining. */ 450011fa71b9SJerome Forissier if (rec->buf_len > (MBEDTLS_SSL_DTLS_MAX_BUFFERING - 4501*32b31808SJens Wiklander hs->buffering.total_bytes_buffered)) { 45027901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET 45037901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 45047901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 45057901324dSJerome Forissier " bytes buffered) -- ignore\n", 45067901324dSJerome Forissier rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 45077901324dSJerome Forissier hs->buffering.total_bytes_buffered)); 4508*32b31808SJens Wiklander return 0; 450911fa71b9SJerome Forissier } 451011fa71b9SJerome Forissier 451111fa71b9SJerome Forissier /* Buffer record */ 451211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffer record from epoch %u", 45137901324dSJerome Forissier ssl->in_epoch + 1U)); 451411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len); 451511fa71b9SJerome Forissier 451611fa71b9SJerome Forissier /* ssl_parse_record_header() only considers records 451711fa71b9SJerome Forissier * of the next epoch as candidates for buffering. */ 451811fa71b9SJerome Forissier hs->buffering.future_record.epoch = ssl->in_epoch + 1; 451911fa71b9SJerome Forissier hs->buffering.future_record.len = rec->buf_len; 452011fa71b9SJerome Forissier 452111fa71b9SJerome Forissier hs->buffering.future_record.data = 452211fa71b9SJerome Forissier mbedtls_calloc(1, hs->buffering.future_record.len); 4523*32b31808SJens Wiklander if (hs->buffering.future_record.data == NULL) { 452411fa71b9SJerome Forissier /* If we run out of RAM trying to buffer a 452511fa71b9SJerome Forissier * record from the next epoch, just ignore. */ 4526*32b31808SJens Wiklander return 0; 452711fa71b9SJerome Forissier } 452811fa71b9SJerome Forissier 452911fa71b9SJerome Forissier memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len); 453011fa71b9SJerome Forissier 453111fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += rec->buf_len; 4532*32b31808SJens Wiklander return 0; 453311fa71b9SJerome Forissier } 453411fa71b9SJerome Forissier 453511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 453611fa71b9SJerome Forissier 4537039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 453811fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl) 453911fa71b9SJerome Forissier { 454011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 454111fa71b9SJerome Forissier mbedtls_record rec; 454211fa71b9SJerome Forissier 454311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 454411fa71b9SJerome Forissier /* We might have buffered a future record; if so, 454511fa71b9SJerome Forissier * and if the epoch matches now, load it. 454611fa71b9SJerome Forissier * On success, this call will set ssl->in_left to 454711fa71b9SJerome Forissier * the length of the buffered record, so that 454811fa71b9SJerome Forissier * the calls to ssl_fetch_input() below will 454911fa71b9SJerome Forissier * essentially be no-ops. */ 455011fa71b9SJerome Forissier ret = ssl_load_buffered_record(ssl); 4551*32b31808SJens Wiklander if (ret != 0) { 4552*32b31808SJens Wiklander return ret; 4553*32b31808SJens Wiklander } 455411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 455511fa71b9SJerome Forissier 455611fa71b9SJerome Forissier /* Ensure that we have enough space available for the default form 455711fa71b9SJerome Forissier * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, 455811fa71b9SJerome Forissier * with no space for CIDs counted in). */ 455911fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl)); 4560*32b31808SJens Wiklander if (ret != 0) { 456111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); 4562*32b31808SJens Wiklander return ret; 456311fa71b9SJerome Forissier } 456411fa71b9SJerome Forissier 456511fa71b9SJerome Forissier ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec); 4566*32b31808SJens Wiklander if (ret != 0) { 456711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4568*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 4569*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) { 457011fa71b9SJerome Forissier ret = ssl_buffer_future_record(ssl, &rec); 4571*32b31808SJens Wiklander if (ret != 0) { 4572*32b31808SJens Wiklander return ret; 4573*32b31808SJens Wiklander } 457411fa71b9SJerome Forissier 457511fa71b9SJerome Forissier /* Fall through to handling of unexpected records */ 457611fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 457711fa71b9SJerome Forissier } 457811fa71b9SJerome Forissier 4579*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) { 458011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 458111fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 458211fa71b9SJerome Forissier * assuming no CID and no offset between record content and 458311fa71b9SJerome Forissier * record plaintext. */ 458411fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl); 458511fa71b9SJerome Forissier 458611fa71b9SJerome Forissier /* Setup internal message pointers from record structure. */ 458711fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 458811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 458911fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 459011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 459111fa71b9SJerome Forissier ssl->in_iv = ssl->in_msg = ssl->in_len + 2; 459211fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 459311fa71b9SJerome Forissier 459411fa71b9SJerome Forissier ret = ssl_check_client_reconnect(ssl); 459511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret); 4596*32b31808SJens Wiklander if (ret != 0) { 4597*32b31808SJens Wiklander return ret; 4598*32b31808SJens Wiklander } 459911fa71b9SJerome Forissier #endif 460011fa71b9SJerome Forissier 460111fa71b9SJerome Forissier /* Skip unexpected record (but not whole datagram) */ 460211fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 460311fa71b9SJerome Forissier 460411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record " 460511fa71b9SJerome Forissier "(header)")); 4606*32b31808SJens Wiklander } else { 460711fa71b9SJerome Forissier /* Skip invalid record and the rest of the datagram */ 460811fa71b9SJerome Forissier ssl->next_record_offset = 0; 460911fa71b9SJerome Forissier ssl->in_left = 0; 461011fa71b9SJerome Forissier 461111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record " 461211fa71b9SJerome Forissier "(header)")); 461311fa71b9SJerome Forissier } 461411fa71b9SJerome Forissier 461511fa71b9SJerome Forissier /* Get next record */ 4616*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 4617*32b31808SJens Wiklander } else 461811fa71b9SJerome Forissier #endif 461911fa71b9SJerome Forissier { 4620*32b31808SJens Wiklander return ret; 462111fa71b9SJerome Forissier } 462211fa71b9SJerome Forissier } 462311fa71b9SJerome Forissier 462411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4625*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 462611fa71b9SJerome Forissier /* Remember offset of next record within datagram. */ 462711fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 4628*32b31808SJens Wiklander if (ssl->next_record_offset < ssl->in_left) { 462911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram")); 463011fa71b9SJerome Forissier } 4631*32b31808SJens Wiklander } else 463211fa71b9SJerome Forissier #endif 463311fa71b9SJerome Forissier { 463411fa71b9SJerome Forissier /* 463511fa71b9SJerome Forissier * Fetch record contents from underlying transport. 463611fa71b9SJerome Forissier */ 463711fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len); 4638*32b31808SJens Wiklander if (ret != 0) { 463911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); 4640*32b31808SJens Wiklander return ret; 464111fa71b9SJerome Forissier } 464211fa71b9SJerome Forissier 464311fa71b9SJerome Forissier ssl->in_left = 0; 464411fa71b9SJerome Forissier } 464511fa71b9SJerome Forissier 464611fa71b9SJerome Forissier /* 464711fa71b9SJerome Forissier * Decrypt record contents. 464811fa71b9SJerome Forissier */ 464911fa71b9SJerome Forissier 4650*32b31808SJens Wiklander if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) { 465111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4652*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 465311fa71b9SJerome Forissier /* Silently discard invalid records */ 4654*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { 465511fa71b9SJerome Forissier /* Except when waiting for Finished as a bad mac here 465611fa71b9SJerome Forissier * probably means something went wrong in the handshake 465711fa71b9SJerome Forissier * (eg wrong psk used, mitm downgrade attempt, etc.) */ 465811fa71b9SJerome Forissier if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || 4659*32b31808SJens Wiklander ssl->state == MBEDTLS_SSL_SERVER_FINISHED) { 466011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 4661*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { 466211fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl, 466311fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 466411fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC); 466511fa71b9SJerome Forissier } 466611fa71b9SJerome Forissier #endif 4667*32b31808SJens Wiklander return ret; 466811fa71b9SJerome Forissier } 466911fa71b9SJerome Forissier 467011fa71b9SJerome Forissier if (ssl->conf->badmac_limit != 0 && 4671*32b31808SJens Wiklander ++ssl->badmac_seen >= ssl->conf->badmac_limit) { 467211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC")); 4673*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC; 467411fa71b9SJerome Forissier } 467511fa71b9SJerome Forissier 467611fa71b9SJerome Forissier /* As above, invalid records cause 467711fa71b9SJerome Forissier * dismissal of the whole datagram. */ 467811fa71b9SJerome Forissier 467911fa71b9SJerome Forissier ssl->next_record_offset = 0; 468011fa71b9SJerome Forissier ssl->in_left = 0; 468111fa71b9SJerome Forissier 468211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)")); 4683*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 468411fa71b9SJerome Forissier } 468511fa71b9SJerome Forissier 4686*32b31808SJens Wiklander return ret; 4687*32b31808SJens Wiklander } else 468811fa71b9SJerome Forissier #endif 468911fa71b9SJerome Forissier { 469011fa71b9SJerome Forissier /* Error out (and send alert) on invalid records */ 469111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 4692*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { 469311fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl, 469411fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 469511fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC); 469611fa71b9SJerome Forissier } 469711fa71b9SJerome Forissier #endif 4698*32b31808SJens Wiklander return ret; 469911fa71b9SJerome Forissier } 470011fa71b9SJerome Forissier } 470111fa71b9SJerome Forissier 470211fa71b9SJerome Forissier 470311fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 470411fa71b9SJerome Forissier * assuming no CID and no offset between record content and 470511fa71b9SJerome Forissier * record plaintext. */ 470611fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl); 470711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 470811fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 470911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 471011fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 471111fa71b9SJerome Forissier 471211fa71b9SJerome Forissier /* The record content type may change during decryption, 471311fa71b9SJerome Forissier * so re-read it. */ 471411fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 471511fa71b9SJerome Forissier /* Also update the input buffer, because unfortunately 471611fa71b9SJerome Forissier * the server-side ssl_parse_client_hello() reparses the 471711fa71b9SJerome Forissier * record header when receiving a ClientHello initiating 471811fa71b9SJerome Forissier * a renegotiation. */ 471911fa71b9SJerome Forissier ssl->in_hdr[0] = rec.type; 472011fa71b9SJerome Forissier ssl->in_msg = rec.buf + rec.data_offset; 472111fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 4722039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0); 472311fa71b9SJerome Forissier 4724*32b31808SJens Wiklander return 0; 472511fa71b9SJerome Forissier } 472611fa71b9SJerome Forissier 472711fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl) 472811fa71b9SJerome Forissier { 472911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 473011fa71b9SJerome Forissier 473111fa71b9SJerome Forissier /* 473211fa71b9SJerome Forissier * Handle particular types of records 473311fa71b9SJerome Forissier */ 4734*32b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { 4735*32b31808SJens Wiklander if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) { 4736*32b31808SJens Wiklander return ret; 473711fa71b9SJerome Forissier } 473811fa71b9SJerome Forissier } 473911fa71b9SJerome Forissier 4740*32b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { 4741*32b31808SJens Wiklander if (ssl->in_msglen != 1) { 47427901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET, 474311fa71b9SJerome Forissier ssl->in_msglen)); 4744*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 474511fa71b9SJerome Forissier } 474611fa71b9SJerome Forissier 4747*32b31808SJens Wiklander if (ssl->in_msg[0] != 1) { 474811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x", 474911fa71b9SJerome Forissier ssl->in_msg[0])); 4750*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 475111fa71b9SJerome Forissier } 475211fa71b9SJerome Forissier 475311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 475411fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 475511fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && 4756*32b31808SJens Wiklander ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) { 4757*32b31808SJens Wiklander if (ssl->handshake == NULL) { 475811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("dropping ChangeCipherSpec outside handshake")); 4759*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 476011fa71b9SJerome Forissier } 476111fa71b9SJerome Forissier 476211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("received out-of-order ChangeCipherSpec - remember")); 4763*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE; 476411fa71b9SJerome Forissier } 476511fa71b9SJerome Forissier #endif 4766*32b31808SJens Wiklander 4767*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 4768*32b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 4769*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE) 4770*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 4771*32b31808SJens Wiklander ("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode")); 4772*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 4773*32b31808SJens Wiklander #else 4774*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 4775*32b31808SJens Wiklander ("ChangeCipherSpec invalid in TLS 1.3 without compatibility mode")); 4776*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 4777*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ 4778*32b31808SJens Wiklander } 4779*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 478011fa71b9SJerome Forissier } 478111fa71b9SJerome Forissier 4782*32b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) { 4783*32b31808SJens Wiklander if (ssl->in_msglen != 2) { 478411fa71b9SJerome Forissier /* Note: Standard allows for more than one 2 byte alert 478511fa71b9SJerome Forissier to be packed in a single message, but Mbed TLS doesn't 478611fa71b9SJerome Forissier currently support this. */ 47877901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET, 478811fa71b9SJerome Forissier ssl->in_msglen)); 4789*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD; 479011fa71b9SJerome Forissier } 479111fa71b9SJerome Forissier 47927901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]", 479311fa71b9SJerome Forissier ssl->in_msg[0], ssl->in_msg[1])); 479411fa71b9SJerome Forissier 479511fa71b9SJerome Forissier /* 479611fa71b9SJerome Forissier * Ignore non-fatal alerts, except close_notify and no_renegotiation 479711fa71b9SJerome Forissier */ 4798*32b31808SJens Wiklander if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) { 479911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)", 480011fa71b9SJerome Forissier ssl->in_msg[1])); 4801*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE; 480211fa71b9SJerome Forissier } 480311fa71b9SJerome Forissier 480411fa71b9SJerome Forissier if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 4805*32b31808SJens Wiklander ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) { 480611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message")); 4807*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY; 480811fa71b9SJerome Forissier } 480911fa71b9SJerome Forissier 481011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) 481111fa71b9SJerome Forissier if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 4812*32b31808SJens Wiklander ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) { 4813*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert")); 481411fa71b9SJerome Forissier /* Will be handled when trying to parse ServerHello */ 4815*32b31808SJens Wiklander return 0; 481611fa71b9SJerome Forissier } 481711fa71b9SJerome Forissier #endif 481811fa71b9SJerome Forissier /* Silently ignore: fetch new message */ 481911fa71b9SJerome Forissier return MBEDTLS_ERR_SSL_NON_FATAL; 482011fa71b9SJerome Forissier } 482111fa71b9SJerome Forissier 482211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4823*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 482411fa71b9SJerome Forissier /* Drop unexpected ApplicationData records, 482511fa71b9SJerome Forissier * except at the beginning of renegotiations */ 482611fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && 4827*32b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 0 482811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 482911fa71b9SJerome Forissier && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 483011fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_HELLO) 483111fa71b9SJerome Forissier #endif 4832*32b31808SJens Wiklander ) { 483311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData")); 4834*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_NON_FATAL; 483511fa71b9SJerome Forissier } 483611fa71b9SJerome Forissier 483711fa71b9SJerome Forissier if (ssl->handshake != NULL && 4838*32b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 1) { 483911fa71b9SJerome Forissier mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl); 484011fa71b9SJerome Forissier } 484111fa71b9SJerome Forissier } 484211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 484311fa71b9SJerome Forissier 4844*32b31808SJens Wiklander return 0; 484511fa71b9SJerome Forissier } 484611fa71b9SJerome Forissier 484711fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl) 484811fa71b9SJerome Forissier { 4849*32b31808SJens Wiklander return mbedtls_ssl_send_alert_message(ssl, 485011fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 4851*32b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 485211fa71b9SJerome Forissier } 485311fa71b9SJerome Forissier 485411fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, 485511fa71b9SJerome Forissier unsigned char level, 485611fa71b9SJerome Forissier unsigned char message) 485711fa71b9SJerome Forissier { 485811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 485911fa71b9SJerome Forissier 4860*32b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) { 4861*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 4862*32b31808SJens Wiklander } 486311fa71b9SJerome Forissier 4864*32b31808SJens Wiklander if (ssl->out_left != 0) { 4865*32b31808SJens Wiklander return mbedtls_ssl_flush_output(ssl); 4866*32b31808SJens Wiklander } 4867039e02dfSJerome Forissier 486811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message")); 486911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("send alert level=%u message=%u", level, message)); 487011fa71b9SJerome Forissier 487111fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; 487211fa71b9SJerome Forissier ssl->out_msglen = 2; 487311fa71b9SJerome Forissier ssl->out_msg[0] = level; 487411fa71b9SJerome Forissier ssl->out_msg[1] = message; 487511fa71b9SJerome Forissier 4876*32b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) { 487711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); 4878*32b31808SJens Wiklander return ret; 487911fa71b9SJerome Forissier } 488011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message")); 488111fa71b9SJerome Forissier 4882*32b31808SJens Wiklander return 0; 488311fa71b9SJerome Forissier } 488411fa71b9SJerome Forissier 488511fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl) 488611fa71b9SJerome Forissier { 488711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 488811fa71b9SJerome Forissier 488911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec")); 489011fa71b9SJerome Forissier 489111fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 489211fa71b9SJerome Forissier ssl->out_msglen = 1; 489311fa71b9SJerome Forissier ssl->out_msg[0] = 1; 489411fa71b9SJerome Forissier 489511fa71b9SJerome Forissier ssl->state++; 489611fa71b9SJerome Forissier 4897*32b31808SJens Wiklander if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 489811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 4899*32b31808SJens Wiklander return ret; 490011fa71b9SJerome Forissier } 490111fa71b9SJerome Forissier 490211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec")); 490311fa71b9SJerome Forissier 4904*32b31808SJens Wiklander return 0; 490511fa71b9SJerome Forissier } 490611fa71b9SJerome Forissier 490711fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl) 490811fa71b9SJerome Forissier { 490911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 491011fa71b9SJerome Forissier 491111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec")); 491211fa71b9SJerome Forissier 4913*32b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 491411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 4915*32b31808SJens Wiklander return ret; 491611fa71b9SJerome Forissier } 491711fa71b9SJerome Forissier 4918*32b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) { 491911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message")); 492011fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 492111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 4922*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 492311fa71b9SJerome Forissier } 492411fa71b9SJerome Forissier 492511fa71b9SJerome Forissier /* CCS records are only accepted if they have length 1 and content '1', 492611fa71b9SJerome Forissier * so we don't need to check this here. */ 492711fa71b9SJerome Forissier 492811fa71b9SJerome Forissier /* 492911fa71b9SJerome Forissier * Switch to our negotiated transform and session parameters for inbound 493011fa71b9SJerome Forissier * data. 493111fa71b9SJerome Forissier */ 493211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for inbound data")); 4933*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 493411fa71b9SJerome Forissier ssl->transform_in = ssl->transform_negotiate; 4935*32b31808SJens Wiklander #endif 493611fa71b9SJerome Forissier ssl->session_in = ssl->session_negotiate; 493711fa71b9SJerome Forissier 493811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4939*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 494011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 494111fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_reset(ssl); 494211fa71b9SJerome Forissier #endif 494311fa71b9SJerome Forissier 494411fa71b9SJerome Forissier /* Increment epoch */ 4945*32b31808SJens Wiklander if (++ssl->in_epoch == 0) { 494611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap")); 494711fa71b9SJerome Forissier /* This is highly unlikely to happen for legitimate reasons, so 494811fa71b9SJerome Forissier treat it as an attack and don't send an alert. */ 4949*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING; 495011fa71b9SJerome Forissier } 4951*32b31808SJens Wiklander } else 495211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 4953*32b31808SJens Wiklander memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); 495411fa71b9SJerome Forissier 495511fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl); 495611fa71b9SJerome Forissier 495711fa71b9SJerome Forissier ssl->state++; 495811fa71b9SJerome Forissier 495911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec")); 496011fa71b9SJerome Forissier 4961*32b31808SJens Wiklander return 0; 496211fa71b9SJerome Forissier } 496311fa71b9SJerome Forissier 496411fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the 496511fa71b9SJerome Forissier * next outgoing record is set, deduce the other pointers. 496611fa71b9SJerome Forissier * 496711fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 496811fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->out_hdr, 496911fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 497011fa71b9SJerome Forissier */ 497111fa71b9SJerome Forissier 49727901324dSJerome Forissier static size_t ssl_transform_get_explicit_iv_len( 49737901324dSJerome Forissier mbedtls_ssl_transform const *transform) 49747901324dSJerome Forissier { 4975*32b31808SJens Wiklander return transform->ivlen - transform->fixed_ivlen; 49767901324dSJerome Forissier } 49777901324dSJerome Forissier 497811fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl, 497911fa71b9SJerome Forissier mbedtls_ssl_transform *transform) 498011fa71b9SJerome Forissier { 498111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4982*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 498311fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr + 3; 498411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 4985*32b31808SJens Wiklander ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 498611fa71b9SJerome Forissier ssl->out_len = ssl->out_cid; 4987*32b31808SJens Wiklander if (transform != NULL) { 498811fa71b9SJerome Forissier ssl->out_len += transform->out_cid_len; 4989*32b31808SJens Wiklander } 499011fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 4991*32b31808SJens Wiklander ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 499211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 499311fa71b9SJerome Forissier ssl->out_iv = ssl->out_len + 2; 4994*32b31808SJens Wiklander } else 499511fa71b9SJerome Forissier #endif 499611fa71b9SJerome Forissier { 499711fa71b9SJerome Forissier ssl->out_len = ssl->out_hdr + 3; 499811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 499911fa71b9SJerome Forissier ssl->out_cid = ssl->out_len; 500011fa71b9SJerome Forissier #endif 500111fa71b9SJerome Forissier ssl->out_iv = ssl->out_hdr + 5; 500211fa71b9SJerome Forissier } 500311fa71b9SJerome Forissier 500411fa71b9SJerome Forissier ssl->out_msg = ssl->out_iv; 50057901324dSJerome Forissier /* Adjust out_msg to make space for explicit IV, if used. */ 5006*32b31808SJens Wiklander if (transform != NULL) { 50077901324dSJerome Forissier ssl->out_msg += ssl_transform_get_explicit_iv_len(transform); 500811fa71b9SJerome Forissier } 5009*32b31808SJens Wiklander } 501011fa71b9SJerome Forissier 501111fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the 501211fa71b9SJerome Forissier * next incoming record is set, deduce the other pointers. 501311fa71b9SJerome Forissier * 501411fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 501511fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->in_hdr, 501611fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 501711fa71b9SJerome Forissier */ 501811fa71b9SJerome Forissier 501911fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl) 502011fa71b9SJerome Forissier { 502111fa71b9SJerome Forissier /* This function sets the pointers to match the case 502211fa71b9SJerome Forissier * of unprotected TLS/DTLS records, with both ssl->in_iv 502311fa71b9SJerome Forissier * and ssl->in_msg pointing to the beginning of the record 502411fa71b9SJerome Forissier * content. 502511fa71b9SJerome Forissier * 502611fa71b9SJerome Forissier * When decrypting a protected record, ssl->in_msg 502711fa71b9SJerome Forissier * will be shifted to point to the beginning of the 502811fa71b9SJerome Forissier * record plaintext. 502911fa71b9SJerome Forissier */ 503011fa71b9SJerome Forissier 503111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5032*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 503311fa71b9SJerome Forissier /* This sets the header pointers to match records 503411fa71b9SJerome Forissier * without CID. When we receive a record containing 503511fa71b9SJerome Forissier * a CID, the fields are shifted accordingly in 503611fa71b9SJerome Forissier * ssl_parse_record_header(). */ 503711fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr + 3; 503811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 5039*32b31808SJens Wiklander ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 504011fa71b9SJerome Forissier ssl->in_len = ssl->in_cid; /* Default: no CID */ 504111fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 5042*32b31808SJens Wiklander ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 504311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 504411fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 5045*32b31808SJens Wiklander } else 504611fa71b9SJerome Forissier #endif 504711fa71b9SJerome Forissier { 5048*32b31808SJens Wiklander ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN; 504911fa71b9SJerome Forissier ssl->in_len = ssl->in_hdr + 3; 505011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 505111fa71b9SJerome Forissier ssl->in_cid = ssl->in_len; 505211fa71b9SJerome Forissier #endif 505311fa71b9SJerome Forissier ssl->in_iv = ssl->in_hdr + 5; 505411fa71b9SJerome Forissier } 505511fa71b9SJerome Forissier 505611fa71b9SJerome Forissier /* This will be adjusted at record decryption time. */ 505711fa71b9SJerome Forissier ssl->in_msg = ssl->in_iv; 505811fa71b9SJerome Forissier } 505911fa71b9SJerome Forissier 506011fa71b9SJerome Forissier /* 506111fa71b9SJerome Forissier * Setup an SSL context 506211fa71b9SJerome Forissier */ 506311fa71b9SJerome Forissier 506411fa71b9SJerome Forissier void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl) 506511fa71b9SJerome Forissier { 506611fa71b9SJerome Forissier /* Set the incoming and outgoing record pointers. */ 506711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5068*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 506911fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 507011fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf; 5071*32b31808SJens Wiklander } else 507211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 507311fa71b9SJerome Forissier { 5074*32b31808SJens Wiklander ssl->out_ctr = ssl->out_buf; 507511fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 507611fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf + 8; 507711fa71b9SJerome Forissier } 507811fa71b9SJerome Forissier 507911fa71b9SJerome Forissier /* Derive other internal pointers. */ 508011fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */); 508111fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl); 508211fa71b9SJerome Forissier } 508311fa71b9SJerome Forissier 508411fa71b9SJerome Forissier /* 508511fa71b9SJerome Forissier * SSL get accessors 508611fa71b9SJerome Forissier */ 508711fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl) 508811fa71b9SJerome Forissier { 5089*32b31808SJens Wiklander return ssl->in_offt == NULL ? 0 : ssl->in_msglen; 509011fa71b9SJerome Forissier } 509111fa71b9SJerome Forissier 509211fa71b9SJerome Forissier int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl) 509311fa71b9SJerome Forissier { 509411fa71b9SJerome Forissier /* 509511fa71b9SJerome Forissier * Case A: We're currently holding back 509611fa71b9SJerome Forissier * a message for further processing. 509711fa71b9SJerome Forissier */ 509811fa71b9SJerome Forissier 5099*32b31808SJens Wiklander if (ssl->keep_current_message == 1) { 510011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: record held back for processing")); 5101*32b31808SJens Wiklander return 1; 510211fa71b9SJerome Forissier } 510311fa71b9SJerome Forissier 510411fa71b9SJerome Forissier /* 510511fa71b9SJerome Forissier * Case B: Further records are pending in the current datagram. 510611fa71b9SJerome Forissier */ 510711fa71b9SJerome Forissier 510811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 510911fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 5110*32b31808SJens Wiklander ssl->in_left > ssl->next_record_offset) { 511111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: more records within current datagram")); 5112*32b31808SJens Wiklander return 1; 511311fa71b9SJerome Forissier } 511411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 511511fa71b9SJerome Forissier 511611fa71b9SJerome Forissier /* 511711fa71b9SJerome Forissier * Case C: A handshake message is being processed. 511811fa71b9SJerome Forissier */ 511911fa71b9SJerome Forissier 5120*32b31808SJens Wiklander if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) { 5121*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, 5122*32b31808SJens Wiklander ("ssl_check_pending: more handshake messages within current record")); 5123*32b31808SJens Wiklander return 1; 512411fa71b9SJerome Forissier } 512511fa71b9SJerome Forissier 512611fa71b9SJerome Forissier /* 512711fa71b9SJerome Forissier * Case D: An application data message is being processed 512811fa71b9SJerome Forissier */ 5129*32b31808SJens Wiklander if (ssl->in_offt != NULL) { 513011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: application data record is being processed")); 5131*32b31808SJens Wiklander return 1; 513211fa71b9SJerome Forissier } 513311fa71b9SJerome Forissier 513411fa71b9SJerome Forissier /* 513511fa71b9SJerome Forissier * In all other cases, the rest of the message can be dropped. 513611fa71b9SJerome Forissier * As in ssl_get_next_record, this needs to be adapted if 513711fa71b9SJerome Forissier * we implement support for multiple alerts in single records. 513811fa71b9SJerome Forissier */ 513911fa71b9SJerome Forissier 514011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending")); 5141*32b31808SJens Wiklander return 0; 514211fa71b9SJerome Forissier } 514311fa71b9SJerome Forissier 514411fa71b9SJerome Forissier 514511fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl) 514611fa71b9SJerome Forissier { 514711fa71b9SJerome Forissier size_t transform_expansion = 0; 514811fa71b9SJerome Forissier const mbedtls_ssl_transform *transform = ssl->transform_out; 514911fa71b9SJerome Forissier unsigned block_size; 5150*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 5151*32b31808SJens Wiklander psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT; 5152*32b31808SJens Wiklander psa_key_type_t key_type; 5153*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 515411fa71b9SJerome Forissier 515511fa71b9SJerome Forissier size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl); 515611fa71b9SJerome Forissier 5157*32b31808SJens Wiklander if (transform == NULL) { 5158*32b31808SJens Wiklander return (int) out_hdr_len; 5159*32b31808SJens Wiklander } 516011fa71b9SJerome Forissier 516111fa71b9SJerome Forissier 5162*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 5163*32b31808SJens Wiklander if (transform->psa_alg == PSA_ALG_GCM || 5164*32b31808SJens Wiklander transform->psa_alg == PSA_ALG_CCM || 5165*32b31808SJens Wiklander transform->psa_alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 8) || 5166*32b31808SJens Wiklander transform->psa_alg == PSA_ALG_CHACHA20_POLY1305 || 5167*32b31808SJens Wiklander transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) { 5168*32b31808SJens Wiklander transform_expansion = transform->minlen; 5169*32b31808SJens Wiklander } else if (transform->psa_alg == PSA_ALG_CBC_NO_PADDING) { 5170*32b31808SJens Wiklander (void) psa_get_key_attributes(transform->psa_key_enc, &attr); 5171*32b31808SJens Wiklander key_type = psa_get_key_type(&attr); 5172*32b31808SJens Wiklander 5173*32b31808SJens Wiklander block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type); 5174*32b31808SJens Wiklander 5175*32b31808SJens Wiklander /* Expansion due to the addition of the MAC. */ 5176*32b31808SJens Wiklander transform_expansion += transform->maclen; 5177*32b31808SJens Wiklander 5178*32b31808SJens Wiklander /* Expansion due to the addition of CBC padding; 5179*32b31808SJens Wiklander * Theoretically up to 256 bytes, but we never use 5180*32b31808SJens Wiklander * more than the block size of the underlying cipher. */ 5181*32b31808SJens Wiklander transform_expansion += block_size; 5182*32b31808SJens Wiklander 5183*32b31808SJens Wiklander /* For TLS 1.2 or higher, an explicit IV is added 5184*32b31808SJens Wiklander * after the record header. */ 5185*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 5186*32b31808SJens Wiklander transform_expansion += block_size; 5187*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 5188*32b31808SJens Wiklander } else { 5189*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, 5190*32b31808SJens Wiklander ("Unsupported psa_alg spotted in mbedtls_ssl_get_record_expansion()")); 5191*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 5192*32b31808SJens Wiklander } 5193*32b31808SJens Wiklander #else 5194*32b31808SJens Wiklander switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) { 519511fa71b9SJerome Forissier case MBEDTLS_MODE_GCM: 519611fa71b9SJerome Forissier case MBEDTLS_MODE_CCM: 519711fa71b9SJerome Forissier case MBEDTLS_MODE_CHACHAPOLY: 519811fa71b9SJerome Forissier case MBEDTLS_MODE_STREAM: 519911fa71b9SJerome Forissier transform_expansion = transform->minlen; 520011fa71b9SJerome Forissier break; 520111fa71b9SJerome Forissier 520211fa71b9SJerome Forissier case MBEDTLS_MODE_CBC: 520311fa71b9SJerome Forissier 520411fa71b9SJerome Forissier block_size = mbedtls_cipher_get_block_size( 520511fa71b9SJerome Forissier &transform->cipher_ctx_enc); 520611fa71b9SJerome Forissier 520711fa71b9SJerome Forissier /* Expansion due to the addition of the MAC. */ 520811fa71b9SJerome Forissier transform_expansion += transform->maclen; 520911fa71b9SJerome Forissier 521011fa71b9SJerome Forissier /* Expansion due to the addition of CBC padding; 521111fa71b9SJerome Forissier * Theoretically up to 256 bytes, but we never use 521211fa71b9SJerome Forissier * more than the block size of the underlying cipher. */ 521311fa71b9SJerome Forissier transform_expansion += block_size; 521411fa71b9SJerome Forissier 5215*32b31808SJens Wiklander /* For TLS 1.2 or higher, an explicit IV is added 521611fa71b9SJerome Forissier * after the record header. */ 5217*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 521811fa71b9SJerome Forissier transform_expansion += block_size; 5219*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 522011fa71b9SJerome Forissier 522111fa71b9SJerome Forissier break; 522211fa71b9SJerome Forissier 522311fa71b9SJerome Forissier default: 522411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 5225*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 522611fa71b9SJerome Forissier } 5227*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 522811fa71b9SJerome Forissier 522911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 5230*32b31808SJens Wiklander if (transform->out_cid_len != 0) { 523111fa71b9SJerome Forissier transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; 5232*32b31808SJens Wiklander } 523311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 523411fa71b9SJerome Forissier 5235*32b31808SJens Wiklander return (int) (out_hdr_len + transform_expansion); 523611fa71b9SJerome Forissier } 523711fa71b9SJerome Forissier 523811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 523911fa71b9SJerome Forissier /* 524011fa71b9SJerome Forissier * Check record counters and renegotiate if they're above the limit. 524111fa71b9SJerome Forissier */ 5242039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 524311fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl) 524411fa71b9SJerome Forissier { 524511fa71b9SJerome Forissier size_t ep_len = mbedtls_ssl_ep_len(ssl); 524611fa71b9SJerome Forissier int in_ctr_cmp; 524711fa71b9SJerome Forissier int out_ctr_cmp; 524811fa71b9SJerome Forissier 5249*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0 || 525011fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || 5251*32b31808SJens Wiklander ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED) { 5252*32b31808SJens Wiklander return 0; 525311fa71b9SJerome Forissier } 525411fa71b9SJerome Forissier 525511fa71b9SJerome Forissier in_ctr_cmp = memcmp(ssl->in_ctr + ep_len, 5256*32b31808SJens Wiklander &ssl->conf->renego_period[ep_len], 5257*32b31808SJens Wiklander MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len); 5258*32b31808SJens Wiklander out_ctr_cmp = memcmp(&ssl->cur_out_ctr[ep_len], 5259*32b31808SJens Wiklander &ssl->conf->renego_period[ep_len], 5260*32b31808SJens Wiklander sizeof(ssl->cur_out_ctr) - ep_len); 526111fa71b9SJerome Forissier 5262*32b31808SJens Wiklander if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) { 5263*32b31808SJens Wiklander return 0; 526411fa71b9SJerome Forissier } 526511fa71b9SJerome Forissier 526611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate")); 5267*32b31808SJens Wiklander return mbedtls_ssl_renegotiate(ssl); 526811fa71b9SJerome Forissier } 526911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 527011fa71b9SJerome Forissier 5271*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 5272*32b31808SJens Wiklander 5273*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) 5274*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 5275*32b31808SJens Wiklander static int ssl_tls13_check_new_session_ticket(mbedtls_ssl_context *ssl) 5276*32b31808SJens Wiklander { 5277*32b31808SJens Wiklander 5278*32b31808SJens Wiklander if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) || 5279*32b31808SJens Wiklander (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET)) { 5280*32b31808SJens Wiklander return 0; 5281*32b31808SJens Wiklander } 5282*32b31808SJens Wiklander 5283*32b31808SJens Wiklander ssl->keep_current_message = 1; 5284*32b31808SJens Wiklander 5285*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received")); 5286*32b31808SJens Wiklander mbedtls_ssl_handshake_set_state(ssl, 5287*32b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET); 5288*32b31808SJens Wiklander 5289*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ; 5290*32b31808SJens Wiklander } 5291*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ 5292*32b31808SJens Wiklander 5293*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 5294*32b31808SJens Wiklander static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) 5295*32b31808SJens Wiklander { 5296*32b31808SJens Wiklander 5297*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message")); 5298*32b31808SJens Wiklander 5299*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) 5300*32b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { 5301*32b31808SJens Wiklander int ret = ssl_tls13_check_new_session_ticket(ssl); 5302*32b31808SJens Wiklander if (ret != 0) { 5303*32b31808SJens Wiklander return ret; 5304*32b31808SJens Wiklander } 5305*32b31808SJens Wiklander } 5306*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ 5307*32b31808SJens Wiklander 5308*32b31808SJens Wiklander /* Fail in all other cases. */ 5309*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 5310*32b31808SJens Wiklander } 5311*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 5312*32b31808SJens Wiklander 5313*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 5314*32b31808SJens Wiklander /* This function is called from mbedtls_ssl_read() when a handshake message is 5315*32b31808SJens Wiklander * received after the initial handshake. In this context, handshake messages 5316*32b31808SJens Wiklander * may only be sent for the purpose of initiating renegotiations. 5317*32b31808SJens Wiklander * 5318*32b31808SJens Wiklander * This function is introduced as a separate helper since the handling 5319*32b31808SJens Wiklander * of post-handshake handshake messages changes significantly in TLS 1.3, 5320*32b31808SJens Wiklander * and having a helper function allows to distinguish between TLS <= 1.2 and 5321*32b31808SJens Wiklander * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read(). 5322*32b31808SJens Wiklander */ 5323*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 5324*32b31808SJens Wiklander static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) 5325*32b31808SJens Wiklander { 5326*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 5327*32b31808SJens Wiklander 5328*32b31808SJens Wiklander /* 5329*32b31808SJens Wiklander * - For client-side, expect SERVER_HELLO_REQUEST. 5330*32b31808SJens Wiklander * - For server-side, expect CLIENT_HELLO. 5331*32b31808SJens Wiklander * - Fail (TLS) or silently drop record (DTLS) in other cases. 5332*32b31808SJens Wiklander */ 5333*32b31808SJens Wiklander 5334*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C) 5335*32b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && 5336*32b31808SJens Wiklander (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || 5337*32b31808SJens Wiklander ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl))) { 5338*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)")); 5339*32b31808SJens Wiklander 5340*32b31808SJens Wiklander /* With DTLS, drop the packet (probably from last handshake) */ 5341*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 5342*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 5343*32b31808SJens Wiklander return 0; 5344*32b31808SJens Wiklander } 5345*32b31808SJens Wiklander #endif 5346*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 5347*32b31808SJens Wiklander } 5348*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C */ 5349*32b31808SJens Wiklander 5350*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SRV_C) 5351*32b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 5352*32b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) { 5353*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)")); 5354*32b31808SJens Wiklander 5355*32b31808SJens Wiklander /* With DTLS, drop the packet (probably from last handshake) */ 5356*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 5357*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 5358*32b31808SJens Wiklander return 0; 5359*32b31808SJens Wiklander } 5360*32b31808SJens Wiklander #endif 5361*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 5362*32b31808SJens Wiklander } 5363*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C */ 5364*32b31808SJens Wiklander 5365*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION) 5366*32b31808SJens Wiklander /* Determine whether renegotiation attempt should be accepted */ 5367*32b31808SJens Wiklander if (!(ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || 5368*32b31808SJens Wiklander (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 5369*32b31808SJens Wiklander ssl->conf->allow_legacy_renegotiation == 5370*32b31808SJens Wiklander MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) { 5371*32b31808SJens Wiklander /* 5372*32b31808SJens Wiklander * Accept renegotiation request 5373*32b31808SJens Wiklander */ 5374*32b31808SJens Wiklander 5375*32b31808SJens Wiklander /* DTLS clients need to know renego is server-initiated */ 5376*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS) 5377*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 5378*32b31808SJens Wiklander ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) { 5379*32b31808SJens Wiklander ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; 5380*32b31808SJens Wiklander } 5381*32b31808SJens Wiklander #endif 5382*32b31808SJens Wiklander ret = mbedtls_ssl_start_renegotiation(ssl); 5383*32b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 5384*32b31808SJens Wiklander ret != 0) { 5385*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", 5386*32b31808SJens Wiklander ret); 5387*32b31808SJens Wiklander return ret; 5388*32b31808SJens Wiklander } 5389*32b31808SJens Wiklander } else 5390*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */ 5391*32b31808SJens Wiklander { 5392*32b31808SJens Wiklander /* 5393*32b31808SJens Wiklander * Refuse renegotiation 5394*32b31808SJens Wiklander */ 5395*32b31808SJens Wiklander 5396*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert")); 5397*32b31808SJens Wiklander 5398*32b31808SJens Wiklander if ((ret = mbedtls_ssl_send_alert_message(ssl, 5399*32b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_WARNING, 5400*32b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) { 5401*32b31808SJens Wiklander return ret; 5402*32b31808SJens Wiklander } 5403*32b31808SJens Wiklander } 5404*32b31808SJens Wiklander 5405*32b31808SJens Wiklander return 0; 5406*32b31808SJens Wiklander } 5407*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 5408*32b31808SJens Wiklander 5409*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL 5410*32b31808SJens Wiklander static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl) 5411*32b31808SJens Wiklander { 5412*32b31808SJens Wiklander /* Check protocol version and dispatch accordingly. */ 5413*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3) 5414*32b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { 5415*32b31808SJens Wiklander return ssl_tls13_handle_hs_message_post_handshake(ssl); 5416*32b31808SJens Wiklander } 5417*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 5418*32b31808SJens Wiklander 5419*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 5420*32b31808SJens Wiklander if (ssl->tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) { 5421*32b31808SJens Wiklander return ssl_tls12_handle_hs_message_post_handshake(ssl); 5422*32b31808SJens Wiklander } 5423*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 5424*32b31808SJens Wiklander 5425*32b31808SJens Wiklander /* Should never happen */ 5426*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 5427*32b31808SJens Wiklander } 5428*32b31808SJens Wiklander 542911fa71b9SJerome Forissier /* 543011fa71b9SJerome Forissier * Receive application data decrypted from the SSL layer 543111fa71b9SJerome Forissier */ 543211fa71b9SJerome Forissier int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len) 543311fa71b9SJerome Forissier { 543411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 543511fa71b9SJerome Forissier size_t n; 543611fa71b9SJerome Forissier 5437*32b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) { 5438*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 5439*32b31808SJens Wiklander } 544011fa71b9SJerome Forissier 544111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> read")); 544211fa71b9SJerome Forissier 544311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5444*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 5445*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { 5446*32b31808SJens Wiklander return ret; 5447*32b31808SJens Wiklander } 544811fa71b9SJerome Forissier 544911fa71b9SJerome Forissier if (ssl->handshake != NULL && 5450*32b31808SJens Wiklander ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) { 5451*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { 5452*32b31808SJens Wiklander return ret; 5453*32b31808SJens Wiklander } 545411fa71b9SJerome Forissier } 545511fa71b9SJerome Forissier } 545611fa71b9SJerome Forissier #endif 545711fa71b9SJerome Forissier 545811fa71b9SJerome Forissier /* 545911fa71b9SJerome Forissier * Check if renegotiation is necessary and/or handshake is 546011fa71b9SJerome Forissier * in process. If yes, perform/continue, and fall through 546111fa71b9SJerome Forissier * if an unexpected packet is received while the client 546211fa71b9SJerome Forissier * is waiting for the ServerHello. 546311fa71b9SJerome Forissier * 546411fa71b9SJerome Forissier * (There is no equivalent to the last condition on 546511fa71b9SJerome Forissier * the server-side as it is not treated as within 546611fa71b9SJerome Forissier * a handshake while waiting for the ClientHello 546711fa71b9SJerome Forissier * after a renegotiation request.) 546811fa71b9SJerome Forissier */ 546911fa71b9SJerome Forissier 547011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 547111fa71b9SJerome Forissier ret = ssl_check_ctr_renegotiate(ssl); 547211fa71b9SJerome Forissier if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 5473*32b31808SJens Wiklander ret != 0) { 547411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret); 5475*32b31808SJens Wiklander return ret; 547611fa71b9SJerome Forissier } 547711fa71b9SJerome Forissier #endif 547811fa71b9SJerome Forissier 5479*32b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { 548011fa71b9SJerome Forissier ret = mbedtls_ssl_handshake(ssl); 548111fa71b9SJerome Forissier if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 5482*32b31808SJens Wiklander ret != 0) { 548311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); 5484*32b31808SJens Wiklander return ret; 548511fa71b9SJerome Forissier } 548611fa71b9SJerome Forissier } 548711fa71b9SJerome Forissier 548811fa71b9SJerome Forissier /* Loop as long as no application data record is available */ 5489*32b31808SJens Wiklander while (ssl->in_offt == NULL) { 549011fa71b9SJerome Forissier /* Start timer if not already running */ 549111fa71b9SJerome Forissier if (ssl->f_get_timer != NULL && 5492*32b31808SJens Wiklander ssl->f_get_timer(ssl->p_timer) == -1) { 549311fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout); 549411fa71b9SJerome Forissier } 549511fa71b9SJerome Forissier 5496*32b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 5497*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONN_EOF) { 5498*32b31808SJens Wiklander return 0; 5499*32b31808SJens Wiklander } 550011fa71b9SJerome Forissier 550111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 5502*32b31808SJens Wiklander return ret; 550311fa71b9SJerome Forissier } 550411fa71b9SJerome Forissier 550511fa71b9SJerome Forissier if (ssl->in_msglen == 0 && 5506*32b31808SJens Wiklander ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) { 550711fa71b9SJerome Forissier /* 550811fa71b9SJerome Forissier * OpenSSL sends empty messages to randomize the IV 550911fa71b9SJerome Forissier */ 5510*32b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 5511*32b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONN_EOF) { 5512*32b31808SJens Wiklander return 0; 5513*32b31808SJens Wiklander } 551411fa71b9SJerome Forissier 551511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 5516*32b31808SJens Wiklander return ret; 551711fa71b9SJerome Forissier } 551811fa71b9SJerome Forissier } 551911fa71b9SJerome Forissier 5520*32b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) { 5521*32b31808SJens Wiklander ret = ssl_handle_hs_message_post_handshake(ssl); 5522*32b31808SJens Wiklander if (ret != 0) { 5523*32b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake", 552411fa71b9SJerome Forissier ret); 5525*32b31808SJens Wiklander return ret; 552611fa71b9SJerome Forissier } 552711fa71b9SJerome Forissier 5528*32b31808SJens Wiklander /* At this point, we don't know whether the renegotiation triggered 5529*32b31808SJens Wiklander * by the post-handshake message has been completed or not. The cases 5530*32b31808SJens Wiklander * to consider are the following: 553111fa71b9SJerome Forissier * 1) The renegotiation is complete. In this case, no new record 553211fa71b9SJerome Forissier * has been read yet. 553311fa71b9SJerome Forissier * 2) The renegotiation is incomplete because the client received 553411fa71b9SJerome Forissier * an application data record while awaiting the ServerHello. 553511fa71b9SJerome Forissier * 3) The renegotiation is incomplete because the client received 553611fa71b9SJerome Forissier * a non-handshake, non-application data message while awaiting 553711fa71b9SJerome Forissier * the ServerHello. 5538*32b31808SJens Wiklander * 5539*32b31808SJens Wiklander * In each of these cases, looping will be the proper action: 554011fa71b9SJerome Forissier * - For 1), the next iteration will read a new record and check 554111fa71b9SJerome Forissier * if it's application data. 554211fa71b9SJerome Forissier * - For 2), the loop condition isn't satisfied as application data 554311fa71b9SJerome Forissier * is present, hence continue is the same as break 554411fa71b9SJerome Forissier * - For 3), the loop condition is satisfied and read_record 554511fa71b9SJerome Forissier * will re-deliver the message that was held back by the client 554611fa71b9SJerome Forissier * when expecting the ServerHello. 554711fa71b9SJerome Forissier */ 5548*32b31808SJens Wiklander 554911fa71b9SJerome Forissier continue; 555011fa71b9SJerome Forissier } 555111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 5552*32b31808SJens Wiklander else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { 5553*32b31808SJens Wiklander if (ssl->conf->renego_max_records >= 0) { 5554*32b31808SJens Wiklander if (++ssl->renego_records_seen > ssl->conf->renego_max_records) { 555511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, " 555611fa71b9SJerome Forissier "but not honored by client")); 5557*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 555811fa71b9SJerome Forissier } 555911fa71b9SJerome Forissier } 556011fa71b9SJerome Forissier } 556111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 556211fa71b9SJerome Forissier 556311fa71b9SJerome Forissier /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ 5564*32b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) { 556511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert")); 5566*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ; 556711fa71b9SJerome Forissier } 556811fa71b9SJerome Forissier 5569*32b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) { 557011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message")); 5571*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 557211fa71b9SJerome Forissier } 557311fa71b9SJerome Forissier 557411fa71b9SJerome Forissier ssl->in_offt = ssl->in_msg; 557511fa71b9SJerome Forissier 557611fa71b9SJerome Forissier /* We're going to return something now, cancel timer, 557711fa71b9SJerome Forissier * except if handshake (renegotiation) is in progress */ 5578*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) { 557911fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0); 5580*32b31808SJens Wiklander } 558111fa71b9SJerome Forissier 558211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 558311fa71b9SJerome Forissier /* If we requested renego but received AppData, resend HelloRequest. 558411fa71b9SJerome Forissier * Do it now, after setting in_offt, to avoid taking this branch 558511fa71b9SJerome Forissier * again if ssl_write_hello_request() returns WANT_WRITE */ 558611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 558711fa71b9SJerome Forissier if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 5588*32b31808SJens Wiklander ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) { 5589*32b31808SJens Wiklander if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) { 559011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request", 559111fa71b9SJerome Forissier ret); 5592*32b31808SJens Wiklander return ret; 559311fa71b9SJerome Forissier } 559411fa71b9SJerome Forissier } 559511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 559611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 559711fa71b9SJerome Forissier } 559811fa71b9SJerome Forissier 559911fa71b9SJerome Forissier n = (len < ssl->in_msglen) 560011fa71b9SJerome Forissier ? len : ssl->in_msglen; 560111fa71b9SJerome Forissier 5602*32b31808SJens Wiklander if (len != 0) { 560311fa71b9SJerome Forissier memcpy(buf, ssl->in_offt, n); 560411fa71b9SJerome Forissier ssl->in_msglen -= n; 5605*32b31808SJens Wiklander } 560611fa71b9SJerome Forissier 56077901324dSJerome Forissier /* Zeroising the plaintext buffer to erase unused application data 56087901324dSJerome Forissier from the memory. */ 56097901324dSJerome Forissier mbedtls_platform_zeroize(ssl->in_offt, n); 56107901324dSJerome Forissier 5611*32b31808SJens Wiklander if (ssl->in_msglen == 0) { 561211fa71b9SJerome Forissier /* all bytes consumed */ 561311fa71b9SJerome Forissier ssl->in_offt = NULL; 561411fa71b9SJerome Forissier ssl->keep_current_message = 0; 5615*32b31808SJens Wiklander } else { 561611fa71b9SJerome Forissier /* more data available */ 561711fa71b9SJerome Forissier ssl->in_offt += n; 561811fa71b9SJerome Forissier } 561911fa71b9SJerome Forissier 562011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= read")); 562111fa71b9SJerome Forissier 5622*32b31808SJens Wiklander return (int) n; 562311fa71b9SJerome Forissier } 562411fa71b9SJerome Forissier 562511fa71b9SJerome Forissier /* 562611fa71b9SJerome Forissier * Send application data to be encrypted by the SSL layer, taking care of max 562711fa71b9SJerome Forissier * fragment length and buffer size. 562811fa71b9SJerome Forissier * 562911fa71b9SJerome Forissier * According to RFC 5246 Section 6.2.1: 563011fa71b9SJerome Forissier * 563111fa71b9SJerome Forissier * Zero-length fragments of Application data MAY be sent as they are 563211fa71b9SJerome Forissier * potentially useful as a traffic analysis countermeasure. 563311fa71b9SJerome Forissier * 563411fa71b9SJerome Forissier * Therefore, it is possible that the input message length is 0 and the 563511fa71b9SJerome Forissier * corresponding return code is 0 on success. 563611fa71b9SJerome Forissier */ 5637039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 563811fa71b9SJerome Forissier static int ssl_write_real(mbedtls_ssl_context *ssl, 563911fa71b9SJerome Forissier const unsigned char *buf, size_t len) 564011fa71b9SJerome Forissier { 564111fa71b9SJerome Forissier int ret = mbedtls_ssl_get_max_out_record_payload(ssl); 564211fa71b9SJerome Forissier const size_t max_len = (size_t) ret; 564311fa71b9SJerome Forissier 5644*32b31808SJens Wiklander if (ret < 0) { 564511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret); 5646*32b31808SJens Wiklander return ret; 564711fa71b9SJerome Forissier } 564811fa71b9SJerome Forissier 5649*32b31808SJens Wiklander if (len > max_len) { 565011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5651*32b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 565211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("fragment larger than the (negotiated) " 56537901324dSJerome Forissier "maximum fragment length: %" MBEDTLS_PRINTF_SIZET 56547901324dSJerome Forissier " > %" MBEDTLS_PRINTF_SIZET, 565511fa71b9SJerome Forissier len, max_len)); 5656*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 5657*32b31808SJens Wiklander } else 565811fa71b9SJerome Forissier #endif 565911fa71b9SJerome Forissier len = max_len; 566011fa71b9SJerome Forissier } 566111fa71b9SJerome Forissier 5662*32b31808SJens Wiklander if (ssl->out_left != 0) { 566311fa71b9SJerome Forissier /* 566411fa71b9SJerome Forissier * The user has previously tried to send the data and 566511fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially 566611fa71b9SJerome Forissier * written. In this case, we expect the high-level write function 566711fa71b9SJerome Forissier * (e.g. mbedtls_ssl_write()) to be called with the same parameters 566811fa71b9SJerome Forissier */ 5669*32b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) { 567011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret); 5671*32b31808SJens Wiklander return ret; 567211fa71b9SJerome Forissier } 5673*32b31808SJens Wiklander } else { 567411fa71b9SJerome Forissier /* 567511fa71b9SJerome Forissier * The user is trying to send a message the first time, so we need to 567611fa71b9SJerome Forissier * copy the data into the internal buffers and setup the data structure 567711fa71b9SJerome Forissier * to keep track of partial writes 567811fa71b9SJerome Forissier */ 567911fa71b9SJerome Forissier ssl->out_msglen = len; 568011fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; 5681*32b31808SJens Wiklander if (len > 0) { 568211fa71b9SJerome Forissier memcpy(ssl->out_msg, buf, len); 5683*32b31808SJens Wiklander } 568411fa71b9SJerome Forissier 5685*32b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) { 568611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret); 5687*32b31808SJens Wiklander return ret; 568811fa71b9SJerome Forissier } 568911fa71b9SJerome Forissier } 569011fa71b9SJerome Forissier 5691*32b31808SJens Wiklander return (int) len; 569211fa71b9SJerome Forissier } 569311fa71b9SJerome Forissier 569411fa71b9SJerome Forissier /* 569511fa71b9SJerome Forissier * Write application data (public-facing wrapper) 569611fa71b9SJerome Forissier */ 569711fa71b9SJerome Forissier int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len) 569811fa71b9SJerome Forissier { 569911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 570011fa71b9SJerome Forissier 570111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write")); 570211fa71b9SJerome Forissier 5703*32b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) { 5704*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 5705*32b31808SJens Wiklander } 570611fa71b9SJerome Forissier 570711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 5708*32b31808SJens Wiklander if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) { 570911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret); 5710*32b31808SJens Wiklander return ret; 571111fa71b9SJerome Forissier } 571211fa71b9SJerome Forissier #endif 571311fa71b9SJerome Forissier 5714*32b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { 5715*32b31808SJens Wiklander if ((ret = mbedtls_ssl_handshake(ssl)) != 0) { 571611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret); 5717*32b31808SJens Wiklander return ret; 571811fa71b9SJerome Forissier } 571911fa71b9SJerome Forissier } 572011fa71b9SJerome Forissier 572111fa71b9SJerome Forissier ret = ssl_write_real(ssl, buf, len); 572211fa71b9SJerome Forissier 572311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write")); 572411fa71b9SJerome Forissier 5725*32b31808SJens Wiklander return ret; 572611fa71b9SJerome Forissier } 572711fa71b9SJerome Forissier 572811fa71b9SJerome Forissier /* 572911fa71b9SJerome Forissier * Notify the peer that the connection is being closed 573011fa71b9SJerome Forissier */ 573111fa71b9SJerome Forissier int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl) 573211fa71b9SJerome Forissier { 573311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 573411fa71b9SJerome Forissier 5735*32b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) { 5736*32b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 5737*32b31808SJens Wiklander } 573811fa71b9SJerome Forissier 573911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify")); 574011fa71b9SJerome Forissier 5741*32b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) { 574211fa71b9SJerome Forissier if ((ret = mbedtls_ssl_send_alert_message(ssl, 574311fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING, 5744*32b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) { 574511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret); 5746*32b31808SJens Wiklander return ret; 574711fa71b9SJerome Forissier } 574811fa71b9SJerome Forissier } 574911fa71b9SJerome Forissier 575011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify")); 575111fa71b9SJerome Forissier 5752*32b31808SJens Wiklander return 0; 575311fa71b9SJerome Forissier } 575411fa71b9SJerome Forissier 575511fa71b9SJerome Forissier void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform) 575611fa71b9SJerome Forissier { 5757*32b31808SJens Wiklander if (transform == NULL) { 575811fa71b9SJerome Forissier return; 5759*32b31808SJens Wiklander } 576011fa71b9SJerome Forissier 5761*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 5762*32b31808SJens Wiklander psa_destroy_key(transform->psa_key_enc); 5763*32b31808SJens Wiklander psa_destroy_key(transform->psa_key_dec); 5764*32b31808SJens Wiklander #else 576511fa71b9SJerome Forissier mbedtls_cipher_free(&transform->cipher_ctx_enc); 576611fa71b9SJerome Forissier mbedtls_cipher_free(&transform->cipher_ctx_dec); 5767*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 576811fa71b9SJerome Forissier 5769*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) 5770*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) 5771*32b31808SJens Wiklander psa_destroy_key(transform->psa_mac_enc); 5772*32b31808SJens Wiklander psa_destroy_key(transform->psa_mac_dec); 5773*32b31808SJens Wiklander #else 577411fa71b9SJerome Forissier mbedtls_md_free(&transform->md_ctx_enc); 577511fa71b9SJerome Forissier mbedtls_md_free(&transform->md_ctx_dec); 5776*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */ 577711fa71b9SJerome Forissier #endif 577811fa71b9SJerome Forissier 577911fa71b9SJerome Forissier mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform)); 578011fa71b9SJerome Forissier } 578111fa71b9SJerome Forissier 5782*32b31808SJens Wiklander void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl, 5783*32b31808SJens Wiklander mbedtls_ssl_transform *transform) 5784*32b31808SJens Wiklander { 5785*32b31808SJens Wiklander ssl->transform_in = transform; 5786*32b31808SJens Wiklander memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN); 5787*32b31808SJens Wiklander } 5788*32b31808SJens Wiklander 5789*32b31808SJens Wiklander void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl, 5790*32b31808SJens Wiklander mbedtls_ssl_transform *transform) 5791*32b31808SJens Wiklander { 5792*32b31808SJens Wiklander ssl->transform_out = transform; 5793*32b31808SJens Wiklander memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr)); 5794*32b31808SJens Wiklander } 5795*32b31808SJens Wiklander 579611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 579711fa71b9SJerome Forissier 579811fa71b9SJerome Forissier void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl) 579911fa71b9SJerome Forissier { 580011fa71b9SJerome Forissier unsigned offset; 580111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 580211fa71b9SJerome Forissier 5803*32b31808SJens Wiklander if (hs == NULL) { 580411fa71b9SJerome Forissier return; 5805*32b31808SJens Wiklander } 580611fa71b9SJerome Forissier 580711fa71b9SJerome Forissier ssl_free_buffered_record(ssl); 580811fa71b9SJerome Forissier 5809*32b31808SJens Wiklander for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) { 581011fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, offset); 581111fa71b9SJerome Forissier } 5812*32b31808SJens Wiklander } 581311fa71b9SJerome Forissier 581411fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, 581511fa71b9SJerome Forissier uint8_t slot) 581611fa71b9SJerome Forissier { 581711fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 581811fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; 581911fa71b9SJerome Forissier 5820*32b31808SJens Wiklander if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS) { 582111fa71b9SJerome Forissier return; 5822*32b31808SJens Wiklander } 582311fa71b9SJerome Forissier 5824*32b31808SJens Wiklander if (hs_buf->is_valid == 1) { 582511fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= hs_buf->data_len; 582611fa71b9SJerome Forissier mbedtls_platform_zeroize(hs_buf->data, hs_buf->data_len); 582711fa71b9SJerome Forissier mbedtls_free(hs_buf->data); 582811fa71b9SJerome Forissier memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); 582911fa71b9SJerome Forissier } 583011fa71b9SJerome Forissier } 583111fa71b9SJerome Forissier 583211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 583311fa71b9SJerome Forissier 583411fa71b9SJerome Forissier /* 583511fa71b9SJerome Forissier * Convert version numbers to/from wire format 583611fa71b9SJerome Forissier * and, for DTLS, to/from TLS equivalent. 583711fa71b9SJerome Forissier * 583811fa71b9SJerome Forissier * For TLS this is the identity. 5839*32b31808SJens Wiklander * For DTLS, map as follows, then use 1's complement (v -> ~v): 584011fa71b9SJerome Forissier * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) 5841*32b31808SJens Wiklander * DTLS 1.0 is stored as TLS 1.1 internally 584211fa71b9SJerome Forissier */ 5843*32b31808SJens Wiklander void mbedtls_ssl_write_version(unsigned char version[2], int transport, 5844*32b31808SJens Wiklander mbedtls_ssl_protocol_version tls_version) 584511fa71b9SJerome Forissier { 584611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5847*32b31808SJens Wiklander if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 5848*32b31808SJens Wiklander tls_version = 5849*32b31808SJens Wiklander ~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201)); 585011fa71b9SJerome Forissier } 585111fa71b9SJerome Forissier #else 585211fa71b9SJerome Forissier ((void) transport); 585311fa71b9SJerome Forissier #endif 5854*32b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(tls_version, version, 0); 585511fa71b9SJerome Forissier } 585611fa71b9SJerome Forissier 5857*32b31808SJens Wiklander uint16_t mbedtls_ssl_read_version(const unsigned char version[2], 5858*32b31808SJens Wiklander int transport) 585911fa71b9SJerome Forissier { 5860*32b31808SJens Wiklander uint16_t tls_version = MBEDTLS_GET_UINT16_BE(version, 0); 586111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 5862*32b31808SJens Wiklander if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 5863*32b31808SJens Wiklander tls_version = 5864*32b31808SJens Wiklander ~(tls_version - (tls_version == 0xfeff ? 0x0202 : 0x0201)); 586511fa71b9SJerome Forissier } 586611fa71b9SJerome Forissier #else 586711fa71b9SJerome Forissier ((void) transport); 586811fa71b9SJerome Forissier #endif 5869*32b31808SJens Wiklander return tls_version; 587011fa71b9SJerome Forissier } 5871*32b31808SJens Wiklander 5872*32b31808SJens Wiklander /* 5873*32b31808SJens Wiklander * Send pending fatal alert. 5874*32b31808SJens Wiklander * 0, No alert message. 5875*32b31808SJens Wiklander * !0, if mbedtls_ssl_send_alert_message() returned in error, the error code it 5876*32b31808SJens Wiklander * returned, ssl->alert_reason otherwise. 5877*32b31808SJens Wiklander */ 5878*32b31808SJens Wiklander int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl) 5879*32b31808SJens Wiklander { 5880*32b31808SJens Wiklander int ret; 5881*32b31808SJens Wiklander 5882*32b31808SJens Wiklander /* No pending alert, return success*/ 5883*32b31808SJens Wiklander if (ssl->send_alert == 0) { 5884*32b31808SJens Wiklander return 0; 5885*32b31808SJens Wiklander } 5886*32b31808SJens Wiklander 5887*32b31808SJens Wiklander ret = mbedtls_ssl_send_alert_message(ssl, 5888*32b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL, 5889*32b31808SJens Wiklander ssl->alert_type); 5890*32b31808SJens Wiklander 5891*32b31808SJens Wiklander /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE, 5892*32b31808SJens Wiklander * do not clear the alert to be able to send it later. 5893*32b31808SJens Wiklander */ 5894*32b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_WANT_WRITE) { 5895*32b31808SJens Wiklander ssl->send_alert = 0; 5896*32b31808SJens Wiklander } 5897*32b31808SJens Wiklander 5898*32b31808SJens Wiklander if (ret != 0) { 5899*32b31808SJens Wiklander return ret; 5900*32b31808SJens Wiklander } 5901*32b31808SJens Wiklander 5902*32b31808SJens Wiklander return ssl->alert_reason; 5903*32b31808SJens Wiklander } 5904*32b31808SJens Wiklander 5905*32b31808SJens Wiklander /* 5906*32b31808SJens Wiklander * Set pending fatal alert flag. 5907*32b31808SJens Wiklander */ 5908*32b31808SJens Wiklander void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl, 5909*32b31808SJens Wiklander unsigned char alert_type, 5910*32b31808SJens Wiklander int alert_reason) 5911*32b31808SJens Wiklander { 5912*32b31808SJens Wiklander ssl->send_alert = 1; 5913*32b31808SJens Wiklander ssl->alert_type = alert_type; 5914*32b31808SJens Wiklander ssl->alert_reason = alert_reason; 591511fa71b9SJerome Forissier } 591611fa71b9SJerome Forissier 591711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */ 5918