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 * The SSL 3.0 specification was drafted by Netscape in 1996, 2211fa71b9SJerome Forissier * and became an IETF standard in 1999. 2311fa71b9SJerome Forissier * 2411fa71b9SJerome Forissier * http://wp.netscape.com/eng/ssl3/ 2511fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc2246.txt 2611fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc4346.txt 2711fa71b9SJerome Forissier */ 2811fa71b9SJerome Forissier 297901324dSJerome Forissier #include "common.h" 3011fa71b9SJerome Forissier 3111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_TLS_C) 3211fa71b9SJerome Forissier 3311fa71b9SJerome Forissier #if defined(MBEDTLS_PLATFORM_C) 3411fa71b9SJerome Forissier #include "mbedtls/platform.h" 3511fa71b9SJerome Forissier #else 3611fa71b9SJerome Forissier #include <stdlib.h> 3711fa71b9SJerome Forissier #define mbedtls_calloc calloc 3811fa71b9SJerome Forissier #define mbedtls_free free 3911fa71b9SJerome Forissier #endif 4011fa71b9SJerome Forissier 4111fa71b9SJerome Forissier #include "mbedtls/ssl.h" 4211fa71b9SJerome Forissier #include "mbedtls/ssl_internal.h" 4311fa71b9SJerome Forissier #include "mbedtls/debug.h" 4411fa71b9SJerome Forissier #include "mbedtls/error.h" 4511fa71b9SJerome Forissier #include "mbedtls/platform_util.h" 4611fa71b9SJerome Forissier #include "mbedtls/version.h" 47*039e02dfSJerome Forissier #include "constant_time_internal.h" 48*039e02dfSJerome Forissier #include "mbedtls/constant_time.h" 497901324dSJerome Forissier 5011fa71b9SJerome Forissier #include <string.h> 5111fa71b9SJerome Forissier 5211fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO) 5311fa71b9SJerome Forissier #include "mbedtls/psa_util.h" 5411fa71b9SJerome Forissier #include "psa/crypto.h" 5511fa71b9SJerome Forissier #endif 5611fa71b9SJerome Forissier 5711fa71b9SJerome Forissier #if defined(MBEDTLS_X509_CRT_PARSE_C) 5811fa71b9SJerome Forissier #include "mbedtls/oid.h" 5911fa71b9SJerome Forissier #endif 6011fa71b9SJerome Forissier 6111fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ); 6211fa71b9SJerome Forissier 6311fa71b9SJerome Forissier /* 6411fa71b9SJerome Forissier * Start a timer. 6511fa71b9SJerome Forissier * Passing millisecs = 0 cancels a running timer. 6611fa71b9SJerome Forissier */ 6711fa71b9SJerome Forissier void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) 6811fa71b9SJerome Forissier { 6911fa71b9SJerome Forissier if( ssl->f_set_timer == NULL ) 7011fa71b9SJerome Forissier return; 7111fa71b9SJerome Forissier 7211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); 7311fa71b9SJerome Forissier ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); 7411fa71b9SJerome Forissier } 7511fa71b9SJerome Forissier 7611fa71b9SJerome Forissier /* 7711fa71b9SJerome Forissier * Return -1 is timer is expired, 0 if it isn't. 7811fa71b9SJerome Forissier */ 7911fa71b9SJerome Forissier int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl ) 8011fa71b9SJerome Forissier { 8111fa71b9SJerome Forissier if( ssl->f_get_timer == NULL ) 8211fa71b9SJerome Forissier return( 0 ); 8311fa71b9SJerome Forissier 8411fa71b9SJerome Forissier if( ssl->f_get_timer( ssl->p_timer ) == 2 ) 8511fa71b9SJerome Forissier { 8611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); 8711fa71b9SJerome Forissier return( -1 ); 8811fa71b9SJerome Forissier } 8911fa71b9SJerome Forissier 9011fa71b9SJerome Forissier return( 0 ); 9111fa71b9SJerome Forissier } 9211fa71b9SJerome Forissier 9311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RECORD_CHECKING) 94*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 9511fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, 9611fa71b9SJerome Forissier unsigned char *buf, 9711fa71b9SJerome Forissier size_t len, 9811fa71b9SJerome Forissier mbedtls_record *rec ); 9911fa71b9SJerome Forissier 10011fa71b9SJerome Forissier int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, 10111fa71b9SJerome Forissier unsigned char *buf, 10211fa71b9SJerome Forissier size_t buflen ) 10311fa71b9SJerome Forissier { 10411fa71b9SJerome Forissier int ret = 0; 10511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) ); 10611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen ); 10711fa71b9SJerome Forissier 10811fa71b9SJerome Forissier /* We don't support record checking in TLS because 10911fa71b9SJerome Forissier * (a) there doesn't seem to be a usecase for it, and 11011fa71b9SJerome Forissier * (b) In SSLv3 and TLS 1.0, CBC record decryption has state 11111fa71b9SJerome Forissier * and we'd need to backup the transform here. 11211fa71b9SJerome Forissier */ 11311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) 11411fa71b9SJerome Forissier { 11511fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 11611fa71b9SJerome Forissier goto exit; 11711fa71b9SJerome Forissier } 11811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 11911fa71b9SJerome Forissier else 12011fa71b9SJerome Forissier { 12111fa71b9SJerome Forissier mbedtls_record rec; 12211fa71b9SJerome Forissier 12311fa71b9SJerome Forissier ret = ssl_parse_record_header( ssl, buf, buflen, &rec ); 12411fa71b9SJerome Forissier if( ret != 0 ) 12511fa71b9SJerome Forissier { 12611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret ); 12711fa71b9SJerome Forissier goto exit; 12811fa71b9SJerome Forissier } 12911fa71b9SJerome Forissier 13011fa71b9SJerome Forissier if( ssl->transform_in != NULL ) 13111fa71b9SJerome Forissier { 13211fa71b9SJerome Forissier ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec ); 13311fa71b9SJerome Forissier if( ret != 0 ) 13411fa71b9SJerome Forissier { 13511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret ); 13611fa71b9SJerome Forissier goto exit; 13711fa71b9SJerome Forissier } 13811fa71b9SJerome Forissier } 13911fa71b9SJerome Forissier } 14011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 14111fa71b9SJerome Forissier 14211fa71b9SJerome Forissier exit: 14311fa71b9SJerome Forissier /* On success, we have decrypted the buffer in-place, so make 14411fa71b9SJerome Forissier * sure we don't leak any plaintext data. */ 14511fa71b9SJerome Forissier mbedtls_platform_zeroize( buf, buflen ); 14611fa71b9SJerome Forissier 14711fa71b9SJerome Forissier /* For the purpose of this API, treat messages with unexpected CID 14811fa71b9SJerome Forissier * as well as such from future epochs as unexpected. */ 14911fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID || 15011fa71b9SJerome Forissier ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 15111fa71b9SJerome Forissier { 15211fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 15311fa71b9SJerome Forissier } 15411fa71b9SJerome Forissier 15511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) ); 15611fa71b9SJerome Forissier return( ret ); 15711fa71b9SJerome Forissier } 15811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RECORD_CHECKING */ 15911fa71b9SJerome Forissier 16011fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0 16111fa71b9SJerome Forissier #define SSL_FORCE_FLUSH 1 16211fa71b9SJerome Forissier 16311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 16411fa71b9SJerome Forissier 16511fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */ 16611fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, 16711fa71b9SJerome Forissier uint8_t slot ); 16811fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); 169*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 17011fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); 171*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 17211fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); 173*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 17411fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl ); 175*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 17611fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, 17711fa71b9SJerome Forissier mbedtls_record const *rec ); 178*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 17911fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); 18011fa71b9SJerome Forissier 18111fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) 18211fa71b9SJerome Forissier { 18311fa71b9SJerome Forissier size_t mtu = mbedtls_ssl_get_current_mtu( ssl ); 18411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 18511fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 18611fa71b9SJerome Forissier #else 18711fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 18811fa71b9SJerome Forissier #endif 18911fa71b9SJerome Forissier 19011fa71b9SJerome Forissier if( mtu != 0 && mtu < out_buf_len ) 19111fa71b9SJerome Forissier return( mtu ); 19211fa71b9SJerome Forissier 19311fa71b9SJerome Forissier return( out_buf_len ); 19411fa71b9SJerome Forissier } 19511fa71b9SJerome Forissier 196*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 19711fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) 19811fa71b9SJerome Forissier { 19911fa71b9SJerome Forissier size_t const bytes_written = ssl->out_left; 20011fa71b9SJerome Forissier size_t const mtu = ssl_get_maximum_datagram_size( ssl ); 20111fa71b9SJerome Forissier 20211fa71b9SJerome Forissier /* Double-check that the write-index hasn't gone 20311fa71b9SJerome Forissier * past what we can transmit in a single datagram. */ 20411fa71b9SJerome Forissier if( bytes_written > mtu ) 20511fa71b9SJerome Forissier { 20611fa71b9SJerome Forissier /* Should never happen... */ 20711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 20811fa71b9SJerome Forissier } 20911fa71b9SJerome Forissier 21011fa71b9SJerome Forissier return( (int) ( mtu - bytes_written ) ); 21111fa71b9SJerome Forissier } 21211fa71b9SJerome Forissier 213*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 21411fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) 21511fa71b9SJerome Forissier { 21611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 21711fa71b9SJerome Forissier size_t remaining, expansion; 21811fa71b9SJerome Forissier size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; 21911fa71b9SJerome Forissier 22011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 22111fa71b9SJerome Forissier const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl ); 22211fa71b9SJerome Forissier 22311fa71b9SJerome Forissier if( max_len > mfl ) 22411fa71b9SJerome Forissier max_len = mfl; 22511fa71b9SJerome Forissier 22611fa71b9SJerome Forissier /* By the standard (RFC 6066 Sect. 4), the MFL extension 22711fa71b9SJerome Forissier * only limits the maximum record payload size, so in theory 22811fa71b9SJerome Forissier * we would be allowed to pack multiple records of payload size 22911fa71b9SJerome Forissier * MFL into a single datagram. However, this would mean that there's 23011fa71b9SJerome Forissier * no way to explicitly communicate MTU restrictions to the peer. 23111fa71b9SJerome Forissier * 23211fa71b9SJerome Forissier * The following reduction of max_len makes sure that we never 23311fa71b9SJerome Forissier * write datagrams larger than MFL + Record Expansion Overhead. 23411fa71b9SJerome Forissier */ 23511fa71b9SJerome Forissier if( max_len <= ssl->out_left ) 23611fa71b9SJerome Forissier return( 0 ); 23711fa71b9SJerome Forissier 23811fa71b9SJerome Forissier max_len -= ssl->out_left; 23911fa71b9SJerome Forissier #endif 24011fa71b9SJerome Forissier 24111fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram( ssl ); 24211fa71b9SJerome Forissier if( ret < 0 ) 24311fa71b9SJerome Forissier return( ret ); 24411fa71b9SJerome Forissier remaining = (size_t) ret; 24511fa71b9SJerome Forissier 24611fa71b9SJerome Forissier ret = mbedtls_ssl_get_record_expansion( ssl ); 24711fa71b9SJerome Forissier if( ret < 0 ) 24811fa71b9SJerome Forissier return( ret ); 24911fa71b9SJerome Forissier expansion = (size_t) ret; 25011fa71b9SJerome Forissier 25111fa71b9SJerome Forissier if( remaining <= expansion ) 25211fa71b9SJerome Forissier return( 0 ); 25311fa71b9SJerome Forissier 25411fa71b9SJerome Forissier remaining -= expansion; 25511fa71b9SJerome Forissier if( remaining >= max_len ) 25611fa71b9SJerome Forissier remaining = max_len; 25711fa71b9SJerome Forissier 25811fa71b9SJerome Forissier return( (int) remaining ); 25911fa71b9SJerome Forissier } 26011fa71b9SJerome Forissier 26111fa71b9SJerome Forissier /* 26211fa71b9SJerome Forissier * Double the retransmit timeout value, within the allowed range, 26311fa71b9SJerome Forissier * returning -1 if the maximum value has already been reached. 26411fa71b9SJerome Forissier */ 265*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 26611fa71b9SJerome Forissier static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) 26711fa71b9SJerome Forissier { 26811fa71b9SJerome Forissier uint32_t new_timeout; 26911fa71b9SJerome Forissier 27011fa71b9SJerome Forissier if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) 27111fa71b9SJerome Forissier return( -1 ); 27211fa71b9SJerome Forissier 27311fa71b9SJerome Forissier /* Implement the final paragraph of RFC 6347 section 4.1.1.1 27411fa71b9SJerome Forissier * in the following way: after the initial transmission and a first 27511fa71b9SJerome Forissier * retransmission, back off to a temporary estimated MTU of 508 bytes. 27611fa71b9SJerome Forissier * This value is guaranteed to be deliverable (if not guaranteed to be 27711fa71b9SJerome Forissier * delivered) of any compliant IPv4 (and IPv6) network, and should work 27811fa71b9SJerome Forissier * on most non-IP stacks too. */ 27911fa71b9SJerome Forissier if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) 28011fa71b9SJerome Forissier { 28111fa71b9SJerome Forissier ssl->handshake->mtu = 508; 28211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); 28311fa71b9SJerome Forissier } 28411fa71b9SJerome Forissier 28511fa71b9SJerome Forissier new_timeout = 2 * ssl->handshake->retransmit_timeout; 28611fa71b9SJerome Forissier 28711fa71b9SJerome Forissier /* Avoid arithmetic overflow and range overflow */ 28811fa71b9SJerome Forissier if( new_timeout < ssl->handshake->retransmit_timeout || 28911fa71b9SJerome Forissier new_timeout > ssl->conf->hs_timeout_max ) 29011fa71b9SJerome Forissier { 29111fa71b9SJerome Forissier new_timeout = ssl->conf->hs_timeout_max; 29211fa71b9SJerome Forissier } 29311fa71b9SJerome Forissier 29411fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = new_timeout; 2957901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs", 2967901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout ) ); 29711fa71b9SJerome Forissier 29811fa71b9SJerome Forissier return( 0 ); 29911fa71b9SJerome Forissier } 30011fa71b9SJerome Forissier 30111fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) 30211fa71b9SJerome Forissier { 30311fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; 3047901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs", 3057901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout ) ); 30611fa71b9SJerome Forissier } 30711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 30811fa71b9SJerome Forissier 30911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 31011fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, 31111fa71b9SJerome Forissier const unsigned char *key_enc, const unsigned char *key_dec, 31211fa71b9SJerome Forissier size_t keylen, 31311fa71b9SJerome Forissier const unsigned char *iv_enc, const unsigned char *iv_dec, 31411fa71b9SJerome Forissier size_t ivlen, 31511fa71b9SJerome Forissier const unsigned char *mac_enc, const unsigned char *mac_dec, 31611fa71b9SJerome Forissier size_t maclen ) = NULL; 31711fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; 31811fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; 31911fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; 32011fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; 32111fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; 32211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 32311fa71b9SJerome Forissier 32411fa71b9SJerome Forissier /* 32511fa71b9SJerome Forissier * Encryption/decryption functions 32611fa71b9SJerome Forissier */ 32711fa71b9SJerome Forissier 3287901324dSJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \ 3297901324dSJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 3307901324dSJerome Forissier 3317901324dSJerome Forissier static size_t ssl_compute_padding_length( size_t len, 3327901324dSJerome Forissier size_t granularity ) 3337901324dSJerome Forissier { 3347901324dSJerome Forissier return( ( granularity - ( len + 1 ) % granularity ) % granularity ); 3357901324dSJerome Forissier } 3367901324dSJerome Forissier 3377901324dSJerome Forissier /* This functions transforms a (D)TLS plaintext fragment and a record content 3387901324dSJerome Forissier * type into an instance of the (D)TLSInnerPlaintext structure. This is used 3397901324dSJerome Forissier * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect 3407901324dSJerome Forissier * a record's content type. 34111fa71b9SJerome Forissier * 34211fa71b9SJerome Forissier * struct { 34311fa71b9SJerome Forissier * opaque content[DTLSPlaintext.length]; 34411fa71b9SJerome Forissier * ContentType real_type; 34511fa71b9SJerome Forissier * uint8 zeros[length_of_padding]; 3467901324dSJerome Forissier * } (D)TLSInnerPlaintext; 34711fa71b9SJerome Forissier * 34811fa71b9SJerome Forissier * Input: 34911fa71b9SJerome Forissier * - `content`: The beginning of the buffer holding the 35011fa71b9SJerome Forissier * plaintext to be wrapped. 35111fa71b9SJerome Forissier * - `*content_size`: The length of the plaintext in Bytes. 35211fa71b9SJerome Forissier * - `max_len`: The number of Bytes available starting from 35311fa71b9SJerome Forissier * `content`. This must be `>= *content_size`. 35411fa71b9SJerome Forissier * - `rec_type`: The desired record content type. 35511fa71b9SJerome Forissier * 35611fa71b9SJerome Forissier * Output: 3577901324dSJerome Forissier * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure. 3587901324dSJerome Forissier * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure. 35911fa71b9SJerome Forissier * 36011fa71b9SJerome Forissier * Returns: 36111fa71b9SJerome Forissier * - `0` on success. 36211fa71b9SJerome Forissier * - A negative error code if `max_len` didn't offer enough space 36311fa71b9SJerome Forissier * for the expansion. 36411fa71b9SJerome Forissier */ 365*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3667901324dSJerome Forissier static int ssl_build_inner_plaintext( unsigned char *content, 36711fa71b9SJerome Forissier size_t *content_size, 36811fa71b9SJerome Forissier size_t remaining, 3697901324dSJerome Forissier uint8_t rec_type, 3707901324dSJerome Forissier size_t pad ) 37111fa71b9SJerome Forissier { 37211fa71b9SJerome Forissier size_t len = *content_size; 37311fa71b9SJerome Forissier 37411fa71b9SJerome Forissier /* Write real content type */ 37511fa71b9SJerome Forissier if( remaining == 0 ) 37611fa71b9SJerome Forissier return( -1 ); 37711fa71b9SJerome Forissier content[ len ] = rec_type; 37811fa71b9SJerome Forissier len++; 37911fa71b9SJerome Forissier remaining--; 38011fa71b9SJerome Forissier 38111fa71b9SJerome Forissier if( remaining < pad ) 38211fa71b9SJerome Forissier return( -1 ); 38311fa71b9SJerome Forissier memset( content + len, 0, pad ); 38411fa71b9SJerome Forissier len += pad; 38511fa71b9SJerome Forissier remaining -= pad; 38611fa71b9SJerome Forissier 38711fa71b9SJerome Forissier *content_size = len; 38811fa71b9SJerome Forissier return( 0 ); 38911fa71b9SJerome Forissier } 39011fa71b9SJerome Forissier 3917901324dSJerome Forissier /* This function parses a (D)TLSInnerPlaintext structure. 3927901324dSJerome Forissier * See ssl_build_inner_plaintext() for details. */ 393*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3947901324dSJerome Forissier static int ssl_parse_inner_plaintext( unsigned char const *content, 39511fa71b9SJerome Forissier size_t *content_size, 39611fa71b9SJerome Forissier uint8_t *rec_type ) 39711fa71b9SJerome Forissier { 39811fa71b9SJerome Forissier size_t remaining = *content_size; 39911fa71b9SJerome Forissier 40011fa71b9SJerome Forissier /* Determine length of padding by skipping zeroes from the back. */ 40111fa71b9SJerome Forissier do 40211fa71b9SJerome Forissier { 40311fa71b9SJerome Forissier if( remaining == 0 ) 40411fa71b9SJerome Forissier return( -1 ); 40511fa71b9SJerome Forissier remaining--; 40611fa71b9SJerome Forissier } while( content[ remaining ] == 0 ); 40711fa71b9SJerome Forissier 40811fa71b9SJerome Forissier *content_size = remaining; 40911fa71b9SJerome Forissier *rec_type = content[ remaining ]; 41011fa71b9SJerome Forissier 41111fa71b9SJerome Forissier return( 0 ); 41211fa71b9SJerome Forissier } 4137901324dSJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || 4147901324dSJerome Forissier MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 41511fa71b9SJerome Forissier 41611fa71b9SJerome Forissier /* `add_data` must have size 13 Bytes if the CID extension is disabled, 41711fa71b9SJerome Forissier * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */ 41811fa71b9SJerome Forissier static void ssl_extract_add_data_from_record( unsigned char* add_data, 41911fa71b9SJerome Forissier size_t *add_data_len, 4207901324dSJerome Forissier mbedtls_record *rec, 4217901324dSJerome Forissier unsigned minor_ver ) 42211fa71b9SJerome Forissier { 42311fa71b9SJerome Forissier /* Quoting RFC 5246 (TLS 1.2): 42411fa71b9SJerome Forissier * 42511fa71b9SJerome Forissier * additional_data = seq_num + TLSCompressed.type + 42611fa71b9SJerome Forissier * TLSCompressed.version + TLSCompressed.length; 42711fa71b9SJerome Forissier * 42811fa71b9SJerome Forissier * For the CID extension, this is extended as follows 42911fa71b9SJerome Forissier * (quoting draft-ietf-tls-dtls-connection-id-05, 43011fa71b9SJerome Forissier * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05): 43111fa71b9SJerome Forissier * 43211fa71b9SJerome Forissier * additional_data = seq_num + DTLSPlaintext.type + 43311fa71b9SJerome Forissier * DTLSPlaintext.version + 43411fa71b9SJerome Forissier * cid + 43511fa71b9SJerome Forissier * cid_length + 43611fa71b9SJerome Forissier * length_of_DTLSInnerPlaintext; 4377901324dSJerome Forissier * 4387901324dSJerome Forissier * For TLS 1.3, the record sequence number is dropped from the AAD 4397901324dSJerome Forissier * and encoded within the nonce of the AEAD operation instead. 44011fa71b9SJerome Forissier */ 44111fa71b9SJerome Forissier 4427901324dSJerome Forissier unsigned char *cur = add_data; 4437901324dSJerome Forissier 4447901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 4457901324dSJerome Forissier if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) 4467901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 4477901324dSJerome Forissier { 4487901324dSJerome Forissier ((void) minor_ver); 4497901324dSJerome Forissier memcpy( cur, rec->ctr, sizeof( rec->ctr ) ); 4507901324dSJerome Forissier cur += sizeof( rec->ctr ); 4517901324dSJerome Forissier } 4527901324dSJerome Forissier 4537901324dSJerome Forissier *cur = rec->type; 4547901324dSJerome Forissier cur++; 4557901324dSJerome Forissier 4567901324dSJerome Forissier memcpy( cur, rec->ver, sizeof( rec->ver ) ); 4577901324dSJerome Forissier cur += sizeof( rec->ver ); 45811fa71b9SJerome Forissier 45911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 46011fa71b9SJerome Forissier if( rec->cid_len != 0 ) 46111fa71b9SJerome Forissier { 4627901324dSJerome Forissier memcpy( cur, rec->cid, rec->cid_len ); 4637901324dSJerome Forissier cur += rec->cid_len; 4647901324dSJerome Forissier 4657901324dSJerome Forissier *cur = rec->cid_len; 4667901324dSJerome Forissier cur++; 4677901324dSJerome Forissier 468*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 ); 4697901324dSJerome Forissier cur += 2; 47011fa71b9SJerome Forissier } 47111fa71b9SJerome Forissier else 47211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 47311fa71b9SJerome Forissier { 474*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 ); 4757901324dSJerome Forissier cur += 2; 47611fa71b9SJerome Forissier } 4777901324dSJerome Forissier 4787901324dSJerome Forissier *add_data_len = cur - add_data; 47911fa71b9SJerome Forissier } 48011fa71b9SJerome Forissier 48111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 48211fa71b9SJerome Forissier 48311fa71b9SJerome Forissier #define SSL3_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */ 48411fa71b9SJerome Forissier 48511fa71b9SJerome Forissier /* 48611fa71b9SJerome Forissier * SSLv3.0 MAC functions 48711fa71b9SJerome Forissier */ 488*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 489*039e02dfSJerome Forissier static int ssl_mac( mbedtls_md_context_t *md_ctx, 49011fa71b9SJerome Forissier const unsigned char *secret, 49111fa71b9SJerome Forissier const unsigned char *buf, size_t len, 49211fa71b9SJerome Forissier const unsigned char *ctr, int type, 49311fa71b9SJerome Forissier unsigned char out[SSL3_MAC_MAX_BYTES] ) 49411fa71b9SJerome Forissier { 49511fa71b9SJerome Forissier unsigned char header[11]; 49611fa71b9SJerome Forissier unsigned char padding[48]; 49711fa71b9SJerome Forissier int padlen; 49811fa71b9SJerome Forissier int md_size = mbedtls_md_get_size( md_ctx->md_info ); 49911fa71b9SJerome Forissier int md_type = mbedtls_md_get_type( md_ctx->md_info ); 500*039e02dfSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 50111fa71b9SJerome Forissier 50211fa71b9SJerome Forissier /* Only MD5 and SHA-1 supported */ 50311fa71b9SJerome Forissier if( md_type == MBEDTLS_MD_MD5 ) 50411fa71b9SJerome Forissier padlen = 48; 50511fa71b9SJerome Forissier else 50611fa71b9SJerome Forissier padlen = 40; 50711fa71b9SJerome Forissier 50811fa71b9SJerome Forissier memcpy( header, ctr, 8 ); 50911fa71b9SJerome Forissier header[8] = (unsigned char) type; 510*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( len, header, 9); 51111fa71b9SJerome Forissier 51211fa71b9SJerome Forissier memset( padding, 0x36, padlen ); 513*039e02dfSJerome Forissier ret = mbedtls_md_starts( md_ctx ); 514*039e02dfSJerome Forissier if( ret != 0 ) 515*039e02dfSJerome Forissier return( ret ); 516*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, secret, md_size ); 517*039e02dfSJerome Forissier if( ret != 0 ) 518*039e02dfSJerome Forissier return( ret ); 519*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, padding, padlen ); 520*039e02dfSJerome Forissier if( ret != 0 ) 521*039e02dfSJerome Forissier return( ret ); 522*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, header, 11 ); 523*039e02dfSJerome Forissier if( ret != 0 ) 524*039e02dfSJerome Forissier return( ret ); 525*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, buf, len ); 526*039e02dfSJerome Forissier if( ret != 0 ) 527*039e02dfSJerome Forissier return( ret ); 528*039e02dfSJerome Forissier ret = mbedtls_md_finish( md_ctx, out ); 529*039e02dfSJerome Forissier if( ret != 0 ) 530*039e02dfSJerome Forissier return( ret ); 53111fa71b9SJerome Forissier 53211fa71b9SJerome Forissier memset( padding, 0x5C, padlen ); 533*039e02dfSJerome Forissier ret = mbedtls_md_starts( md_ctx ); 534*039e02dfSJerome Forissier if( ret != 0 ) 535*039e02dfSJerome Forissier return( ret ); 536*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, secret, md_size ); 537*039e02dfSJerome Forissier if( ret != 0 ) 538*039e02dfSJerome Forissier return( ret ); 539*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, padding, padlen ); 540*039e02dfSJerome Forissier if( ret != 0 ) 541*039e02dfSJerome Forissier return( ret ); 542*039e02dfSJerome Forissier ret = mbedtls_md_update( md_ctx, out, md_size ); 543*039e02dfSJerome Forissier if( ret != 0 ) 544*039e02dfSJerome Forissier return( ret ); 545*039e02dfSJerome Forissier ret = mbedtls_md_finish( md_ctx, out ); 546*039e02dfSJerome Forissier if( ret != 0 ) 547*039e02dfSJerome Forissier return( ret ); 548*039e02dfSJerome Forissier 549*039e02dfSJerome Forissier return( 0 ); 55011fa71b9SJerome Forissier } 55111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 55211fa71b9SJerome Forissier 5537901324dSJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 5547901324dSJerome Forissier defined(MBEDTLS_CCM_C) || \ 5557901324dSJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 556*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 5577901324dSJerome Forissier static int ssl_transform_aead_dynamic_iv_is_explicit( 5587901324dSJerome Forissier mbedtls_ssl_transform const *transform ) 5597901324dSJerome Forissier { 5607901324dSJerome Forissier return( transform->ivlen != transform->fixed_ivlen ); 5617901324dSJerome Forissier } 5627901324dSJerome Forissier 5637901324dSJerome Forissier /* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV ) 5647901324dSJerome Forissier * 5657901324dSJerome Forissier * Concretely, this occurs in two variants: 5667901324dSJerome Forissier * 5677901324dSJerome Forissier * a) Fixed and dynamic IV lengths add up to total IV length, giving 5687901324dSJerome Forissier * IV = fixed_iv || dynamic_iv 5697901324dSJerome Forissier * 5707901324dSJerome Forissier * This variant is used in TLS 1.2 when used with GCM or CCM. 5717901324dSJerome Forissier * 5727901324dSJerome Forissier * b) Fixed IV lengths matches total IV length, giving 5737901324dSJerome Forissier * IV = fixed_iv XOR ( 0 || dynamic_iv ) 5747901324dSJerome Forissier * 5757901324dSJerome Forissier * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly. 5767901324dSJerome Forissier * 5777901324dSJerome Forissier * See also the documentation of mbedtls_ssl_transform. 5787901324dSJerome Forissier * 5797901324dSJerome Forissier * This function has the precondition that 5807901324dSJerome Forissier * 5817901324dSJerome Forissier * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len ) 5827901324dSJerome Forissier * 5837901324dSJerome Forissier * which has to be ensured by the caller. If this precondition 5847901324dSJerome Forissier * violated, the behavior of this function is undefined. 5857901324dSJerome Forissier */ 5867901324dSJerome Forissier static void ssl_build_record_nonce( unsigned char *dst_iv, 5877901324dSJerome Forissier size_t dst_iv_len, 5887901324dSJerome Forissier unsigned char const *fixed_iv, 5897901324dSJerome Forissier size_t fixed_iv_len, 5907901324dSJerome Forissier unsigned char const *dynamic_iv, 5917901324dSJerome Forissier size_t dynamic_iv_len ) 5927901324dSJerome Forissier { 5937901324dSJerome Forissier size_t i; 5947901324dSJerome Forissier 5957901324dSJerome Forissier /* Start with Fixed IV || 0 */ 5967901324dSJerome Forissier memset( dst_iv, 0, dst_iv_len ); 5977901324dSJerome Forissier memcpy( dst_iv, fixed_iv, fixed_iv_len ); 5987901324dSJerome Forissier 5997901324dSJerome Forissier dst_iv += dst_iv_len - dynamic_iv_len; 6007901324dSJerome Forissier for( i = 0; i < dynamic_iv_len; i++ ) 6017901324dSJerome Forissier dst_iv[i] ^= dynamic_iv[i]; 6027901324dSJerome Forissier } 6037901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 6047901324dSJerome Forissier 60511fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, 60611fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 60711fa71b9SJerome Forissier mbedtls_record *rec, 60811fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), 60911fa71b9SJerome Forissier void *p_rng ) 61011fa71b9SJerome Forissier { 61111fa71b9SJerome Forissier mbedtls_cipher_mode_t mode; 61211fa71b9SJerome Forissier int auth_done = 0; 61311fa71b9SJerome Forissier unsigned char * data; 61411fa71b9SJerome Forissier unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ]; 61511fa71b9SJerome Forissier size_t add_data_len; 61611fa71b9SJerome Forissier size_t post_avail; 61711fa71b9SJerome Forissier 61811fa71b9SJerome Forissier /* The SSL context is only used for debugging purposes! */ 61911fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 62011fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 62111fa71b9SJerome Forissier ((void) ssl); 62211fa71b9SJerome Forissier #endif 62311fa71b9SJerome Forissier 62411fa71b9SJerome Forissier /* The PRNG is used for dynamic IV generation that's used 62511fa71b9SJerome Forissier * for CBC transformations in TLS 1.1 and TLS 1.2. */ 6267901324dSJerome Forissier #if !( defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ 62711fa71b9SJerome Forissier ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) ) 62811fa71b9SJerome Forissier ((void) f_rng); 62911fa71b9SJerome Forissier ((void) p_rng); 63011fa71b9SJerome Forissier #endif 63111fa71b9SJerome Forissier 63211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); 63311fa71b9SJerome Forissier 63411fa71b9SJerome Forissier if( transform == NULL ) 63511fa71b9SJerome Forissier { 63611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) ); 63711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 63811fa71b9SJerome Forissier } 63911fa71b9SJerome Forissier if( rec == NULL 64011fa71b9SJerome Forissier || rec->buf == NULL 64111fa71b9SJerome Forissier || rec->buf_len < rec->data_offset 64211fa71b9SJerome Forissier || rec->buf_len - rec->data_offset < rec->data_len 64311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 64411fa71b9SJerome Forissier || rec->cid_len != 0 64511fa71b9SJerome Forissier #endif 64611fa71b9SJerome Forissier ) 64711fa71b9SJerome Forissier { 64811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) ); 64911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 65011fa71b9SJerome Forissier } 65111fa71b9SJerome Forissier 65211fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 65311fa71b9SJerome Forissier post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); 65411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", 65511fa71b9SJerome Forissier data, rec->data_len ); 65611fa71b9SJerome Forissier 65711fa71b9SJerome Forissier mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ); 65811fa71b9SJerome Forissier 65911fa71b9SJerome Forissier if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) 66011fa71b9SJerome Forissier { 6617901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %" MBEDTLS_PRINTF_SIZET 6627901324dSJerome Forissier " too large, maximum %" MBEDTLS_PRINTF_SIZET, 6637901324dSJerome Forissier rec->data_len, 6647901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); 66511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 66611fa71b9SJerome Forissier } 66711fa71b9SJerome Forissier 6687901324dSJerome Forissier /* The following two code paths implement the (D)TLSInnerPlaintext 6697901324dSJerome Forissier * structure present in TLS 1.3 and DTLS 1.2 + CID. 6707901324dSJerome Forissier * 6717901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 6727901324dSJerome Forissier * 6737901324dSJerome Forissier * Note that this changes `rec->data_len`, and hence 6747901324dSJerome Forissier * `post_avail` needs to be recalculated afterwards. 6757901324dSJerome Forissier * 6767901324dSJerome Forissier * Note also that the two code paths cannot occur simultaneously 6777901324dSJerome Forissier * since they apply to different versions of the protocol. There 6787901324dSJerome Forissier * is hence no risk of double-addition of the inner plaintext. 6797901324dSJerome Forissier */ 6807901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 6817901324dSJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) 6827901324dSJerome Forissier { 6837901324dSJerome Forissier size_t padding = 6847901324dSJerome Forissier ssl_compute_padding_length( rec->data_len, 6857901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY ); 6867901324dSJerome Forissier if( ssl_build_inner_plaintext( data, 6877901324dSJerome Forissier &rec->data_len, 6887901324dSJerome Forissier post_avail, 6897901324dSJerome Forissier rec->type, 6907901324dSJerome Forissier padding ) != 0 ) 6917901324dSJerome Forissier { 6927901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 6937901324dSJerome Forissier } 6947901324dSJerome Forissier 6957901324dSJerome Forissier rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA; 6967901324dSJerome Forissier } 6977901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 6987901324dSJerome Forissier 69911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 70011fa71b9SJerome Forissier /* 70111fa71b9SJerome Forissier * Add CID information 70211fa71b9SJerome Forissier */ 70311fa71b9SJerome Forissier rec->cid_len = transform->out_cid_len; 70411fa71b9SJerome Forissier memcpy( rec->cid, transform->out_cid, transform->out_cid_len ); 70511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len ); 70611fa71b9SJerome Forissier 70711fa71b9SJerome Forissier if( rec->cid_len != 0 ) 70811fa71b9SJerome Forissier { 7097901324dSJerome Forissier size_t padding = 7107901324dSJerome Forissier ssl_compute_padding_length( rec->data_len, 7117901324dSJerome Forissier MBEDTLS_SSL_CID_PADDING_GRANULARITY ); 71211fa71b9SJerome Forissier /* 71311fa71b9SJerome Forissier * Wrap plaintext into DTLSInnerPlaintext structure. 7147901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 71511fa71b9SJerome Forissier * 71611fa71b9SJerome Forissier * Note that this changes `rec->data_len`, and hence 71711fa71b9SJerome Forissier * `post_avail` needs to be recalculated afterwards. 71811fa71b9SJerome Forissier */ 7197901324dSJerome Forissier if( ssl_build_inner_plaintext( data, 72011fa71b9SJerome Forissier &rec->data_len, 72111fa71b9SJerome Forissier post_avail, 7227901324dSJerome Forissier rec->type, 7237901324dSJerome Forissier padding ) != 0 ) 72411fa71b9SJerome Forissier { 72511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 72611fa71b9SJerome Forissier } 72711fa71b9SJerome Forissier 72811fa71b9SJerome Forissier rec->type = MBEDTLS_SSL_MSG_CID; 72911fa71b9SJerome Forissier } 73011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 73111fa71b9SJerome Forissier 73211fa71b9SJerome Forissier post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); 73311fa71b9SJerome Forissier 73411fa71b9SJerome Forissier /* 73511fa71b9SJerome Forissier * Add MAC before if needed 73611fa71b9SJerome Forissier */ 73711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 73811fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM || 73911fa71b9SJerome Forissier ( mode == MBEDTLS_MODE_CBC 74011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 74111fa71b9SJerome Forissier && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED 74211fa71b9SJerome Forissier #endif 74311fa71b9SJerome Forissier ) ) 74411fa71b9SJerome Forissier { 74511fa71b9SJerome Forissier if( post_avail < transform->maclen ) 74611fa71b9SJerome Forissier { 74711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 74811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 74911fa71b9SJerome Forissier } 75011fa71b9SJerome Forissier 75111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 75211fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 75311fa71b9SJerome Forissier { 75411fa71b9SJerome Forissier unsigned char mac[SSL3_MAC_MAX_BYTES]; 755*039e02dfSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 756*039e02dfSJerome Forissier ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc, 75711fa71b9SJerome Forissier data, rec->data_len, rec->ctr, rec->type, mac ); 758*039e02dfSJerome Forissier if( ret == 0 ) 75911fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 760*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac, transform->maclen ); 761*039e02dfSJerome Forissier if( ret != 0 ) 762*039e02dfSJerome Forissier { 763*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret ); 764*039e02dfSJerome Forissier return( ret ); 765*039e02dfSJerome Forissier } 76611fa71b9SJerome Forissier } 76711fa71b9SJerome Forissier else 76811fa71b9SJerome Forissier #endif 76911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 77011fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 77111fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) 77211fa71b9SJerome Forissier { 77311fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 774*039e02dfSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 77511fa71b9SJerome Forissier 7767901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 7777901324dSJerome Forissier transform->minor_ver ); 77811fa71b9SJerome Forissier 779*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, 780*039e02dfSJerome Forissier add_data, add_data_len ); 781*039e02dfSJerome Forissier if( ret != 0 ) 782*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 783*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, 78411fa71b9SJerome Forissier data, rec->data_len ); 785*039e02dfSJerome Forissier if( ret != 0 ) 786*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 787*039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); 788*039e02dfSJerome Forissier if( ret != 0 ) 789*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 790*039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc ); 791*039e02dfSJerome Forissier if( ret != 0 ) 792*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 79311fa71b9SJerome Forissier 79411fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 795*039e02dfSJerome Forissier 796*039e02dfSJerome Forissier hmac_failed_etm_disabled: 797*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac, transform->maclen ); 798*039e02dfSJerome Forissier if( ret != 0 ) 799*039e02dfSJerome Forissier { 800*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret ); 801*039e02dfSJerome Forissier return( ret ); 802*039e02dfSJerome Forissier } 80311fa71b9SJerome Forissier } 80411fa71b9SJerome Forissier else 80511fa71b9SJerome Forissier #endif 80611fa71b9SJerome Forissier { 80711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 80811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 80911fa71b9SJerome Forissier } 81011fa71b9SJerome Forissier 81111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len, 81211fa71b9SJerome Forissier transform->maclen ); 81311fa71b9SJerome Forissier 81411fa71b9SJerome Forissier rec->data_len += transform->maclen; 81511fa71b9SJerome Forissier post_avail -= transform->maclen; 81611fa71b9SJerome Forissier auth_done++; 81711fa71b9SJerome Forissier } 81811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ 81911fa71b9SJerome Forissier 82011fa71b9SJerome Forissier /* 82111fa71b9SJerome Forissier * Encrypt 82211fa71b9SJerome Forissier */ 82311fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) 82411fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM ) 82511fa71b9SJerome Forissier { 82611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 82711fa71b9SJerome Forissier size_t olen; 8287901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 82911fa71b9SJerome Forissier "including %d bytes of padding", 83011fa71b9SJerome Forissier rec->data_len, 0 ) ); 83111fa71b9SJerome Forissier 83211fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, 83311fa71b9SJerome Forissier transform->iv_enc, transform->ivlen, 83411fa71b9SJerome Forissier data, rec->data_len, 83511fa71b9SJerome Forissier data, &olen ) ) != 0 ) 83611fa71b9SJerome Forissier { 83711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 83811fa71b9SJerome Forissier return( ret ); 83911fa71b9SJerome Forissier } 84011fa71b9SJerome Forissier 84111fa71b9SJerome Forissier if( rec->data_len != olen ) 84211fa71b9SJerome Forissier { 84311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 84411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 84511fa71b9SJerome Forissier } 84611fa71b9SJerome Forissier } 84711fa71b9SJerome Forissier else 84811fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ 84911fa71b9SJerome Forissier 85011fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 85111fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 85211fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 85311fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_GCM || 85411fa71b9SJerome Forissier mode == MBEDTLS_MODE_CCM || 85511fa71b9SJerome Forissier mode == MBEDTLS_MODE_CHACHAPOLY ) 85611fa71b9SJerome Forissier { 85711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 85811fa71b9SJerome Forissier unsigned char iv[12]; 8597901324dSJerome Forissier unsigned char *dynamic_iv; 8607901324dSJerome Forissier size_t dynamic_iv_len; 8617901324dSJerome Forissier int dynamic_iv_is_explicit = 8627901324dSJerome Forissier ssl_transform_aead_dynamic_iv_is_explicit( transform ); 86311fa71b9SJerome Forissier 8647901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 8657901324dSJerome Forissier if( post_avail < transform->taglen ) 86611fa71b9SJerome Forissier { 86711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 86811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 86911fa71b9SJerome Forissier } 87011fa71b9SJerome Forissier 87111fa71b9SJerome Forissier /* 8727901324dSJerome Forissier * Build nonce for AEAD encryption. 8737901324dSJerome Forissier * 8747901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 8757901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 8767901324dSJerome Forissier * can be chosen freely - in particular, it need not 8777901324dSJerome Forissier * agree with the record sequence number. 8787901324dSJerome Forissier * However, since ChaChaPoly as well as all AEAD modes 8797901324dSJerome Forissier * in TLS 1.3 use the record sequence number as the 8807901324dSJerome Forissier * dynamic part of the nonce, we uniformly use the 8817901324dSJerome Forissier * record sequence number here in all cases. 88211fa71b9SJerome Forissier */ 8837901324dSJerome Forissier dynamic_iv = rec->ctr; 8847901324dSJerome Forissier dynamic_iv_len = sizeof( rec->ctr ); 88511fa71b9SJerome Forissier 8867901324dSJerome Forissier ssl_build_record_nonce( iv, sizeof( iv ), 8877901324dSJerome Forissier transform->iv_enc, 8887901324dSJerome Forissier transform->fixed_ivlen, 8897901324dSJerome Forissier dynamic_iv, 8907901324dSJerome Forissier dynamic_iv_len ); 89111fa71b9SJerome Forissier 8927901324dSJerome Forissier /* 8937901324dSJerome Forissier * Build additional data for AEAD encryption. 8947901324dSJerome Forissier * This depends on the TLS version. 8957901324dSJerome Forissier */ 8967901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 8977901324dSJerome Forissier transform->minor_ver ); 89811fa71b9SJerome Forissier 89911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", 90011fa71b9SJerome Forissier iv, transform->ivlen ); 90111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", 9027901324dSJerome Forissier dynamic_iv, 9037901324dSJerome Forissier dynamic_iv_is_explicit ? dynamic_iv_len : 0 ); 90411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", 90511fa71b9SJerome Forissier add_data, add_data_len ); 9067901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 90711fa71b9SJerome Forissier "including 0 bytes of padding", 90811fa71b9SJerome Forissier rec->data_len ) ); 90911fa71b9SJerome Forissier 91011fa71b9SJerome Forissier /* 91111fa71b9SJerome Forissier * Encrypt and authenticate 91211fa71b9SJerome Forissier */ 91311fa71b9SJerome Forissier 9147901324dSJerome Forissier if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc, 91511fa71b9SJerome Forissier iv, transform->ivlen, 9167901324dSJerome Forissier add_data, add_data_len, 9177901324dSJerome Forissier data, rec->data_len, /* src */ 9187901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), /* dst */ 9197901324dSJerome Forissier &rec->data_len, 9207901324dSJerome Forissier transform->taglen ) ) != 0 ) 92111fa71b9SJerome Forissier { 92211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); 92311fa71b9SJerome Forissier return( ret ); 92411fa71b9SJerome Forissier } 92511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", 9267901324dSJerome Forissier data + rec->data_len - transform->taglen, 9277901324dSJerome Forissier transform->taglen ); 9287901324dSJerome Forissier /* Account for authentication tag. */ 92911fa71b9SJerome Forissier post_avail -= transform->taglen; 9307901324dSJerome Forissier 9317901324dSJerome Forissier /* 9327901324dSJerome Forissier * Prefix record content with dynamic IV in case it is explicit. 9337901324dSJerome Forissier */ 9347901324dSJerome Forissier if( dynamic_iv_is_explicit != 0 ) 9357901324dSJerome Forissier { 9367901324dSJerome Forissier if( rec->data_offset < dynamic_iv_len ) 9377901324dSJerome Forissier { 9387901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 9397901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 9407901324dSJerome Forissier } 9417901324dSJerome Forissier 9427901324dSJerome Forissier memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len ); 9437901324dSJerome Forissier rec->data_offset -= dynamic_iv_len; 9447901324dSJerome Forissier rec->data_len += dynamic_iv_len; 9457901324dSJerome Forissier } 9467901324dSJerome Forissier 94711fa71b9SJerome Forissier auth_done++; 94811fa71b9SJerome Forissier } 94911fa71b9SJerome Forissier else 9507901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 9517901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 95211fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_CBC ) 95311fa71b9SJerome Forissier { 95411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 95511fa71b9SJerome Forissier size_t padlen, i; 95611fa71b9SJerome Forissier size_t olen; 95711fa71b9SJerome Forissier 95811fa71b9SJerome Forissier /* Currently we're always using minimal padding 95911fa71b9SJerome Forissier * (up to 255 bytes would be allowed). */ 96011fa71b9SJerome Forissier padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen; 96111fa71b9SJerome Forissier if( padlen == transform->ivlen ) 96211fa71b9SJerome Forissier padlen = 0; 96311fa71b9SJerome Forissier 96411fa71b9SJerome Forissier /* Check there's enough space in the buffer for the padding. */ 96511fa71b9SJerome Forissier if( post_avail < padlen + 1 ) 96611fa71b9SJerome Forissier { 96711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 96811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 96911fa71b9SJerome Forissier } 97011fa71b9SJerome Forissier 97111fa71b9SJerome Forissier for( i = 0; i <= padlen; i++ ) 97211fa71b9SJerome Forissier data[rec->data_len + i] = (unsigned char) padlen; 97311fa71b9SJerome Forissier 97411fa71b9SJerome Forissier rec->data_len += padlen + 1; 97511fa71b9SJerome Forissier post_avail -= padlen + 1; 97611fa71b9SJerome Forissier 97711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 97811fa71b9SJerome Forissier /* 97911fa71b9SJerome Forissier * Prepend per-record IV for block cipher in TLS v1.1 and up as per 98011fa71b9SJerome Forissier * Method 1 (6.2.3.2. in RFC4346 and RFC5246) 98111fa71b9SJerome Forissier */ 98211fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 98311fa71b9SJerome Forissier { 98411fa71b9SJerome Forissier if( f_rng == NULL ) 98511fa71b9SJerome Forissier { 98611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) ); 98711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 98811fa71b9SJerome Forissier } 98911fa71b9SJerome Forissier 99011fa71b9SJerome Forissier if( rec->data_offset < transform->ivlen ) 99111fa71b9SJerome Forissier { 99211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 99311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 99411fa71b9SJerome Forissier } 99511fa71b9SJerome Forissier 99611fa71b9SJerome Forissier /* 99711fa71b9SJerome Forissier * Generate IV 99811fa71b9SJerome Forissier */ 99911fa71b9SJerome Forissier ret = f_rng( p_rng, transform->iv_enc, transform->ivlen ); 100011fa71b9SJerome Forissier if( ret != 0 ) 100111fa71b9SJerome Forissier return( ret ); 100211fa71b9SJerome Forissier 100311fa71b9SJerome Forissier memcpy( data - transform->ivlen, transform->iv_enc, 100411fa71b9SJerome Forissier transform->ivlen ); 100511fa71b9SJerome Forissier 100611fa71b9SJerome Forissier } 100711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 100811fa71b9SJerome Forissier 10097901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 10107901324dSJerome Forissier "including %" MBEDTLS_PRINTF_SIZET 10117901324dSJerome Forissier " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding", 101211fa71b9SJerome Forissier rec->data_len, transform->ivlen, 101311fa71b9SJerome Forissier padlen + 1 ) ); 101411fa71b9SJerome Forissier 101511fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, 101611fa71b9SJerome Forissier transform->iv_enc, 101711fa71b9SJerome Forissier transform->ivlen, 101811fa71b9SJerome Forissier data, rec->data_len, 101911fa71b9SJerome Forissier data, &olen ) ) != 0 ) 102011fa71b9SJerome Forissier { 102111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 102211fa71b9SJerome Forissier return( ret ); 102311fa71b9SJerome Forissier } 102411fa71b9SJerome Forissier 102511fa71b9SJerome Forissier if( rec->data_len != olen ) 102611fa71b9SJerome Forissier { 102711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 102811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 102911fa71b9SJerome Forissier } 103011fa71b9SJerome Forissier 103111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) 103211fa71b9SJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 103311fa71b9SJerome Forissier { 103411fa71b9SJerome Forissier /* 103511fa71b9SJerome Forissier * Save IV in SSL3 and TLS1 103611fa71b9SJerome Forissier */ 103711fa71b9SJerome Forissier memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv, 103811fa71b9SJerome Forissier transform->ivlen ); 103911fa71b9SJerome Forissier } 104011fa71b9SJerome Forissier else 104111fa71b9SJerome Forissier #endif 104211fa71b9SJerome Forissier { 104311fa71b9SJerome Forissier data -= transform->ivlen; 104411fa71b9SJerome Forissier rec->data_offset -= transform->ivlen; 104511fa71b9SJerome Forissier rec->data_len += transform->ivlen; 104611fa71b9SJerome Forissier } 104711fa71b9SJerome Forissier 104811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 104911fa71b9SJerome Forissier if( auth_done == 0 ) 105011fa71b9SJerome Forissier { 105111fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 105211fa71b9SJerome Forissier 105311fa71b9SJerome Forissier /* 105411fa71b9SJerome Forissier * MAC(MAC_write_key, seq_num + 105511fa71b9SJerome Forissier * TLSCipherText.type + 105611fa71b9SJerome Forissier * TLSCipherText.version + 105711fa71b9SJerome Forissier * length_of( (IV +) ENC(...) ) + 105811fa71b9SJerome Forissier * IV + // except for TLS 1.0 105911fa71b9SJerome Forissier * ENC(content + padding + padding_length)); 106011fa71b9SJerome Forissier */ 106111fa71b9SJerome Forissier 106211fa71b9SJerome Forissier if( post_avail < transform->maclen) 106311fa71b9SJerome Forissier { 106411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 106511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 106611fa71b9SJerome Forissier } 106711fa71b9SJerome Forissier 10687901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, 10697901324dSJerome Forissier rec, transform->minor_ver ); 107011fa71b9SJerome Forissier 107111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); 107211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, 107311fa71b9SJerome Forissier add_data_len ); 107411fa71b9SJerome Forissier 1075*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, 107611fa71b9SJerome Forissier add_data_len ); 1077*039e02dfSJerome Forissier if( ret != 0 ) 1078*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1079*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, 108011fa71b9SJerome Forissier data, rec->data_len ); 1081*039e02dfSJerome Forissier if( ret != 0 ) 1082*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1083*039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); 1084*039e02dfSJerome Forissier if( ret != 0 ) 1085*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1086*039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc ); 1087*039e02dfSJerome Forissier if( ret != 0 ) 1088*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 108911fa71b9SJerome Forissier 109011fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 109111fa71b9SJerome Forissier 109211fa71b9SJerome Forissier rec->data_len += transform->maclen; 109311fa71b9SJerome Forissier post_avail -= transform->maclen; 109411fa71b9SJerome Forissier auth_done++; 1095*039e02dfSJerome Forissier 1096*039e02dfSJerome Forissier hmac_failed_etm_enabled: 1097*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac, transform->maclen ); 1098*039e02dfSJerome Forissier if( ret != 0 ) 1099*039e02dfSJerome Forissier { 1100*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret ); 1101*039e02dfSJerome Forissier return( ret ); 1102*039e02dfSJerome Forissier } 110311fa71b9SJerome Forissier } 110411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 110511fa71b9SJerome Forissier } 110611fa71b9SJerome Forissier else 11077901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ 110811fa71b9SJerome Forissier { 110911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 111011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 111111fa71b9SJerome Forissier } 111211fa71b9SJerome Forissier 111311fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 111411fa71b9SJerome Forissier if( auth_done != 1 ) 111511fa71b9SJerome Forissier { 111611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 111711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 111811fa71b9SJerome Forissier } 111911fa71b9SJerome Forissier 112011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); 112111fa71b9SJerome Forissier 112211fa71b9SJerome Forissier return( 0 ); 112311fa71b9SJerome Forissier } 112411fa71b9SJerome Forissier 112511fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, 112611fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 112711fa71b9SJerome Forissier mbedtls_record *rec ) 112811fa71b9SJerome Forissier { 112911fa71b9SJerome Forissier size_t olen; 113011fa71b9SJerome Forissier mbedtls_cipher_mode_t mode; 113111fa71b9SJerome Forissier int ret, auth_done = 0; 113211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 113311fa71b9SJerome Forissier size_t padlen = 0, correct = 1; 113411fa71b9SJerome Forissier #endif 113511fa71b9SJerome Forissier unsigned char* data; 113611fa71b9SJerome Forissier unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ]; 113711fa71b9SJerome Forissier size_t add_data_len; 113811fa71b9SJerome Forissier 113911fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 114011fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 114111fa71b9SJerome Forissier ((void) ssl); 114211fa71b9SJerome Forissier #endif 114311fa71b9SJerome Forissier 114411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); 114511fa71b9SJerome Forissier if( rec == NULL || 114611fa71b9SJerome Forissier rec->buf == NULL || 114711fa71b9SJerome Forissier rec->buf_len < rec->data_offset || 114811fa71b9SJerome Forissier rec->buf_len - rec->data_offset < rec->data_len ) 114911fa71b9SJerome Forissier { 115011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) ); 115111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 115211fa71b9SJerome Forissier } 115311fa71b9SJerome Forissier 115411fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 115511fa71b9SJerome Forissier mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec ); 115611fa71b9SJerome Forissier 115711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 115811fa71b9SJerome Forissier /* 115911fa71b9SJerome Forissier * Match record's CID with incoming CID. 116011fa71b9SJerome Forissier */ 116111fa71b9SJerome Forissier if( rec->cid_len != transform->in_cid_len || 116211fa71b9SJerome Forissier memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 ) 116311fa71b9SJerome Forissier { 116411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_CID ); 116511fa71b9SJerome Forissier } 116611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 116711fa71b9SJerome Forissier 116811fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) 116911fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM ) 117011fa71b9SJerome Forissier { 117111fa71b9SJerome Forissier padlen = 0; 117211fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, 117311fa71b9SJerome Forissier transform->iv_dec, 117411fa71b9SJerome Forissier transform->ivlen, 117511fa71b9SJerome Forissier data, rec->data_len, 117611fa71b9SJerome Forissier data, &olen ) ) != 0 ) 117711fa71b9SJerome Forissier { 117811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 117911fa71b9SJerome Forissier return( ret ); 118011fa71b9SJerome Forissier } 118111fa71b9SJerome Forissier 118211fa71b9SJerome Forissier if( rec->data_len != olen ) 118311fa71b9SJerome Forissier { 118411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 118511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 118611fa71b9SJerome Forissier } 118711fa71b9SJerome Forissier } 118811fa71b9SJerome Forissier else 118911fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ 119011fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 119111fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 119211fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 119311fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_GCM || 119411fa71b9SJerome Forissier mode == MBEDTLS_MODE_CCM || 119511fa71b9SJerome Forissier mode == MBEDTLS_MODE_CHACHAPOLY ) 119611fa71b9SJerome Forissier { 119711fa71b9SJerome Forissier unsigned char iv[12]; 11987901324dSJerome Forissier unsigned char *dynamic_iv; 11997901324dSJerome Forissier size_t dynamic_iv_len; 120011fa71b9SJerome Forissier 120111fa71b9SJerome Forissier /* 12027901324dSJerome Forissier * Extract dynamic part of nonce for AEAD decryption. 12037901324dSJerome Forissier * 12047901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 12057901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 12067901324dSJerome Forissier * can be chosen freely - in particular, it need not 12077901324dSJerome Forissier * agree with the record sequence number. 120811fa71b9SJerome Forissier */ 12097901324dSJerome Forissier dynamic_iv_len = sizeof( rec->ctr ); 12107901324dSJerome Forissier if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 ) 121111fa71b9SJerome Forissier { 12127901324dSJerome Forissier if( rec->data_len < dynamic_iv_len ) 12137901324dSJerome Forissier { 12147901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 12157901324dSJerome Forissier " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ", 12167901324dSJerome Forissier rec->data_len, 12177901324dSJerome Forissier dynamic_iv_len ) ); 121811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 121911fa71b9SJerome Forissier } 12207901324dSJerome Forissier dynamic_iv = data; 122111fa71b9SJerome Forissier 12227901324dSJerome Forissier data += dynamic_iv_len; 12237901324dSJerome Forissier rec->data_offset += dynamic_iv_len; 12247901324dSJerome Forissier rec->data_len -= dynamic_iv_len; 122511fa71b9SJerome Forissier } 122611fa71b9SJerome Forissier else 122711fa71b9SJerome Forissier { 12287901324dSJerome Forissier dynamic_iv = rec->ctr; 122911fa71b9SJerome Forissier } 123011fa71b9SJerome Forissier 12317901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 12327901324dSJerome Forissier if( rec->data_len < transform->taglen ) 12337901324dSJerome Forissier { 12347901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 12357901324dSJerome Forissier ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ", 12367901324dSJerome Forissier rec->data_len, 12377901324dSJerome Forissier transform->taglen ) ); 12387901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 12397901324dSJerome Forissier } 12407901324dSJerome Forissier rec->data_len -= transform->taglen; 124111fa71b9SJerome Forissier 12427901324dSJerome Forissier /* 12437901324dSJerome Forissier * Prepare nonce from dynamic and static parts. 12447901324dSJerome Forissier */ 12457901324dSJerome Forissier ssl_build_record_nonce( iv, sizeof( iv ), 12467901324dSJerome Forissier transform->iv_dec, 12477901324dSJerome Forissier transform->fixed_ivlen, 12487901324dSJerome Forissier dynamic_iv, 12497901324dSJerome Forissier dynamic_iv_len ); 12507901324dSJerome Forissier 12517901324dSJerome Forissier /* 12527901324dSJerome Forissier * Build additional data for AEAD encryption. 12537901324dSJerome Forissier * This depends on the TLS version. 12547901324dSJerome Forissier */ 12557901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 12567901324dSJerome Forissier transform->minor_ver ); 125711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", 125811fa71b9SJerome Forissier add_data, add_data_len ); 125911fa71b9SJerome Forissier 126011fa71b9SJerome Forissier /* Because of the check above, we know that there are 1261*039e02dfSJerome Forissier * explicit_iv_len Bytes preceding data, and taglen 126211fa71b9SJerome Forissier * bytes following data + data_len. This justifies 126311fa71b9SJerome Forissier * the debug message and the invocation of 126411fa71b9SJerome Forissier * mbedtls_cipher_auth_decrypt() below. */ 126511fa71b9SJerome Forissier 126611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); 126711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len, 126811fa71b9SJerome Forissier transform->taglen ); 126911fa71b9SJerome Forissier 127011fa71b9SJerome Forissier /* 127111fa71b9SJerome Forissier * Decrypt and authenticate 127211fa71b9SJerome Forissier */ 12737901324dSJerome Forissier if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec, 127411fa71b9SJerome Forissier iv, transform->ivlen, 127511fa71b9SJerome Forissier add_data, add_data_len, 12767901324dSJerome Forissier data, rec->data_len + transform->taglen, /* src */ 12777901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), &olen, /* dst */ 127811fa71b9SJerome Forissier transform->taglen ) ) != 0 ) 127911fa71b9SJerome Forissier { 128011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); 128111fa71b9SJerome Forissier 128211fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) 128311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 128411fa71b9SJerome Forissier 128511fa71b9SJerome Forissier return( ret ); 128611fa71b9SJerome Forissier } 128711fa71b9SJerome Forissier auth_done++; 128811fa71b9SJerome Forissier 128911fa71b9SJerome Forissier /* Double-check that AEAD decryption doesn't change content length. */ 129011fa71b9SJerome Forissier if( olen != rec->data_len ) 129111fa71b9SJerome Forissier { 129211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 129311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 129411fa71b9SJerome Forissier } 129511fa71b9SJerome Forissier } 129611fa71b9SJerome Forissier else 129711fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ 12987901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 129911fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_CBC ) 130011fa71b9SJerome Forissier { 130111fa71b9SJerome Forissier size_t minlen = 0; 130211fa71b9SJerome Forissier 130311fa71b9SJerome Forissier /* 130411fa71b9SJerome Forissier * Check immediate ciphertext sanity 130511fa71b9SJerome Forissier */ 130611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 130711fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 130811fa71b9SJerome Forissier { 130911fa71b9SJerome Forissier /* The ciphertext is prefixed with the CBC IV. */ 131011fa71b9SJerome Forissier minlen += transform->ivlen; 131111fa71b9SJerome Forissier } 131211fa71b9SJerome Forissier #endif 131311fa71b9SJerome Forissier 131411fa71b9SJerome Forissier /* Size considerations: 131511fa71b9SJerome Forissier * 131611fa71b9SJerome Forissier * - The CBC cipher text must not be empty and hence 131711fa71b9SJerome Forissier * at least of size transform->ivlen. 131811fa71b9SJerome Forissier * 131911fa71b9SJerome Forissier * Together with the potential IV-prefix, this explains 132011fa71b9SJerome Forissier * the first of the two checks below. 132111fa71b9SJerome Forissier * 132211fa71b9SJerome Forissier * - The record must contain a MAC, either in plain or 132311fa71b9SJerome Forissier * encrypted, depending on whether Encrypt-then-MAC 132411fa71b9SJerome Forissier * is used or not. 132511fa71b9SJerome Forissier * - If it is, the message contains the IV-prefix, 132611fa71b9SJerome Forissier * the CBC ciphertext, and the MAC. 132711fa71b9SJerome Forissier * - If it is not, the padded plaintext, and hence 132811fa71b9SJerome Forissier * the CBC ciphertext, has at least length maclen + 1 132911fa71b9SJerome Forissier * because there is at least the padding length byte. 133011fa71b9SJerome Forissier * 133111fa71b9SJerome Forissier * As the CBC ciphertext is not empty, both cases give the 133211fa71b9SJerome Forissier * lower bound minlen + maclen + 1 on the record size, which 133311fa71b9SJerome Forissier * we test for in the second check below. 133411fa71b9SJerome Forissier */ 133511fa71b9SJerome Forissier if( rec->data_len < minlen + transform->ivlen || 133611fa71b9SJerome Forissier rec->data_len < minlen + transform->maclen + 1 ) 133711fa71b9SJerome Forissier { 13387901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 13397901324dSJerome Forissier ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET 13407901324dSJerome Forissier "), maclen (%" MBEDTLS_PRINTF_SIZET ") " 134111fa71b9SJerome Forissier "+ 1 ) ( + expl IV )", rec->data_len, 134211fa71b9SJerome Forissier transform->ivlen, 134311fa71b9SJerome Forissier transform->maclen ) ); 134411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 134511fa71b9SJerome Forissier } 134611fa71b9SJerome Forissier 134711fa71b9SJerome Forissier /* 134811fa71b9SJerome Forissier * Authenticate before decrypt if enabled 134911fa71b9SJerome Forissier */ 135011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 135111fa71b9SJerome Forissier if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) 135211fa71b9SJerome Forissier { 135311fa71b9SJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; 135411fa71b9SJerome Forissier 135511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); 135611fa71b9SJerome Forissier 135711fa71b9SJerome Forissier /* Update data_len in tandem with add_data. 135811fa71b9SJerome Forissier * 135911fa71b9SJerome Forissier * The subtraction is safe because of the previous check 136011fa71b9SJerome Forissier * data_len >= minlen + maclen + 1. 136111fa71b9SJerome Forissier * 136211fa71b9SJerome Forissier * Afterwards, we know that data + data_len is followed by at 136311fa71b9SJerome Forissier * least maclen Bytes, which justifies the call to 1364*039e02dfSJerome Forissier * mbedtls_ct_memcmp() below. 136511fa71b9SJerome Forissier * 136611fa71b9SJerome Forissier * Further, we still know that data_len > minlen */ 136711fa71b9SJerome Forissier rec->data_len -= transform->maclen; 13687901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 13697901324dSJerome Forissier transform->minor_ver ); 137011fa71b9SJerome Forissier 137111fa71b9SJerome Forissier /* Calculate expected MAC. */ 137211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, 137311fa71b9SJerome Forissier add_data_len ); 1374*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, 137511fa71b9SJerome Forissier add_data_len ); 1376*039e02dfSJerome Forissier if( ret != 0 ) 1377*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1378*039e02dfSJerome Forissier ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, 137911fa71b9SJerome Forissier data, rec->data_len ); 1380*039e02dfSJerome Forissier if( ret != 0 ) 1381*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1382*039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); 1383*039e02dfSJerome Forissier if( ret != 0 ) 1384*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 1385*039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec ); 1386*039e02dfSJerome Forissier if( ret != 0 ) 1387*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 138811fa71b9SJerome Forissier 138911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, 139011fa71b9SJerome Forissier transform->maclen ); 139111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, 139211fa71b9SJerome Forissier transform->maclen ); 139311fa71b9SJerome Forissier 139411fa71b9SJerome Forissier /* Compare expected MAC with MAC at the end of the record. */ 1395*039e02dfSJerome Forissier if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect, 139611fa71b9SJerome Forissier transform->maclen ) != 0 ) 139711fa71b9SJerome Forissier { 139811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); 1399*039e02dfSJerome Forissier ret = MBEDTLS_ERR_SSL_INVALID_MAC; 1400*039e02dfSJerome Forissier goto hmac_failed_etm_enabled; 140111fa71b9SJerome Forissier } 140211fa71b9SJerome Forissier auth_done++; 1403*039e02dfSJerome Forissier 1404*039e02dfSJerome Forissier hmac_failed_etm_enabled: 1405*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac_expect, transform->maclen ); 1406*039e02dfSJerome Forissier if( ret != 0 ) 1407*039e02dfSJerome Forissier { 1408*039e02dfSJerome Forissier if( ret != MBEDTLS_ERR_SSL_INVALID_MAC ) 1409*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret ); 1410*039e02dfSJerome Forissier return( ret ); 1411*039e02dfSJerome Forissier } 141211fa71b9SJerome Forissier } 141311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 141411fa71b9SJerome Forissier 141511fa71b9SJerome Forissier /* 141611fa71b9SJerome Forissier * Check length sanity 141711fa71b9SJerome Forissier */ 141811fa71b9SJerome Forissier 141911fa71b9SJerome Forissier /* We know from above that data_len > minlen >= 0, 142011fa71b9SJerome Forissier * so the following check in particular implies that 142111fa71b9SJerome Forissier * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */ 142211fa71b9SJerome Forissier if( rec->data_len % transform->ivlen != 0 ) 142311fa71b9SJerome Forissier { 14247901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 14257901324dSJerome Forissier ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0", 142611fa71b9SJerome Forissier rec->data_len, transform->ivlen ) ); 142711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 142811fa71b9SJerome Forissier } 142911fa71b9SJerome Forissier 143011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 143111fa71b9SJerome Forissier /* 143211fa71b9SJerome Forissier * Initialize for prepended IV for block cipher in TLS v1.1 and up 143311fa71b9SJerome Forissier */ 143411fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 143511fa71b9SJerome Forissier { 143611fa71b9SJerome Forissier /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */ 143711fa71b9SJerome Forissier memcpy( transform->iv_dec, data, transform->ivlen ); 143811fa71b9SJerome Forissier 143911fa71b9SJerome Forissier data += transform->ivlen; 144011fa71b9SJerome Forissier rec->data_offset += transform->ivlen; 144111fa71b9SJerome Forissier rec->data_len -= transform->ivlen; 144211fa71b9SJerome Forissier } 144311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 144411fa71b9SJerome Forissier 144511fa71b9SJerome Forissier /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */ 144611fa71b9SJerome Forissier 144711fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, 144811fa71b9SJerome Forissier transform->iv_dec, transform->ivlen, 144911fa71b9SJerome Forissier data, rec->data_len, data, &olen ) ) != 0 ) 145011fa71b9SJerome Forissier { 145111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 145211fa71b9SJerome Forissier return( ret ); 145311fa71b9SJerome Forissier } 145411fa71b9SJerome Forissier 145511fa71b9SJerome Forissier /* Double-check that length hasn't changed during decryption. */ 145611fa71b9SJerome Forissier if( rec->data_len != olen ) 145711fa71b9SJerome Forissier { 145811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 145911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 146011fa71b9SJerome Forissier } 146111fa71b9SJerome Forissier 146211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) 146311fa71b9SJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 146411fa71b9SJerome Forissier { 146511fa71b9SJerome Forissier /* 146611fa71b9SJerome Forissier * Save IV in SSL3 and TLS1, where CBC decryption of consecutive 146711fa71b9SJerome Forissier * records is equivalent to CBC decryption of the concatenation 146811fa71b9SJerome Forissier * of the records; in other words, IVs are maintained across 146911fa71b9SJerome Forissier * record decryptions. 147011fa71b9SJerome Forissier */ 147111fa71b9SJerome Forissier memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv, 147211fa71b9SJerome Forissier transform->ivlen ); 147311fa71b9SJerome Forissier } 147411fa71b9SJerome Forissier #endif 147511fa71b9SJerome Forissier 147611fa71b9SJerome Forissier /* Safe since data_len >= minlen + maclen + 1, so after having 147711fa71b9SJerome Forissier * subtracted at most minlen and maclen up to this point, 147811fa71b9SJerome Forissier * data_len > 0 (because of data_len % ivlen == 0, it's actually 147911fa71b9SJerome Forissier * >= ivlen ). */ 148011fa71b9SJerome Forissier padlen = data[rec->data_len - 1]; 148111fa71b9SJerome Forissier 148211fa71b9SJerome Forissier if( auth_done == 1 ) 148311fa71b9SJerome Forissier { 1484*039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge( 14857901324dSJerome Forissier rec->data_len, 14867901324dSJerome Forissier padlen + 1 ); 14877901324dSJerome Forissier correct &= mask; 14887901324dSJerome Forissier padlen &= mask; 148911fa71b9SJerome Forissier } 149011fa71b9SJerome Forissier else 149111fa71b9SJerome Forissier { 149211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 149311fa71b9SJerome Forissier if( rec->data_len < transform->maclen + padlen + 1 ) 149411fa71b9SJerome Forissier { 14957901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 14967901324dSJerome Forissier ") < maclen (%" MBEDTLS_PRINTF_SIZET 14977901324dSJerome Forissier ") + padlen (%" MBEDTLS_PRINTF_SIZET ")", 149811fa71b9SJerome Forissier rec->data_len, 149911fa71b9SJerome Forissier transform->maclen, 150011fa71b9SJerome Forissier padlen + 1 ) ); 150111fa71b9SJerome Forissier } 150211fa71b9SJerome Forissier #endif 150311fa71b9SJerome Forissier 1504*039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge( 15057901324dSJerome Forissier rec->data_len, 15067901324dSJerome Forissier transform->maclen + padlen + 1 ); 15077901324dSJerome Forissier correct &= mask; 15087901324dSJerome Forissier padlen &= mask; 150911fa71b9SJerome Forissier } 151011fa71b9SJerome Forissier 151111fa71b9SJerome Forissier padlen++; 151211fa71b9SJerome Forissier 151311fa71b9SJerome Forissier /* Regardless of the validity of the padding, 151411fa71b9SJerome Forissier * we have data_len >= padlen here. */ 151511fa71b9SJerome Forissier 151611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 151711fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 151811fa71b9SJerome Forissier { 15197901324dSJerome Forissier /* This is the SSL 3.0 path, we don't have to worry about Lucky 15207901324dSJerome Forissier * 13, because there's a strictly worse padding attack built in 15217901324dSJerome Forissier * the protocol (known as part of POODLE), so we don't care if the 15227901324dSJerome Forissier * code is not constant-time, in particular branches are OK. */ 152311fa71b9SJerome Forissier if( padlen > transform->ivlen ) 152411fa71b9SJerome Forissier { 152511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 15267901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %" MBEDTLS_PRINTF_SIZET ", " 15277901324dSJerome Forissier "should be no more than %" MBEDTLS_PRINTF_SIZET, 152811fa71b9SJerome Forissier padlen, transform->ivlen ) ); 152911fa71b9SJerome Forissier #endif 153011fa71b9SJerome Forissier correct = 0; 153111fa71b9SJerome Forissier } 153211fa71b9SJerome Forissier } 153311fa71b9SJerome Forissier else 153411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 153511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 153611fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 153711fa71b9SJerome Forissier if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) 153811fa71b9SJerome Forissier { 153911fa71b9SJerome Forissier /* The padding check involves a series of up to 256 154011fa71b9SJerome Forissier * consecutive memory reads at the end of the record 154111fa71b9SJerome Forissier * plaintext buffer. In order to hide the length and 154211fa71b9SJerome Forissier * validity of the padding, always perform exactly 154311fa71b9SJerome Forissier * `min(256,plaintext_len)` reads (but take into account 154411fa71b9SJerome Forissier * only the last `padlen` bytes for the padding check). */ 154511fa71b9SJerome Forissier size_t pad_count = 0; 154611fa71b9SJerome Forissier volatile unsigned char* const check = data; 154711fa71b9SJerome Forissier 154811fa71b9SJerome Forissier /* Index of first padding byte; it has been ensured above 154911fa71b9SJerome Forissier * that the subtraction is safe. */ 155011fa71b9SJerome Forissier size_t const padding_idx = rec->data_len - padlen; 155111fa71b9SJerome Forissier size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256; 155211fa71b9SJerome Forissier size_t const start_idx = rec->data_len - num_checks; 155311fa71b9SJerome Forissier size_t idx; 155411fa71b9SJerome Forissier 155511fa71b9SJerome Forissier for( idx = start_idx; idx < rec->data_len; idx++ ) 155611fa71b9SJerome Forissier { 15577901324dSJerome Forissier /* pad_count += (idx >= padding_idx) && 15587901324dSJerome Forissier * (check[idx] == padlen - 1); 15597901324dSJerome Forissier */ 1560*039e02dfSJerome Forissier const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx ); 1561*039e02dfSJerome Forissier const size_t equal = mbedtls_ct_size_bool_eq( check[idx], 15627901324dSJerome Forissier padlen - 1 ); 15637901324dSJerome Forissier pad_count += mask & equal; 156411fa71b9SJerome Forissier } 1565*039e02dfSJerome Forissier correct &= mbedtls_ct_size_bool_eq( pad_count, padlen ); 156611fa71b9SJerome Forissier 156711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 156811fa71b9SJerome Forissier if( padlen > 0 && correct == 0 ) 156911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); 157011fa71b9SJerome Forissier #endif 1571*039e02dfSJerome Forissier padlen &= mbedtls_ct_size_mask( correct ); 157211fa71b9SJerome Forissier } 157311fa71b9SJerome Forissier else 157411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ 157511fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 157611fa71b9SJerome Forissier { 157711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 157811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 157911fa71b9SJerome Forissier } 158011fa71b9SJerome Forissier 158111fa71b9SJerome Forissier /* If the padding was found to be invalid, padlen == 0 158211fa71b9SJerome Forissier * and the subtraction is safe. If the padding was found valid, 158311fa71b9SJerome Forissier * padlen hasn't been changed and the previous assertion 158411fa71b9SJerome Forissier * data_len >= padlen still holds. */ 158511fa71b9SJerome Forissier rec->data_len -= padlen; 158611fa71b9SJerome Forissier } 158711fa71b9SJerome Forissier else 15887901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ 158911fa71b9SJerome Forissier { 159011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 159111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 159211fa71b9SJerome Forissier } 159311fa71b9SJerome Forissier 159411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 159511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", 159611fa71b9SJerome Forissier data, rec->data_len ); 159711fa71b9SJerome Forissier #endif 159811fa71b9SJerome Forissier 159911fa71b9SJerome Forissier /* 160011fa71b9SJerome Forissier * Authenticate if not done yet. 160111fa71b9SJerome Forissier * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). 160211fa71b9SJerome Forissier */ 160311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 160411fa71b9SJerome Forissier if( auth_done == 0 ) 160511fa71b9SJerome Forissier { 1606*039e02dfSJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 }; 1607*039e02dfSJerome Forissier unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 }; 160811fa71b9SJerome Forissier 160911fa71b9SJerome Forissier /* If the initial value of padlen was such that 161011fa71b9SJerome Forissier * data_len < maclen + padlen + 1, then padlen 161111fa71b9SJerome Forissier * got reset to 1, and the initial check 161211fa71b9SJerome Forissier * data_len >= minlen + maclen + 1 161311fa71b9SJerome Forissier * guarantees that at this point we still 161411fa71b9SJerome Forissier * have at least data_len >= maclen. 161511fa71b9SJerome Forissier * 161611fa71b9SJerome Forissier * If the initial value of padlen was such that 161711fa71b9SJerome Forissier * data_len >= maclen + padlen + 1, then we have 161811fa71b9SJerome Forissier * subtracted either padlen + 1 (if the padding was correct) 161911fa71b9SJerome Forissier * or 0 (if the padding was incorrect) since then, 162011fa71b9SJerome Forissier * hence data_len >= maclen in any case. 162111fa71b9SJerome Forissier */ 162211fa71b9SJerome Forissier rec->data_len -= transform->maclen; 16237901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 16247901324dSJerome Forissier transform->minor_ver ); 162511fa71b9SJerome Forissier 162611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 162711fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 162811fa71b9SJerome Forissier { 1629*039e02dfSJerome Forissier ret = ssl_mac( &transform->md_ctx_dec, 163011fa71b9SJerome Forissier transform->mac_dec, 163111fa71b9SJerome Forissier data, rec->data_len, 163211fa71b9SJerome Forissier rec->ctr, rec->type, 163311fa71b9SJerome Forissier mac_expect ); 1634*039e02dfSJerome Forissier if( ret != 0 ) 1635*039e02dfSJerome Forissier { 1636*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret ); 1637*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 1638*039e02dfSJerome Forissier } 16397901324dSJerome Forissier memcpy( mac_peer, data + rec->data_len, transform->maclen ); 164011fa71b9SJerome Forissier } 164111fa71b9SJerome Forissier else 164211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 164311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 164411fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 164511fa71b9SJerome Forissier if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) 164611fa71b9SJerome Forissier { 164711fa71b9SJerome Forissier /* 164811fa71b9SJerome Forissier * The next two sizes are the minimum and maximum values of 16497901324dSJerome Forissier * data_len over all padlen values. 165011fa71b9SJerome Forissier * 165111fa71b9SJerome Forissier * They're independent of padlen, since we previously did 165211fa71b9SJerome Forissier * data_len -= padlen. 165311fa71b9SJerome Forissier * 165411fa71b9SJerome Forissier * Note that max_len + maclen is never more than the buffer 165511fa71b9SJerome Forissier * length, as we previously did in_msglen -= maclen too. 165611fa71b9SJerome Forissier */ 165711fa71b9SJerome Forissier const size_t max_len = rec->data_len + padlen; 165811fa71b9SJerome Forissier const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; 165911fa71b9SJerome Forissier 1660*039e02dfSJerome Forissier ret = mbedtls_ct_hmac( &transform->md_ctx_dec, 16617901324dSJerome Forissier add_data, add_data_len, 16627901324dSJerome Forissier data, rec->data_len, min_len, max_len, 16637901324dSJerome Forissier mac_expect ); 16647901324dSJerome Forissier if( ret != 0 ) 166511fa71b9SJerome Forissier { 1666*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret ); 1667*039e02dfSJerome Forissier goto hmac_failed_etm_disabled; 166811fa71b9SJerome Forissier } 166911fa71b9SJerome Forissier 1670*039e02dfSJerome Forissier mbedtls_ct_memcpy_offset( mac_peer, data, 16717901324dSJerome Forissier rec->data_len, 16727901324dSJerome Forissier min_len, max_len, 16737901324dSJerome Forissier transform->maclen ); 167411fa71b9SJerome Forissier } 167511fa71b9SJerome Forissier else 167611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ 167711fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 167811fa71b9SJerome Forissier { 167911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 168011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 168111fa71b9SJerome Forissier } 168211fa71b9SJerome Forissier 168311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 168411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen ); 16857901324dSJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, transform->maclen ); 168611fa71b9SJerome Forissier #endif 168711fa71b9SJerome Forissier 1688*039e02dfSJerome Forissier if( mbedtls_ct_memcmp( mac_peer, mac_expect, 168911fa71b9SJerome Forissier transform->maclen ) != 0 ) 169011fa71b9SJerome Forissier { 169111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 169211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); 169311fa71b9SJerome Forissier #endif 169411fa71b9SJerome Forissier correct = 0; 169511fa71b9SJerome Forissier } 169611fa71b9SJerome Forissier auth_done++; 1697*039e02dfSJerome Forissier 1698*039e02dfSJerome Forissier hmac_failed_etm_disabled: 1699*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac_peer, transform->maclen ); 1700*039e02dfSJerome Forissier mbedtls_platform_zeroize( mac_expect, transform->maclen ); 1701*039e02dfSJerome Forissier if( ret != 0 ) 1702*039e02dfSJerome Forissier return( ret ); 170311fa71b9SJerome Forissier } 170411fa71b9SJerome Forissier 170511fa71b9SJerome Forissier /* 170611fa71b9SJerome Forissier * Finally check the correct flag 170711fa71b9SJerome Forissier */ 170811fa71b9SJerome Forissier if( correct == 0 ) 170911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 171011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ 171111fa71b9SJerome Forissier 171211fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 171311fa71b9SJerome Forissier if( auth_done != 1 ) 171411fa71b9SJerome Forissier { 171511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 171611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 171711fa71b9SJerome Forissier } 171811fa71b9SJerome Forissier 17197901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 17207901324dSJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) 17217901324dSJerome Forissier { 17227901324dSJerome Forissier /* Remove inner padding and infer true content type. */ 17237901324dSJerome Forissier ret = ssl_parse_inner_plaintext( data, &rec->data_len, 17247901324dSJerome Forissier &rec->type ); 17257901324dSJerome Forissier 17267901324dSJerome Forissier if( ret != 0 ) 17277901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 17287901324dSJerome Forissier } 17297901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 17307901324dSJerome Forissier 173111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 173211fa71b9SJerome Forissier if( rec->cid_len != 0 ) 173311fa71b9SJerome Forissier { 17347901324dSJerome Forissier ret = ssl_parse_inner_plaintext( data, &rec->data_len, 173511fa71b9SJerome Forissier &rec->type ); 173611fa71b9SJerome Forissier if( ret != 0 ) 173711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 173811fa71b9SJerome Forissier } 173911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 174011fa71b9SJerome Forissier 174111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); 174211fa71b9SJerome Forissier 174311fa71b9SJerome Forissier return( 0 ); 174411fa71b9SJerome Forissier } 174511fa71b9SJerome Forissier 174611fa71b9SJerome Forissier #undef MAC_NONE 174711fa71b9SJerome Forissier #undef MAC_PLAINTEXT 174811fa71b9SJerome Forissier #undef MAC_CIPHERTEXT 174911fa71b9SJerome Forissier 175011fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 175111fa71b9SJerome Forissier /* 175211fa71b9SJerome Forissier * Compression/decompression functions 175311fa71b9SJerome Forissier */ 1754*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 175511fa71b9SJerome Forissier static int ssl_compress_buf( mbedtls_ssl_context *ssl ) 175611fa71b9SJerome Forissier { 175711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 175811fa71b9SJerome Forissier unsigned char *msg_post = ssl->out_msg; 175911fa71b9SJerome Forissier ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; 176011fa71b9SJerome Forissier size_t len_pre = ssl->out_msglen; 176111fa71b9SJerome Forissier unsigned char *msg_pre = ssl->compress_buf; 176211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 176311fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 176411fa71b9SJerome Forissier #else 176511fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 176611fa71b9SJerome Forissier #endif 176711fa71b9SJerome Forissier 176811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); 176911fa71b9SJerome Forissier 177011fa71b9SJerome Forissier if( len_pre == 0 ) 177111fa71b9SJerome Forissier return( 0 ); 177211fa71b9SJerome Forissier 177311fa71b9SJerome Forissier memcpy( msg_pre, ssl->out_msg, len_pre ); 177411fa71b9SJerome Forissier 17757901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 177611fa71b9SJerome Forissier ssl->out_msglen ) ); 177711fa71b9SJerome Forissier 177811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", 177911fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 178011fa71b9SJerome Forissier 178111fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.next_in = msg_pre; 178211fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_in = len_pre; 178311fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.next_out = msg_post; 178411fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written; 178511fa71b9SJerome Forissier 178611fa71b9SJerome Forissier ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); 178711fa71b9SJerome Forissier if( ret != Z_OK ) 178811fa71b9SJerome Forissier { 178911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); 179011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); 179111fa71b9SJerome Forissier } 179211fa71b9SJerome Forissier 179311fa71b9SJerome Forissier ssl->out_msglen = out_buf_len - 179411fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_out - bytes_written; 179511fa71b9SJerome Forissier 17967901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 179711fa71b9SJerome Forissier ssl->out_msglen ) ); 179811fa71b9SJerome Forissier 179911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", 180011fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 180111fa71b9SJerome Forissier 180211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); 180311fa71b9SJerome Forissier 180411fa71b9SJerome Forissier return( 0 ); 180511fa71b9SJerome Forissier } 180611fa71b9SJerome Forissier 1807*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 180811fa71b9SJerome Forissier static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) 180911fa71b9SJerome Forissier { 181011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 181111fa71b9SJerome Forissier unsigned char *msg_post = ssl->in_msg; 181211fa71b9SJerome Forissier ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; 181311fa71b9SJerome Forissier size_t len_pre = ssl->in_msglen; 181411fa71b9SJerome Forissier unsigned char *msg_pre = ssl->compress_buf; 181511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 181611fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 181711fa71b9SJerome Forissier #else 181811fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 181911fa71b9SJerome Forissier #endif 182011fa71b9SJerome Forissier 182111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); 182211fa71b9SJerome Forissier 182311fa71b9SJerome Forissier if( len_pre == 0 ) 182411fa71b9SJerome Forissier return( 0 ); 182511fa71b9SJerome Forissier 182611fa71b9SJerome Forissier memcpy( msg_pre, ssl->in_msg, len_pre ); 182711fa71b9SJerome Forissier 18287901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 182911fa71b9SJerome Forissier ssl->in_msglen ) ); 183011fa71b9SJerome Forissier 183111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", 183211fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 183311fa71b9SJerome Forissier 183411fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.next_in = msg_pre; 183511fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_in = len_pre; 183611fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.next_out = msg_post; 183711fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes; 183811fa71b9SJerome Forissier 183911fa71b9SJerome Forissier ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); 184011fa71b9SJerome Forissier if( ret != Z_OK ) 184111fa71b9SJerome Forissier { 184211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); 184311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); 184411fa71b9SJerome Forissier } 184511fa71b9SJerome Forissier 184611fa71b9SJerome Forissier ssl->in_msglen = in_buf_len - 184711fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_out - header_bytes; 184811fa71b9SJerome Forissier 18497901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 185011fa71b9SJerome Forissier ssl->in_msglen ) ); 185111fa71b9SJerome Forissier 185211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", 185311fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 185411fa71b9SJerome Forissier 185511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); 185611fa71b9SJerome Forissier 185711fa71b9SJerome Forissier return( 0 ); 185811fa71b9SJerome Forissier } 185911fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */ 186011fa71b9SJerome Forissier 186111fa71b9SJerome Forissier /* 186211fa71b9SJerome Forissier * Fill the input message buffer by appending data to it. 186311fa71b9SJerome Forissier * The amount of data already fetched is in ssl->in_left. 186411fa71b9SJerome Forissier * 186511fa71b9SJerome Forissier * If we return 0, is it guaranteed that (at least) nb_want bytes are 186611fa71b9SJerome Forissier * available (from this read and/or a previous one). Otherwise, an error code 186711fa71b9SJerome Forissier * is returned (possibly EOF or WANT_READ). 186811fa71b9SJerome Forissier * 186911fa71b9SJerome Forissier * With stream transport (TLS) on success ssl->in_left == nb_want, but 187011fa71b9SJerome Forissier * with datagram transport (DTLS) on success ssl->in_left >= nb_want, 187111fa71b9SJerome Forissier * since we always read a whole datagram at once. 187211fa71b9SJerome Forissier * 187311fa71b9SJerome Forissier * For DTLS, it is up to the caller to set ssl->next_record_offset when 187411fa71b9SJerome Forissier * they're done reading a record. 187511fa71b9SJerome Forissier */ 187611fa71b9SJerome Forissier int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) 187711fa71b9SJerome Forissier { 187811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 187911fa71b9SJerome Forissier size_t len; 188011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 188111fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 188211fa71b9SJerome Forissier #else 188311fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 188411fa71b9SJerome Forissier #endif 188511fa71b9SJerome Forissier 188611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); 188711fa71b9SJerome Forissier 188811fa71b9SJerome Forissier if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) 188911fa71b9SJerome Forissier { 189011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " 189111fa71b9SJerome Forissier "or mbedtls_ssl_set_bio()" ) ); 189211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 189311fa71b9SJerome Forissier } 189411fa71b9SJerome Forissier 189511fa71b9SJerome Forissier if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) 189611fa71b9SJerome Forissier { 189711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); 189811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 189911fa71b9SJerome Forissier } 190011fa71b9SJerome Forissier 190111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 190211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 190311fa71b9SJerome Forissier { 190411fa71b9SJerome Forissier uint32_t timeout; 190511fa71b9SJerome Forissier 190611fa71b9SJerome Forissier /* 190711fa71b9SJerome Forissier * The point is, we need to always read a full datagram at once, so we 190811fa71b9SJerome Forissier * sometimes read more then requested, and handle the additional data. 190911fa71b9SJerome Forissier * It could be the rest of the current record (while fetching the 191011fa71b9SJerome Forissier * header) and/or some other records in the same datagram. 191111fa71b9SJerome Forissier */ 191211fa71b9SJerome Forissier 191311fa71b9SJerome Forissier /* 191411fa71b9SJerome Forissier * Move to the next record in the already read datagram if applicable 191511fa71b9SJerome Forissier */ 191611fa71b9SJerome Forissier if( ssl->next_record_offset != 0 ) 191711fa71b9SJerome Forissier { 191811fa71b9SJerome Forissier if( ssl->in_left < ssl->next_record_offset ) 191911fa71b9SJerome Forissier { 192011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 192111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 192211fa71b9SJerome Forissier } 192311fa71b9SJerome Forissier 192411fa71b9SJerome Forissier ssl->in_left -= ssl->next_record_offset; 192511fa71b9SJerome Forissier 192611fa71b9SJerome Forissier if( ssl->in_left != 0 ) 192711fa71b9SJerome Forissier { 19287901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %" 19297901324dSJerome Forissier MBEDTLS_PRINTF_SIZET, 193011fa71b9SJerome Forissier ssl->next_record_offset ) ); 193111fa71b9SJerome Forissier memmove( ssl->in_hdr, 193211fa71b9SJerome Forissier ssl->in_hdr + ssl->next_record_offset, 193311fa71b9SJerome Forissier ssl->in_left ); 193411fa71b9SJerome Forissier } 193511fa71b9SJerome Forissier 193611fa71b9SJerome Forissier ssl->next_record_offset = 0; 193711fa71b9SJerome Forissier } 193811fa71b9SJerome Forissier 19397901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET 19407901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 194111fa71b9SJerome Forissier ssl->in_left, nb_want ) ); 194211fa71b9SJerome Forissier 194311fa71b9SJerome Forissier /* 194411fa71b9SJerome Forissier * Done if we already have enough data. 194511fa71b9SJerome Forissier */ 194611fa71b9SJerome Forissier if( nb_want <= ssl->in_left) 194711fa71b9SJerome Forissier { 194811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); 194911fa71b9SJerome Forissier return( 0 ); 195011fa71b9SJerome Forissier } 195111fa71b9SJerome Forissier 195211fa71b9SJerome Forissier /* 195311fa71b9SJerome Forissier * A record can't be split across datagrams. If we need to read but 195411fa71b9SJerome Forissier * are not at the beginning of a new record, the caller did something 195511fa71b9SJerome Forissier * wrong. 195611fa71b9SJerome Forissier */ 195711fa71b9SJerome Forissier if( ssl->in_left != 0 ) 195811fa71b9SJerome Forissier { 195911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 196011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 196111fa71b9SJerome Forissier } 196211fa71b9SJerome Forissier 196311fa71b9SJerome Forissier /* 196411fa71b9SJerome Forissier * Don't even try to read if time's out already. 196511fa71b9SJerome Forissier * This avoids by-passing the timer when repeatedly receiving messages 196611fa71b9SJerome Forissier * that will end up being dropped. 196711fa71b9SJerome Forissier */ 196811fa71b9SJerome Forissier if( mbedtls_ssl_check_timer( ssl ) != 0 ) 196911fa71b9SJerome Forissier { 197011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); 197111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 197211fa71b9SJerome Forissier } 197311fa71b9SJerome Forissier else 197411fa71b9SJerome Forissier { 197511fa71b9SJerome Forissier len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); 197611fa71b9SJerome Forissier 197711fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 197811fa71b9SJerome Forissier timeout = ssl->handshake->retransmit_timeout; 197911fa71b9SJerome Forissier else 198011fa71b9SJerome Forissier timeout = ssl->conf->read_timeout; 198111fa71b9SJerome Forissier 19827901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %lu ms", (unsigned long) timeout ) ); 198311fa71b9SJerome Forissier 198411fa71b9SJerome Forissier if( ssl->f_recv_timeout != NULL ) 198511fa71b9SJerome Forissier ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, 198611fa71b9SJerome Forissier timeout ); 198711fa71b9SJerome Forissier else 198811fa71b9SJerome Forissier ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); 198911fa71b9SJerome Forissier 199011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); 199111fa71b9SJerome Forissier 199211fa71b9SJerome Forissier if( ret == 0 ) 199311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONN_EOF ); 199411fa71b9SJerome Forissier } 199511fa71b9SJerome Forissier 199611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) 199711fa71b9SJerome Forissier { 199811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); 199911fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 200011fa71b9SJerome Forissier 200111fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 200211fa71b9SJerome Forissier { 200311fa71b9SJerome Forissier if( ssl_double_retransmit_timeout( ssl ) != 0 ) 200411fa71b9SJerome Forissier { 200511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); 200611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_TIMEOUT ); 200711fa71b9SJerome Forissier } 200811fa71b9SJerome Forissier 200911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) 201011fa71b9SJerome Forissier { 201111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); 201211fa71b9SJerome Forissier return( ret ); 201311fa71b9SJerome Forissier } 201411fa71b9SJerome Forissier 201511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 201611fa71b9SJerome Forissier } 201711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 201811fa71b9SJerome Forissier else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 201911fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 202011fa71b9SJerome Forissier { 202111fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 ) 202211fa71b9SJerome Forissier { 202311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request", 202411fa71b9SJerome Forissier ret ); 202511fa71b9SJerome Forissier return( ret ); 202611fa71b9SJerome Forissier } 202711fa71b9SJerome Forissier 202811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 202911fa71b9SJerome Forissier } 203011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 203111fa71b9SJerome Forissier } 203211fa71b9SJerome Forissier 203311fa71b9SJerome Forissier if( ret < 0 ) 203411fa71b9SJerome Forissier return( ret ); 203511fa71b9SJerome Forissier 203611fa71b9SJerome Forissier ssl->in_left = ret; 203711fa71b9SJerome Forissier } 203811fa71b9SJerome Forissier else 203911fa71b9SJerome Forissier #endif 204011fa71b9SJerome Forissier { 20417901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET 20427901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 204311fa71b9SJerome Forissier ssl->in_left, nb_want ) ); 204411fa71b9SJerome Forissier 204511fa71b9SJerome Forissier while( ssl->in_left < nb_want ) 204611fa71b9SJerome Forissier { 204711fa71b9SJerome Forissier len = nb_want - ssl->in_left; 204811fa71b9SJerome Forissier 204911fa71b9SJerome Forissier if( mbedtls_ssl_check_timer( ssl ) != 0 ) 205011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 205111fa71b9SJerome Forissier else 205211fa71b9SJerome Forissier { 205311fa71b9SJerome Forissier if( ssl->f_recv_timeout != NULL ) 205411fa71b9SJerome Forissier { 205511fa71b9SJerome Forissier ret = ssl->f_recv_timeout( ssl->p_bio, 205611fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len, 205711fa71b9SJerome Forissier ssl->conf->read_timeout ); 205811fa71b9SJerome Forissier } 205911fa71b9SJerome Forissier else 206011fa71b9SJerome Forissier { 206111fa71b9SJerome Forissier ret = ssl->f_recv( ssl->p_bio, 206211fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len ); 206311fa71b9SJerome Forissier } 206411fa71b9SJerome Forissier } 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 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); 207011fa71b9SJerome Forissier 207111fa71b9SJerome Forissier if( ret == 0 ) 207211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONN_EOF ); 207311fa71b9SJerome Forissier 207411fa71b9SJerome Forissier if( ret < 0 ) 207511fa71b9SJerome Forissier return( ret ); 207611fa71b9SJerome Forissier 20777901324dSJerome Forissier if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) 207811fa71b9SJerome Forissier { 207911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, 20807901324dSJerome Forissier ( "f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " were requested", 20817901324dSJerome Forissier ret, len ) ); 208211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 208311fa71b9SJerome Forissier } 208411fa71b9SJerome Forissier 208511fa71b9SJerome Forissier ssl->in_left += ret; 208611fa71b9SJerome Forissier } 208711fa71b9SJerome Forissier } 208811fa71b9SJerome Forissier 208911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); 209011fa71b9SJerome Forissier 209111fa71b9SJerome Forissier return( 0 ); 209211fa71b9SJerome Forissier } 209311fa71b9SJerome Forissier 209411fa71b9SJerome Forissier /* 209511fa71b9SJerome Forissier * Flush any data not yet written 209611fa71b9SJerome Forissier */ 209711fa71b9SJerome Forissier int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) 209811fa71b9SJerome Forissier { 209911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 210011fa71b9SJerome Forissier unsigned char *buf; 210111fa71b9SJerome Forissier 210211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); 210311fa71b9SJerome Forissier 210411fa71b9SJerome Forissier if( ssl->f_send == NULL ) 210511fa71b9SJerome Forissier { 210611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " 210711fa71b9SJerome Forissier "or mbedtls_ssl_set_bio()" ) ); 210811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 210911fa71b9SJerome Forissier } 211011fa71b9SJerome Forissier 211111fa71b9SJerome Forissier /* Avoid incrementing counter if data is flushed */ 211211fa71b9SJerome Forissier if( ssl->out_left == 0 ) 211311fa71b9SJerome Forissier { 211411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); 211511fa71b9SJerome Forissier return( 0 ); 211611fa71b9SJerome Forissier } 211711fa71b9SJerome Forissier 211811fa71b9SJerome Forissier while( ssl->out_left > 0 ) 211911fa71b9SJerome Forissier { 21207901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %" MBEDTLS_PRINTF_SIZET 21217901324dSJerome Forissier ", out_left: %" MBEDTLS_PRINTF_SIZET, 212211fa71b9SJerome Forissier mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); 212311fa71b9SJerome Forissier 212411fa71b9SJerome Forissier buf = ssl->out_hdr - ssl->out_left; 212511fa71b9SJerome Forissier ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); 212611fa71b9SJerome Forissier 212711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); 212811fa71b9SJerome Forissier 212911fa71b9SJerome Forissier if( ret <= 0 ) 213011fa71b9SJerome Forissier return( ret ); 213111fa71b9SJerome Forissier 21327901324dSJerome Forissier if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) 213311fa71b9SJerome Forissier { 213411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, 21357901324dSJerome Forissier ( "f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " bytes were sent", 21367901324dSJerome Forissier ret, ssl->out_left ) ); 213711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 213811fa71b9SJerome Forissier } 213911fa71b9SJerome Forissier 214011fa71b9SJerome Forissier ssl->out_left -= ret; 214111fa71b9SJerome Forissier } 214211fa71b9SJerome Forissier 214311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 214411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 214511fa71b9SJerome Forissier { 214611fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 214711fa71b9SJerome Forissier } 214811fa71b9SJerome Forissier else 214911fa71b9SJerome Forissier #endif 215011fa71b9SJerome Forissier { 215111fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 215211fa71b9SJerome Forissier } 215311fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 215411fa71b9SJerome Forissier 215511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); 215611fa71b9SJerome Forissier 215711fa71b9SJerome Forissier return( 0 ); 215811fa71b9SJerome Forissier } 215911fa71b9SJerome Forissier 216011fa71b9SJerome Forissier /* 216111fa71b9SJerome Forissier * Functions to handle the DTLS retransmission state machine 216211fa71b9SJerome Forissier */ 216311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 216411fa71b9SJerome Forissier /* 216511fa71b9SJerome Forissier * Append current handshake message to current outgoing flight 216611fa71b9SJerome Forissier */ 2167*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 216811fa71b9SJerome Forissier static int ssl_flight_append( mbedtls_ssl_context *ssl ) 216911fa71b9SJerome Forissier { 217011fa71b9SJerome Forissier mbedtls_ssl_flight_item *msg; 217111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); 217211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", 217311fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 217411fa71b9SJerome Forissier 217511fa71b9SJerome Forissier /* Allocate space for current message */ 217611fa71b9SJerome Forissier if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) 217711fa71b9SJerome Forissier { 21787901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 217911fa71b9SJerome Forissier sizeof( mbedtls_ssl_flight_item ) ) ); 218011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); 218111fa71b9SJerome Forissier } 218211fa71b9SJerome Forissier 218311fa71b9SJerome Forissier if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) 218411fa71b9SJerome Forissier { 21857901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 21867901324dSJerome Forissier ssl->out_msglen ) ); 218711fa71b9SJerome Forissier mbedtls_free( msg ); 218811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); 218911fa71b9SJerome Forissier } 219011fa71b9SJerome Forissier 219111fa71b9SJerome Forissier /* Copy current handshake message with headers */ 219211fa71b9SJerome Forissier memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); 219311fa71b9SJerome Forissier msg->len = ssl->out_msglen; 219411fa71b9SJerome Forissier msg->type = ssl->out_msgtype; 219511fa71b9SJerome Forissier msg->next = NULL; 219611fa71b9SJerome Forissier 219711fa71b9SJerome Forissier /* Append to the current flight */ 219811fa71b9SJerome Forissier if( ssl->handshake->flight == NULL ) 219911fa71b9SJerome Forissier ssl->handshake->flight = msg; 220011fa71b9SJerome Forissier else 220111fa71b9SJerome Forissier { 220211fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = ssl->handshake->flight; 220311fa71b9SJerome Forissier while( cur->next != NULL ) 220411fa71b9SJerome Forissier cur = cur->next; 220511fa71b9SJerome Forissier cur->next = msg; 220611fa71b9SJerome Forissier } 220711fa71b9SJerome Forissier 220811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); 220911fa71b9SJerome Forissier return( 0 ); 221011fa71b9SJerome Forissier } 221111fa71b9SJerome Forissier 221211fa71b9SJerome Forissier /* 221311fa71b9SJerome Forissier * Free the current flight of handshake messages 221411fa71b9SJerome Forissier */ 221511fa71b9SJerome Forissier void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight ) 221611fa71b9SJerome Forissier { 221711fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = flight; 221811fa71b9SJerome Forissier mbedtls_ssl_flight_item *next; 221911fa71b9SJerome Forissier 222011fa71b9SJerome Forissier while( cur != NULL ) 222111fa71b9SJerome Forissier { 222211fa71b9SJerome Forissier next = cur->next; 222311fa71b9SJerome Forissier 222411fa71b9SJerome Forissier mbedtls_free( cur->p ); 222511fa71b9SJerome Forissier mbedtls_free( cur ); 222611fa71b9SJerome Forissier 222711fa71b9SJerome Forissier cur = next; 222811fa71b9SJerome Forissier } 222911fa71b9SJerome Forissier } 223011fa71b9SJerome Forissier 223111fa71b9SJerome Forissier /* 223211fa71b9SJerome Forissier * Swap transform_out and out_ctr with the alternative ones 223311fa71b9SJerome Forissier */ 2234*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 223511fa71b9SJerome Forissier static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) 223611fa71b9SJerome Forissier { 223711fa71b9SJerome Forissier mbedtls_ssl_transform *tmp_transform; 223811fa71b9SJerome Forissier unsigned char tmp_out_ctr[8]; 223911fa71b9SJerome Forissier 224011fa71b9SJerome Forissier if( ssl->transform_out == ssl->handshake->alt_transform_out ) 224111fa71b9SJerome Forissier { 224211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); 224311fa71b9SJerome Forissier return( 0 ); 224411fa71b9SJerome Forissier } 224511fa71b9SJerome Forissier 224611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); 224711fa71b9SJerome Forissier 224811fa71b9SJerome Forissier /* Swap transforms */ 224911fa71b9SJerome Forissier tmp_transform = ssl->transform_out; 225011fa71b9SJerome Forissier ssl->transform_out = ssl->handshake->alt_transform_out; 225111fa71b9SJerome Forissier ssl->handshake->alt_transform_out = tmp_transform; 225211fa71b9SJerome Forissier 225311fa71b9SJerome Forissier /* Swap epoch + sequence_number */ 225411fa71b9SJerome Forissier memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); 225511fa71b9SJerome Forissier memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); 225611fa71b9SJerome Forissier memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); 225711fa71b9SJerome Forissier 225811fa71b9SJerome Forissier /* Adjust to the newly activated transform */ 225911fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 226011fa71b9SJerome Forissier 226111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 226211fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_activate != NULL ) 226311fa71b9SJerome Forissier { 226411fa71b9SJerome Forissier int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ); 226511fa71b9SJerome Forissier if( ret != 0 ) 226611fa71b9SJerome Forissier { 226711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); 226811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 226911fa71b9SJerome Forissier } 227011fa71b9SJerome Forissier } 227111fa71b9SJerome Forissier #endif 227211fa71b9SJerome Forissier 227311fa71b9SJerome Forissier return( 0 ); 227411fa71b9SJerome Forissier } 227511fa71b9SJerome Forissier 227611fa71b9SJerome Forissier /* 227711fa71b9SJerome Forissier * Retransmit the current flight of messages. 227811fa71b9SJerome Forissier */ 227911fa71b9SJerome Forissier int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) 228011fa71b9SJerome Forissier { 228111fa71b9SJerome Forissier int ret = 0; 228211fa71b9SJerome Forissier 228311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); 228411fa71b9SJerome Forissier 228511fa71b9SJerome Forissier ret = mbedtls_ssl_flight_transmit( ssl ); 228611fa71b9SJerome Forissier 228711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); 228811fa71b9SJerome Forissier 228911fa71b9SJerome Forissier return( ret ); 229011fa71b9SJerome Forissier } 229111fa71b9SJerome Forissier 229211fa71b9SJerome Forissier /* 229311fa71b9SJerome Forissier * Transmit or retransmit the current flight of messages. 229411fa71b9SJerome Forissier * 229511fa71b9SJerome Forissier * Need to remember the current message in case flush_output returns 229611fa71b9SJerome Forissier * WANT_WRITE, causing us to exit this function and come back later. 229711fa71b9SJerome Forissier * This function must be called until state is no longer SENDING. 229811fa71b9SJerome Forissier */ 229911fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) 230011fa71b9SJerome Forissier { 230111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 230211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); 230311fa71b9SJerome Forissier 230411fa71b9SJerome Forissier if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) 230511fa71b9SJerome Forissier { 230611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); 230711fa71b9SJerome Forissier 230811fa71b9SJerome Forissier ssl->handshake->cur_msg = ssl->handshake->flight; 230911fa71b9SJerome Forissier ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; 231011fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 231111fa71b9SJerome Forissier if( ret != 0 ) 231211fa71b9SJerome Forissier return( ret ); 231311fa71b9SJerome Forissier 231411fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; 231511fa71b9SJerome Forissier } 231611fa71b9SJerome Forissier 231711fa71b9SJerome Forissier while( ssl->handshake->cur_msg != NULL ) 231811fa71b9SJerome Forissier { 231911fa71b9SJerome Forissier size_t max_frag_len; 232011fa71b9SJerome Forissier const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; 232111fa71b9SJerome Forissier 232211fa71b9SJerome Forissier int const is_finished = 232311fa71b9SJerome Forissier ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && 232411fa71b9SJerome Forissier cur->p[0] == MBEDTLS_SSL_HS_FINISHED ); 232511fa71b9SJerome Forissier 232611fa71b9SJerome Forissier uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? 232711fa71b9SJerome Forissier SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; 232811fa71b9SJerome Forissier 232911fa71b9SJerome Forissier /* Swap epochs before sending Finished: we can't do it after 233011fa71b9SJerome Forissier * sending ChangeCipherSpec, in case write returns WANT_READ. 233111fa71b9SJerome Forissier * Must be done before copying, may change out_msg pointer */ 233211fa71b9SJerome Forissier if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) 233311fa71b9SJerome Forissier { 233411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); 233511fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 233611fa71b9SJerome Forissier if( ret != 0 ) 233711fa71b9SJerome Forissier return( ret ); 233811fa71b9SJerome Forissier } 233911fa71b9SJerome Forissier 234011fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram( ssl ); 234111fa71b9SJerome Forissier if( ret < 0 ) 234211fa71b9SJerome Forissier return( ret ); 234311fa71b9SJerome Forissier max_frag_len = (size_t) ret; 234411fa71b9SJerome Forissier 234511fa71b9SJerome Forissier /* CCS is copied as is, while HS messages may need fragmentation */ 234611fa71b9SJerome Forissier if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 234711fa71b9SJerome Forissier { 234811fa71b9SJerome Forissier if( max_frag_len == 0 ) 234911fa71b9SJerome Forissier { 235011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 235111fa71b9SJerome Forissier return( ret ); 235211fa71b9SJerome Forissier 235311fa71b9SJerome Forissier continue; 235411fa71b9SJerome Forissier } 235511fa71b9SJerome Forissier 235611fa71b9SJerome Forissier memcpy( ssl->out_msg, cur->p, cur->len ); 235711fa71b9SJerome Forissier ssl->out_msglen = cur->len; 235811fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 235911fa71b9SJerome Forissier 236011fa71b9SJerome Forissier /* Update position inside current message */ 236111fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur->len; 236211fa71b9SJerome Forissier } 236311fa71b9SJerome Forissier else 236411fa71b9SJerome Forissier { 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 237111fa71b9SJerome Forissier if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) 237211fa71b9SJerome Forissier { 237311fa71b9SJerome Forissier if( is_finished ) 237411fa71b9SJerome Forissier { 237511fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 237611fa71b9SJerome Forissier if( ret != 0 ) 237711fa71b9SJerome Forissier return( ret ); 237811fa71b9SJerome Forissier } 237911fa71b9SJerome Forissier 238011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 238111fa71b9SJerome Forissier return( ret ); 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 239011fa71b9SJerome Forissier if( frag_off == 0 && cur_hs_frag_len != hs_len ) 239111fa71b9SJerome Forissier { 239211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", 239311fa71b9SJerome Forissier (unsigned) cur_hs_frag_len, 239411fa71b9SJerome Forissier (unsigned) max_hs_frag_len ) ); 239511fa71b9SJerome Forissier } 239611fa71b9SJerome Forissier 239711fa71b9SJerome Forissier /* Messages are stored with handshake headers as if not fragmented, 239811fa71b9SJerome Forissier * copy beginning of headers then fill fragmentation fields. 239911fa71b9SJerome Forissier * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ 240011fa71b9SJerome Forissier memcpy( ssl->out_msg, cur->p, 6 ); 240111fa71b9SJerome Forissier 2402*039e02dfSJerome Forissier ssl->out_msg[6] = MBEDTLS_BYTE_2( frag_off ); 2403*039e02dfSJerome Forissier ssl->out_msg[7] = MBEDTLS_BYTE_1( frag_off ); 2404*039e02dfSJerome Forissier ssl->out_msg[8] = MBEDTLS_BYTE_0( frag_off ); 240511fa71b9SJerome Forissier 2406*039e02dfSJerome Forissier ssl->out_msg[ 9] = MBEDTLS_BYTE_2( cur_hs_frag_len ); 2407*039e02dfSJerome Forissier ssl->out_msg[10] = MBEDTLS_BYTE_1( cur_hs_frag_len ); 2408*039e02dfSJerome Forissier ssl->out_msg[11] = MBEDTLS_BYTE_0( cur_hs_frag_len ); 240911fa71b9SJerome Forissier 241011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); 241111fa71b9SJerome Forissier 241211fa71b9SJerome Forissier /* Copy the handshake message content and set records fields */ 241311fa71b9SJerome Forissier memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); 241411fa71b9SJerome Forissier ssl->out_msglen = cur_hs_frag_len + 12; 241511fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 241611fa71b9SJerome Forissier 241711fa71b9SJerome Forissier /* Update position inside current message */ 241811fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur_hs_frag_len; 241911fa71b9SJerome Forissier } 242011fa71b9SJerome Forissier 242111fa71b9SJerome Forissier /* If done with the current message move to the next one if any */ 242211fa71b9SJerome Forissier if( ssl->handshake->cur_msg_p >= cur->p + cur->len ) 242311fa71b9SJerome Forissier { 242411fa71b9SJerome Forissier if( cur->next != NULL ) 242511fa71b9SJerome Forissier { 242611fa71b9SJerome Forissier ssl->handshake->cur_msg = cur->next; 242711fa71b9SJerome Forissier ssl->handshake->cur_msg_p = cur->next->p + 12; 242811fa71b9SJerome Forissier } 242911fa71b9SJerome Forissier else 243011fa71b9SJerome Forissier { 243111fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 243211fa71b9SJerome Forissier ssl->handshake->cur_msg_p = NULL; 243311fa71b9SJerome Forissier } 243411fa71b9SJerome Forissier } 243511fa71b9SJerome Forissier 243611fa71b9SJerome Forissier /* Actually send the message out */ 243711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) 243811fa71b9SJerome Forissier { 243911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 244011fa71b9SJerome Forissier return( ret ); 244111fa71b9SJerome Forissier } 244211fa71b9SJerome Forissier } 244311fa71b9SJerome Forissier 244411fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 244511fa71b9SJerome Forissier return( ret ); 244611fa71b9SJerome Forissier 244711fa71b9SJerome Forissier /* Update state and set timer */ 244811fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 244911fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 245011fa71b9SJerome Forissier else 245111fa71b9SJerome Forissier { 245211fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 245311fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); 245411fa71b9SJerome Forissier } 245511fa71b9SJerome Forissier 245611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); 245711fa71b9SJerome Forissier 245811fa71b9SJerome Forissier return( 0 ); 245911fa71b9SJerome Forissier } 246011fa71b9SJerome Forissier 246111fa71b9SJerome Forissier /* 246211fa71b9SJerome Forissier * To be called when the last message of an incoming flight is received. 246311fa71b9SJerome Forissier */ 246411fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) 246511fa71b9SJerome Forissier { 246611fa71b9SJerome Forissier /* We won't need to resend that one any more */ 246711fa71b9SJerome Forissier mbedtls_ssl_flight_free( ssl->handshake->flight ); 246811fa71b9SJerome Forissier ssl->handshake->flight = NULL; 246911fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 247011fa71b9SJerome Forissier 247111fa71b9SJerome Forissier /* The next incoming flight will start with this msg_seq */ 247211fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; 247311fa71b9SJerome Forissier 247411fa71b9SJerome Forissier /* We don't want to remember CCS's across flight boundaries. */ 247511fa71b9SJerome Forissier ssl->handshake->buffering.seen_ccs = 0; 247611fa71b9SJerome Forissier 247711fa71b9SJerome Forissier /* Clear future message buffering structure. */ 247811fa71b9SJerome Forissier mbedtls_ssl_buffering_free( ssl ); 247911fa71b9SJerome Forissier 248011fa71b9SJerome Forissier /* Cancel timer */ 248111fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 248211fa71b9SJerome Forissier 248311fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 248411fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) 248511fa71b9SJerome Forissier { 248611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 248711fa71b9SJerome Forissier } 248811fa71b9SJerome Forissier else 248911fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; 249011fa71b9SJerome Forissier } 249111fa71b9SJerome Forissier 249211fa71b9SJerome Forissier /* 249311fa71b9SJerome Forissier * To be called when the last message of an outgoing flight is send. 249411fa71b9SJerome Forissier */ 249511fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) 249611fa71b9SJerome Forissier { 249711fa71b9SJerome Forissier ssl_reset_retransmit_timeout( ssl ); 249811fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); 249911fa71b9SJerome Forissier 250011fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 250111fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) 250211fa71b9SJerome Forissier { 250311fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 250411fa71b9SJerome Forissier } 250511fa71b9SJerome Forissier else 250611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 250711fa71b9SJerome Forissier } 250811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 250911fa71b9SJerome Forissier 251011fa71b9SJerome Forissier /* 251111fa71b9SJerome Forissier * Handshake layer functions 251211fa71b9SJerome Forissier */ 251311fa71b9SJerome Forissier 251411fa71b9SJerome Forissier /* 251511fa71b9SJerome Forissier * Write (DTLS: or queue) current handshake (including CCS) message. 251611fa71b9SJerome Forissier * 251711fa71b9SJerome Forissier * - fill in handshake headers 251811fa71b9SJerome Forissier * - update handshake checksum 251911fa71b9SJerome Forissier * - DTLS: save message for resending 252011fa71b9SJerome Forissier * - then pass to the record layer 252111fa71b9SJerome Forissier * 252211fa71b9SJerome Forissier * DTLS: except for HelloRequest, messages are only queued, and will only be 252311fa71b9SJerome Forissier * actually sent when calling flight_transmit() or resend(). 252411fa71b9SJerome Forissier * 252511fa71b9SJerome Forissier * Inputs: 252611fa71b9SJerome Forissier * - ssl->out_msglen: 4 + actual handshake message len 252711fa71b9SJerome Forissier * (4 is the size of handshake headers for TLS) 252811fa71b9SJerome Forissier * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) 252911fa71b9SJerome Forissier * - ssl->out_msg + 4: the handshake message body 253011fa71b9SJerome Forissier * 253111fa71b9SJerome Forissier * Outputs, ie state before passing to flight_append() or write_record(): 253211fa71b9SJerome Forissier * - ssl->out_msglen: the length of the record contents 253311fa71b9SJerome Forissier * (including handshake headers but excluding record headers) 253411fa71b9SJerome Forissier * - ssl->out_msg: the record contents (handshake headers + content) 253511fa71b9SJerome Forissier */ 253611fa71b9SJerome Forissier int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) 253711fa71b9SJerome Forissier { 253811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 253911fa71b9SJerome Forissier const size_t hs_len = ssl->out_msglen - 4; 254011fa71b9SJerome Forissier const unsigned char hs_type = ssl->out_msg[0]; 254111fa71b9SJerome Forissier 254211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); 254311fa71b9SJerome Forissier 254411fa71b9SJerome Forissier /* 254511fa71b9SJerome Forissier * Sanity checks 254611fa71b9SJerome Forissier */ 254711fa71b9SJerome Forissier if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && 254811fa71b9SJerome Forissier ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 254911fa71b9SJerome Forissier { 255011fa71b9SJerome Forissier /* In SSLv3, the client might send a NoCertificate alert. */ 255111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) 255211fa71b9SJerome Forissier if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && 255311fa71b9SJerome Forissier ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && 255411fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) 255511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ 255611fa71b9SJerome Forissier { 255711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 255811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 255911fa71b9SJerome Forissier } 256011fa71b9SJerome Forissier } 256111fa71b9SJerome Forissier 256211fa71b9SJerome Forissier /* Whenever we send anything different from a 256311fa71b9SJerome Forissier * HelloRequest we should be in a handshake - double check. */ 256411fa71b9SJerome Forissier if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 256511fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && 256611fa71b9SJerome Forissier ssl->handshake == NULL ) 256711fa71b9SJerome Forissier { 256811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 256911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 257011fa71b9SJerome Forissier } 257111fa71b9SJerome Forissier 257211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 257311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 257411fa71b9SJerome Forissier ssl->handshake != NULL && 257511fa71b9SJerome Forissier ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) 257611fa71b9SJerome Forissier { 257711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 257811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 257911fa71b9SJerome Forissier } 258011fa71b9SJerome Forissier #endif 258111fa71b9SJerome Forissier 258211fa71b9SJerome Forissier /* Double-check that we did not exceed the bounds 258311fa71b9SJerome Forissier * of the outgoing record buffer. 258411fa71b9SJerome Forissier * This should never fail as the various message 258511fa71b9SJerome Forissier * writing functions must obey the bounds of the 258611fa71b9SJerome Forissier * outgoing record buffer, but better be safe. 258711fa71b9SJerome Forissier * 258811fa71b9SJerome Forissier * Note: We deliberately do not check for the MTU or MFL here. 258911fa71b9SJerome Forissier */ 259011fa71b9SJerome Forissier if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) 259111fa71b9SJerome Forissier { 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 ) ); 259711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 259811fa71b9SJerome Forissier } 259911fa71b9SJerome Forissier 260011fa71b9SJerome Forissier /* 260111fa71b9SJerome Forissier * Fill handshake headers 260211fa71b9SJerome Forissier */ 260311fa71b9SJerome Forissier if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 260411fa71b9SJerome Forissier { 2605*039e02dfSJerome Forissier ssl->out_msg[1] = MBEDTLS_BYTE_2( hs_len ); 2606*039e02dfSJerome Forissier ssl->out_msg[2] = MBEDTLS_BYTE_1( hs_len ); 2607*039e02dfSJerome Forissier ssl->out_msg[3] = MBEDTLS_BYTE_0( hs_len ); 260811fa71b9SJerome Forissier 260911fa71b9SJerome Forissier /* 261011fa71b9SJerome Forissier * DTLS has additional fields in the Handshake layer, 261111fa71b9SJerome Forissier * between the length field and the actual payload: 261211fa71b9SJerome Forissier * uint16 message_seq; 261311fa71b9SJerome Forissier * uint24 fragment_offset; 261411fa71b9SJerome Forissier * uint24 fragment_length; 261511fa71b9SJerome Forissier */ 261611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 261711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 261811fa71b9SJerome Forissier { 261911fa71b9SJerome Forissier /* Make room for the additional DTLS fields */ 262011fa71b9SJerome Forissier if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) 262111fa71b9SJerome Forissier { 262211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " 26237901324dSJerome Forissier "size %" MBEDTLS_PRINTF_SIZET ", maximum %" MBEDTLS_PRINTF_SIZET, 26247901324dSJerome Forissier hs_len, 26257901324dSJerome Forissier (size_t) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); 262611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 262711fa71b9SJerome Forissier } 262811fa71b9SJerome Forissier 262911fa71b9SJerome Forissier memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); 263011fa71b9SJerome Forissier ssl->out_msglen += 8; 263111fa71b9SJerome Forissier 263211fa71b9SJerome Forissier /* Write message_seq and update it, except for HelloRequest */ 263311fa71b9SJerome Forissier if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) 263411fa71b9SJerome Forissier { 2635*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( ssl->handshake->out_msg_seq, ssl->out_msg, 4 ); 263611fa71b9SJerome Forissier ++( ssl->handshake->out_msg_seq ); 263711fa71b9SJerome Forissier } 263811fa71b9SJerome Forissier else 263911fa71b9SJerome Forissier { 264011fa71b9SJerome Forissier ssl->out_msg[4] = 0; 264111fa71b9SJerome Forissier ssl->out_msg[5] = 0; 264211fa71b9SJerome Forissier } 264311fa71b9SJerome Forissier 264411fa71b9SJerome Forissier /* Handshake hashes are computed without fragmentation, 264511fa71b9SJerome Forissier * so set frag_offset = 0 and frag_len = hs_len for now */ 264611fa71b9SJerome Forissier memset( ssl->out_msg + 6, 0x00, 3 ); 264711fa71b9SJerome Forissier memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); 264811fa71b9SJerome Forissier } 264911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 265011fa71b9SJerome Forissier 265111fa71b9SJerome Forissier /* Update running hashes of handshake messages seen */ 265211fa71b9SJerome Forissier if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) 265311fa71b9SJerome Forissier ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); 265411fa71b9SJerome Forissier } 265511fa71b9SJerome Forissier 265611fa71b9SJerome Forissier /* Either send now, or just save to be sent (and resent) later */ 265711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 265811fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 265911fa71b9SJerome Forissier ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 266011fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) 266111fa71b9SJerome Forissier { 266211fa71b9SJerome Forissier if( ( ret = ssl_flight_append( ssl ) ) != 0 ) 266311fa71b9SJerome Forissier { 266411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); 266511fa71b9SJerome Forissier return( ret ); 266611fa71b9SJerome Forissier } 266711fa71b9SJerome Forissier } 266811fa71b9SJerome Forissier else 266911fa71b9SJerome Forissier #endif 267011fa71b9SJerome Forissier { 267111fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 267211fa71b9SJerome Forissier { 267311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); 267411fa71b9SJerome Forissier return( ret ); 267511fa71b9SJerome Forissier } 267611fa71b9SJerome Forissier } 267711fa71b9SJerome Forissier 267811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); 267911fa71b9SJerome Forissier 268011fa71b9SJerome Forissier return( 0 ); 268111fa71b9SJerome Forissier } 268211fa71b9SJerome Forissier 268311fa71b9SJerome Forissier /* 268411fa71b9SJerome Forissier * Record layer functions 268511fa71b9SJerome Forissier */ 268611fa71b9SJerome Forissier 268711fa71b9SJerome Forissier /* 268811fa71b9SJerome Forissier * Write current record. 268911fa71b9SJerome Forissier * 269011fa71b9SJerome Forissier * Uses: 269111fa71b9SJerome Forissier * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) 269211fa71b9SJerome Forissier * - ssl->out_msglen: length of the record content (excl headers) 269311fa71b9SJerome Forissier * - ssl->out_msg: record content 269411fa71b9SJerome Forissier */ 269511fa71b9SJerome Forissier int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) 269611fa71b9SJerome Forissier { 269711fa71b9SJerome Forissier int ret, done = 0; 269811fa71b9SJerome Forissier size_t len = ssl->out_msglen; 269911fa71b9SJerome Forissier uint8_t flush = force_flush; 270011fa71b9SJerome Forissier 270111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); 270211fa71b9SJerome Forissier 270311fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 270411fa71b9SJerome Forissier if( ssl->transform_out != NULL && 270511fa71b9SJerome Forissier ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) 270611fa71b9SJerome Forissier { 270711fa71b9SJerome Forissier if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) 270811fa71b9SJerome Forissier { 270911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); 271011fa71b9SJerome Forissier return( ret ); 271111fa71b9SJerome Forissier } 271211fa71b9SJerome Forissier 271311fa71b9SJerome Forissier len = ssl->out_msglen; 271411fa71b9SJerome Forissier } 271511fa71b9SJerome Forissier #endif /*MBEDTLS_ZLIB_SUPPORT */ 271611fa71b9SJerome Forissier 271711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 271811fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_write != NULL ) 271911fa71b9SJerome Forissier { 272011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); 272111fa71b9SJerome Forissier 272211fa71b9SJerome Forissier ret = mbedtls_ssl_hw_record_write( ssl ); 272311fa71b9SJerome Forissier if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) 272411fa71b9SJerome Forissier { 272511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); 272611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 272711fa71b9SJerome Forissier } 272811fa71b9SJerome Forissier 272911fa71b9SJerome Forissier if( ret == 0 ) 273011fa71b9SJerome Forissier done = 1; 273111fa71b9SJerome Forissier } 273211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 273311fa71b9SJerome Forissier if( !done ) 273411fa71b9SJerome Forissier { 273511fa71b9SJerome Forissier unsigned i; 273611fa71b9SJerome Forissier size_t protected_record_size; 273711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 273811fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 273911fa71b9SJerome Forissier #else 274011fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 274111fa71b9SJerome Forissier #endif 274211fa71b9SJerome Forissier /* Skip writing the record content type to after the encryption, 274311fa71b9SJerome Forissier * as it may change when using the CID extension. */ 274411fa71b9SJerome Forissier 274511fa71b9SJerome Forissier mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, 274611fa71b9SJerome Forissier ssl->conf->transport, ssl->out_hdr + 1 ); 274711fa71b9SJerome Forissier 274811fa71b9SJerome Forissier memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); 2749*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0); 275011fa71b9SJerome Forissier 275111fa71b9SJerome Forissier if( ssl->transform_out != NULL ) 275211fa71b9SJerome Forissier { 275311fa71b9SJerome Forissier mbedtls_record rec; 275411fa71b9SJerome Forissier 275511fa71b9SJerome Forissier rec.buf = ssl->out_iv; 275611fa71b9SJerome Forissier rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf ); 275711fa71b9SJerome Forissier rec.data_len = ssl->out_msglen; 275811fa71b9SJerome Forissier rec.data_offset = ssl->out_msg - rec.buf; 275911fa71b9SJerome Forissier 276011fa71b9SJerome Forissier memcpy( &rec.ctr[0], ssl->out_ctr, 8 ); 276111fa71b9SJerome Forissier mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, 276211fa71b9SJerome Forissier ssl->conf->transport, rec.ver ); 276311fa71b9SJerome Forissier rec.type = ssl->out_msgtype; 276411fa71b9SJerome Forissier 276511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 276611fa71b9SJerome Forissier /* The CID is set by mbedtls_ssl_encrypt_buf(). */ 276711fa71b9SJerome Forissier rec.cid_len = 0; 276811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 276911fa71b9SJerome Forissier 277011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec, 277111fa71b9SJerome Forissier ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) 277211fa71b9SJerome Forissier { 277311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); 277411fa71b9SJerome Forissier return( ret ); 277511fa71b9SJerome Forissier } 277611fa71b9SJerome Forissier 277711fa71b9SJerome Forissier if( rec.data_offset != 0 ) 277811fa71b9SJerome Forissier { 277911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 278011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 278111fa71b9SJerome Forissier } 278211fa71b9SJerome Forissier 278311fa71b9SJerome Forissier /* Update the record content type and CID. */ 278411fa71b9SJerome Forissier ssl->out_msgtype = rec.type; 278511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID ) 278611fa71b9SJerome Forissier memcpy( ssl->out_cid, rec.cid, rec.cid_len ); 278711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 278811fa71b9SJerome Forissier ssl->out_msglen = len = rec.data_len; 2789*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->out_len, 0 ); 279011fa71b9SJerome Forissier } 279111fa71b9SJerome Forissier 279211fa71b9SJerome Forissier protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl ); 279311fa71b9SJerome Forissier 279411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 279511fa71b9SJerome Forissier /* In case of DTLS, double-check that we don't exceed 279611fa71b9SJerome Forissier * the remaining space in the datagram. */ 279711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 279811fa71b9SJerome Forissier { 279911fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram( ssl ); 280011fa71b9SJerome Forissier if( ret < 0 ) 280111fa71b9SJerome Forissier return( ret ); 280211fa71b9SJerome Forissier 280311fa71b9SJerome Forissier if( protected_record_size > (size_t) ret ) 280411fa71b9SJerome Forissier { 280511fa71b9SJerome Forissier /* Should never happen */ 280611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 280711fa71b9SJerome Forissier } 280811fa71b9SJerome Forissier } 280911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 281011fa71b9SJerome Forissier 281111fa71b9SJerome Forissier /* Now write the potentially updated record content type. */ 281211fa71b9SJerome Forissier ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; 281311fa71b9SJerome Forissier 28147901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %u, " 28157901324dSJerome Forissier "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET, 281611fa71b9SJerome Forissier ssl->out_hdr[0], ssl->out_hdr[1], 281711fa71b9SJerome Forissier ssl->out_hdr[2], len ) ); 281811fa71b9SJerome Forissier 281911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", 282011fa71b9SJerome Forissier ssl->out_hdr, protected_record_size ); 282111fa71b9SJerome Forissier 282211fa71b9SJerome Forissier ssl->out_left += protected_record_size; 282311fa71b9SJerome Forissier ssl->out_hdr += protected_record_size; 282411fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 282511fa71b9SJerome Forissier 282611fa71b9SJerome Forissier for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- ) 282711fa71b9SJerome Forissier if( ++ssl->cur_out_ctr[i - 1] != 0 ) 282811fa71b9SJerome Forissier break; 282911fa71b9SJerome Forissier 283011fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */ 283111fa71b9SJerome Forissier if( i == mbedtls_ssl_ep_len( ssl ) ) 283211fa71b9SJerome Forissier { 283311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); 283411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 283511fa71b9SJerome Forissier } 283611fa71b9SJerome Forissier } 283711fa71b9SJerome Forissier 283811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 283911fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 284011fa71b9SJerome Forissier flush == SSL_DONT_FORCE_FLUSH ) 284111fa71b9SJerome Forissier { 284211fa71b9SJerome Forissier size_t remaining; 284311fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram( ssl ); 284411fa71b9SJerome Forissier if( ret < 0 ) 284511fa71b9SJerome Forissier { 284611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", 284711fa71b9SJerome Forissier ret ); 284811fa71b9SJerome Forissier return( ret ); 284911fa71b9SJerome Forissier } 285011fa71b9SJerome Forissier 285111fa71b9SJerome Forissier remaining = (size_t) ret; 285211fa71b9SJerome Forissier if( remaining == 0 ) 285311fa71b9SJerome Forissier { 285411fa71b9SJerome Forissier flush = SSL_FORCE_FLUSH; 285511fa71b9SJerome Forissier } 285611fa71b9SJerome Forissier else 285711fa71b9SJerome Forissier { 285811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); 285911fa71b9SJerome Forissier } 286011fa71b9SJerome Forissier } 286111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 286211fa71b9SJerome Forissier 286311fa71b9SJerome Forissier if( ( flush == SSL_FORCE_FLUSH ) && 286411fa71b9SJerome Forissier ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 286511fa71b9SJerome Forissier { 286611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); 286711fa71b9SJerome Forissier return( ret ); 286811fa71b9SJerome Forissier } 286911fa71b9SJerome Forissier 287011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); 287111fa71b9SJerome Forissier 287211fa71b9SJerome Forissier return( 0 ); 287311fa71b9SJerome Forissier } 287411fa71b9SJerome Forissier 287511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 287611fa71b9SJerome Forissier 2877*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 287811fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) 287911fa71b9SJerome Forissier { 288011fa71b9SJerome Forissier if( ssl->in_msglen < ssl->in_hslen || 288111fa71b9SJerome Forissier memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || 288211fa71b9SJerome Forissier memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) 288311fa71b9SJerome Forissier { 288411fa71b9SJerome Forissier return( 1 ); 288511fa71b9SJerome Forissier } 288611fa71b9SJerome Forissier return( 0 ); 288711fa71b9SJerome Forissier } 288811fa71b9SJerome Forissier 288911fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) 289011fa71b9SJerome Forissier { 289111fa71b9SJerome Forissier return( ( ssl->in_msg[9] << 16 ) | 289211fa71b9SJerome Forissier ( ssl->in_msg[10] << 8 ) | 289311fa71b9SJerome Forissier ssl->in_msg[11] ); 289411fa71b9SJerome Forissier } 289511fa71b9SJerome Forissier 289611fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) 289711fa71b9SJerome Forissier { 289811fa71b9SJerome Forissier return( ( ssl->in_msg[6] << 16 ) | 289911fa71b9SJerome Forissier ( ssl->in_msg[7] << 8 ) | 290011fa71b9SJerome Forissier ssl->in_msg[8] ); 290111fa71b9SJerome Forissier } 290211fa71b9SJerome Forissier 2903*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 290411fa71b9SJerome Forissier static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) 290511fa71b9SJerome Forissier { 290611fa71b9SJerome Forissier uint32_t msg_len, frag_off, frag_len; 290711fa71b9SJerome Forissier 290811fa71b9SJerome Forissier msg_len = ssl_get_hs_total_len( ssl ); 290911fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off( ssl ); 291011fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len( ssl ); 291111fa71b9SJerome Forissier 291211fa71b9SJerome Forissier if( frag_off > msg_len ) 291311fa71b9SJerome Forissier return( -1 ); 291411fa71b9SJerome Forissier 291511fa71b9SJerome Forissier if( frag_len > msg_len - frag_off ) 291611fa71b9SJerome Forissier return( -1 ); 291711fa71b9SJerome Forissier 291811fa71b9SJerome Forissier if( frag_len + 12 > ssl->in_msglen ) 291911fa71b9SJerome Forissier return( -1 ); 292011fa71b9SJerome Forissier 292111fa71b9SJerome Forissier return( 0 ); 292211fa71b9SJerome Forissier } 292311fa71b9SJerome Forissier 292411fa71b9SJerome Forissier /* 292511fa71b9SJerome Forissier * Mark bits in bitmask (used for DTLS HS reassembly) 292611fa71b9SJerome Forissier */ 292711fa71b9SJerome Forissier static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) 292811fa71b9SJerome Forissier { 292911fa71b9SJerome Forissier unsigned int start_bits, end_bits; 293011fa71b9SJerome Forissier 293111fa71b9SJerome Forissier start_bits = 8 - ( offset % 8 ); 293211fa71b9SJerome Forissier if( start_bits != 8 ) 293311fa71b9SJerome Forissier { 293411fa71b9SJerome Forissier size_t first_byte_idx = offset / 8; 293511fa71b9SJerome Forissier 293611fa71b9SJerome Forissier /* Special case */ 293711fa71b9SJerome Forissier if( len <= start_bits ) 293811fa71b9SJerome Forissier { 293911fa71b9SJerome Forissier for( ; len != 0; len-- ) 294011fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << ( start_bits - len ); 294111fa71b9SJerome Forissier 294211fa71b9SJerome Forissier /* Avoid potential issues with offset or len becoming invalid */ 294311fa71b9SJerome Forissier return; 294411fa71b9SJerome Forissier } 294511fa71b9SJerome Forissier 294611fa71b9SJerome Forissier offset += start_bits; /* Now offset % 8 == 0 */ 294711fa71b9SJerome Forissier len -= start_bits; 294811fa71b9SJerome Forissier 294911fa71b9SJerome Forissier for( ; start_bits != 0; start_bits-- ) 295011fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << ( start_bits - 1 ); 295111fa71b9SJerome Forissier } 295211fa71b9SJerome Forissier 295311fa71b9SJerome Forissier end_bits = len % 8; 295411fa71b9SJerome Forissier if( end_bits != 0 ) 295511fa71b9SJerome Forissier { 295611fa71b9SJerome Forissier size_t last_byte_idx = ( offset + len ) / 8; 295711fa71b9SJerome Forissier 295811fa71b9SJerome Forissier len -= end_bits; /* Now len % 8 == 0 */ 295911fa71b9SJerome Forissier 296011fa71b9SJerome Forissier for( ; end_bits != 0; end_bits-- ) 296111fa71b9SJerome Forissier mask[last_byte_idx] |= 1 << ( 8 - end_bits ); 296211fa71b9SJerome Forissier } 296311fa71b9SJerome Forissier 296411fa71b9SJerome Forissier memset( mask + offset / 8, 0xFF, len / 8 ); 296511fa71b9SJerome Forissier } 296611fa71b9SJerome Forissier 296711fa71b9SJerome Forissier /* 296811fa71b9SJerome Forissier * Check that bitmask is full 296911fa71b9SJerome Forissier */ 2970*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 297111fa71b9SJerome Forissier static int ssl_bitmask_check( unsigned char *mask, size_t len ) 297211fa71b9SJerome Forissier { 297311fa71b9SJerome Forissier size_t i; 297411fa71b9SJerome Forissier 297511fa71b9SJerome Forissier for( i = 0; i < len / 8; i++ ) 297611fa71b9SJerome Forissier if( mask[i] != 0xFF ) 297711fa71b9SJerome Forissier return( -1 ); 297811fa71b9SJerome Forissier 297911fa71b9SJerome Forissier for( i = 0; i < len % 8; i++ ) 298011fa71b9SJerome Forissier if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) 298111fa71b9SJerome Forissier return( -1 ); 298211fa71b9SJerome Forissier 298311fa71b9SJerome Forissier return( 0 ); 298411fa71b9SJerome Forissier } 298511fa71b9SJerome Forissier 298611fa71b9SJerome Forissier /* msg_len does not include the handshake header */ 298711fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size( size_t msg_len, 298811fa71b9SJerome Forissier unsigned add_bitmap ) 298911fa71b9SJerome Forissier { 299011fa71b9SJerome Forissier size_t alloc_len; 299111fa71b9SJerome Forissier 299211fa71b9SJerome Forissier alloc_len = 12; /* Handshake header */ 299311fa71b9SJerome Forissier alloc_len += msg_len; /* Content buffer */ 299411fa71b9SJerome Forissier 299511fa71b9SJerome Forissier if( add_bitmap ) 299611fa71b9SJerome Forissier alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ 299711fa71b9SJerome Forissier 299811fa71b9SJerome Forissier return( alloc_len ); 299911fa71b9SJerome Forissier } 300011fa71b9SJerome Forissier 300111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 300211fa71b9SJerome Forissier 300311fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) 300411fa71b9SJerome Forissier { 300511fa71b9SJerome Forissier return( ( ssl->in_msg[1] << 16 ) | 300611fa71b9SJerome Forissier ( ssl->in_msg[2] << 8 ) | 300711fa71b9SJerome Forissier ssl->in_msg[3] ); 300811fa71b9SJerome Forissier } 300911fa71b9SJerome Forissier 301011fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) 301111fa71b9SJerome Forissier { 301211fa71b9SJerome Forissier if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) 301311fa71b9SJerome Forissier { 30147901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %" MBEDTLS_PRINTF_SIZET, 301511fa71b9SJerome Forissier ssl->in_msglen ) ); 301611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 301711fa71b9SJerome Forissier } 301811fa71b9SJerome Forissier 301911fa71b9SJerome Forissier ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); 302011fa71b9SJerome Forissier 302111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" 30227901324dSJerome Forissier " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET, 302311fa71b9SJerome Forissier ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); 302411fa71b9SJerome Forissier 302511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 302611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 302711fa71b9SJerome Forissier { 302811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 302911fa71b9SJerome Forissier unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; 303011fa71b9SJerome Forissier 303111fa71b9SJerome Forissier if( ssl_check_hs_header( ssl ) != 0 ) 303211fa71b9SJerome Forissier { 303311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); 303411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 303511fa71b9SJerome Forissier } 303611fa71b9SJerome Forissier 303711fa71b9SJerome Forissier if( ssl->handshake != NULL && 303811fa71b9SJerome Forissier ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && 303911fa71b9SJerome Forissier recv_msg_seq != ssl->handshake->in_msg_seq ) || 304011fa71b9SJerome Forissier ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && 304111fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) 304211fa71b9SJerome Forissier { 304311fa71b9SJerome Forissier if( recv_msg_seq > ssl->handshake->in_msg_seq ) 304411fa71b9SJerome Forissier { 304511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", 304611fa71b9SJerome Forissier recv_msg_seq, 304711fa71b9SJerome Forissier ssl->handshake->in_msg_seq ) ); 304811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 304911fa71b9SJerome Forissier } 305011fa71b9SJerome Forissier 305111fa71b9SJerome Forissier /* Retransmit only on last message from previous flight, to avoid 305211fa71b9SJerome Forissier * too many retransmissions. 305311fa71b9SJerome Forissier * Besides, No sane server ever retransmits HelloVerifyRequest */ 305411fa71b9SJerome Forissier if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && 305511fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) 305611fa71b9SJerome Forissier { 305711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " 30587901324dSJerome Forissier "message_seq = %u, start_of_flight = %u", 305911fa71b9SJerome Forissier recv_msg_seq, 306011fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq ) ); 306111fa71b9SJerome Forissier 306211fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) 306311fa71b9SJerome Forissier { 306411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); 306511fa71b9SJerome Forissier return( ret ); 306611fa71b9SJerome Forissier } 306711fa71b9SJerome Forissier } 306811fa71b9SJerome Forissier else 306911fa71b9SJerome Forissier { 307011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " 30717901324dSJerome Forissier "message_seq = %u, expected = %u", 307211fa71b9SJerome Forissier recv_msg_seq, 307311fa71b9SJerome Forissier ssl->handshake->in_msg_seq ) ); 307411fa71b9SJerome Forissier } 307511fa71b9SJerome Forissier 307611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 307711fa71b9SJerome Forissier } 307811fa71b9SJerome Forissier /* Wait until message completion to increment in_msg_seq */ 307911fa71b9SJerome Forissier 308011fa71b9SJerome Forissier /* Message reassembly is handled alongside buffering of future 308111fa71b9SJerome Forissier * messages; the commonality is that both handshake fragments and 308211fa71b9SJerome Forissier * future messages cannot be forwarded immediately to the 308311fa71b9SJerome Forissier * handshake logic layer. */ 308411fa71b9SJerome Forissier if( ssl_hs_is_proper_fragment( ssl ) == 1 ) 308511fa71b9SJerome Forissier { 308611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); 308711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 308811fa71b9SJerome Forissier } 308911fa71b9SJerome Forissier } 309011fa71b9SJerome Forissier else 309111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 309211fa71b9SJerome Forissier /* With TLS we don't handle fragmentation (for now) */ 309311fa71b9SJerome Forissier if( ssl->in_msglen < ssl->in_hslen ) 309411fa71b9SJerome Forissier { 309511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); 309611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 309711fa71b9SJerome Forissier } 309811fa71b9SJerome Forissier 309911fa71b9SJerome Forissier return( 0 ); 310011fa71b9SJerome Forissier } 310111fa71b9SJerome Forissier 310211fa71b9SJerome Forissier void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) 310311fa71b9SJerome Forissier { 310411fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 310511fa71b9SJerome Forissier 310611fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) 310711fa71b9SJerome Forissier { 310811fa71b9SJerome Forissier ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); 310911fa71b9SJerome Forissier } 311011fa71b9SJerome Forissier 311111fa71b9SJerome Forissier /* Handshake message is complete, increment counter */ 311211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 311311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 311411fa71b9SJerome Forissier ssl->handshake != NULL ) 311511fa71b9SJerome Forissier { 311611fa71b9SJerome Forissier unsigned offset; 311711fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 311811fa71b9SJerome Forissier 311911fa71b9SJerome Forissier /* Increment handshake sequence number */ 312011fa71b9SJerome Forissier hs->in_msg_seq++; 312111fa71b9SJerome Forissier 312211fa71b9SJerome Forissier /* 312311fa71b9SJerome Forissier * Clear up handshake buffering and reassembly structure. 312411fa71b9SJerome Forissier */ 312511fa71b9SJerome Forissier 312611fa71b9SJerome Forissier /* Free first entry */ 312711fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, 0 ); 312811fa71b9SJerome Forissier 312911fa71b9SJerome Forissier /* Shift all other entries */ 313011fa71b9SJerome Forissier for( offset = 0, hs_buf = &hs->buffering.hs[0]; 313111fa71b9SJerome Forissier offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; 313211fa71b9SJerome Forissier offset++, hs_buf++ ) 313311fa71b9SJerome Forissier { 313411fa71b9SJerome Forissier *hs_buf = *(hs_buf + 1); 313511fa71b9SJerome Forissier } 313611fa71b9SJerome Forissier 313711fa71b9SJerome Forissier /* Create a fresh last entry */ 313811fa71b9SJerome Forissier memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); 313911fa71b9SJerome Forissier } 314011fa71b9SJerome Forissier #endif 314111fa71b9SJerome Forissier } 314211fa71b9SJerome Forissier 314311fa71b9SJerome Forissier /* 314411fa71b9SJerome Forissier * DTLS anti-replay: RFC 6347 4.1.2.6 314511fa71b9SJerome Forissier * 314611fa71b9SJerome Forissier * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). 314711fa71b9SJerome Forissier * Bit n is set iff record number in_window_top - n has been seen. 314811fa71b9SJerome Forissier * 314911fa71b9SJerome Forissier * Usually, in_window_top is the last record number seen and the lsb of 315011fa71b9SJerome Forissier * in_window is set. The only exception is the initial state (record number 0 315111fa71b9SJerome Forissier * not seen yet). 315211fa71b9SJerome Forissier */ 315311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 315411fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) 315511fa71b9SJerome Forissier { 315611fa71b9SJerome Forissier ssl->in_window_top = 0; 315711fa71b9SJerome Forissier ssl->in_window = 0; 315811fa71b9SJerome Forissier } 315911fa71b9SJerome Forissier 316011fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) 316111fa71b9SJerome Forissier { 316211fa71b9SJerome Forissier return( ( (uint64_t) buf[0] << 40 ) | 316311fa71b9SJerome Forissier ( (uint64_t) buf[1] << 32 ) | 316411fa71b9SJerome Forissier ( (uint64_t) buf[2] << 24 ) | 316511fa71b9SJerome Forissier ( (uint64_t) buf[3] << 16 ) | 316611fa71b9SJerome Forissier ( (uint64_t) buf[4] << 8 ) | 316711fa71b9SJerome Forissier ( (uint64_t) buf[5] ) ); 316811fa71b9SJerome Forissier } 316911fa71b9SJerome Forissier 3170*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 317111fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr ) 317211fa71b9SJerome Forissier { 317311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 317411fa71b9SJerome Forissier unsigned char *original_in_ctr; 317511fa71b9SJerome Forissier 317611fa71b9SJerome Forissier // save original in_ctr 317711fa71b9SJerome Forissier original_in_ctr = ssl->in_ctr; 317811fa71b9SJerome Forissier 317911fa71b9SJerome Forissier // use counter from record 318011fa71b9SJerome Forissier ssl->in_ctr = record_in_ctr; 318111fa71b9SJerome Forissier 318211fa71b9SJerome Forissier ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl ); 318311fa71b9SJerome Forissier 318411fa71b9SJerome Forissier // restore the counter 318511fa71b9SJerome Forissier ssl->in_ctr = original_in_ctr; 318611fa71b9SJerome Forissier 318711fa71b9SJerome Forissier return ret; 318811fa71b9SJerome Forissier } 318911fa71b9SJerome Forissier 319011fa71b9SJerome Forissier /* 319111fa71b9SJerome Forissier * Return 0 if sequence number is acceptable, -1 otherwise 319211fa71b9SJerome Forissier */ 319311fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl ) 319411fa71b9SJerome Forissier { 319511fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); 319611fa71b9SJerome Forissier uint64_t bit; 319711fa71b9SJerome Forissier 319811fa71b9SJerome Forissier if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) 319911fa71b9SJerome Forissier return( 0 ); 320011fa71b9SJerome Forissier 320111fa71b9SJerome Forissier if( rec_seqnum > ssl->in_window_top ) 320211fa71b9SJerome Forissier return( 0 ); 320311fa71b9SJerome Forissier 320411fa71b9SJerome Forissier bit = ssl->in_window_top - rec_seqnum; 320511fa71b9SJerome Forissier 320611fa71b9SJerome Forissier if( bit >= 64 ) 320711fa71b9SJerome Forissier return( -1 ); 320811fa71b9SJerome Forissier 320911fa71b9SJerome Forissier if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) 321011fa71b9SJerome Forissier return( -1 ); 321111fa71b9SJerome Forissier 321211fa71b9SJerome Forissier return( 0 ); 321311fa71b9SJerome Forissier } 321411fa71b9SJerome Forissier 321511fa71b9SJerome Forissier /* 321611fa71b9SJerome Forissier * Update replay window on new validated record 321711fa71b9SJerome Forissier */ 321811fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) 321911fa71b9SJerome Forissier { 322011fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); 322111fa71b9SJerome Forissier 322211fa71b9SJerome Forissier if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) 322311fa71b9SJerome Forissier return; 322411fa71b9SJerome Forissier 322511fa71b9SJerome Forissier if( rec_seqnum > ssl->in_window_top ) 322611fa71b9SJerome Forissier { 322711fa71b9SJerome Forissier /* Update window_top and the contents of the window */ 322811fa71b9SJerome Forissier uint64_t shift = rec_seqnum - ssl->in_window_top; 322911fa71b9SJerome Forissier 323011fa71b9SJerome Forissier if( shift >= 64 ) 323111fa71b9SJerome Forissier ssl->in_window = 1; 323211fa71b9SJerome Forissier else 323311fa71b9SJerome Forissier { 323411fa71b9SJerome Forissier ssl->in_window <<= shift; 323511fa71b9SJerome Forissier ssl->in_window |= 1; 323611fa71b9SJerome Forissier } 323711fa71b9SJerome Forissier 323811fa71b9SJerome Forissier ssl->in_window_top = rec_seqnum; 323911fa71b9SJerome Forissier } 324011fa71b9SJerome Forissier else 324111fa71b9SJerome Forissier { 324211fa71b9SJerome Forissier /* Mark that number as seen in the current window */ 324311fa71b9SJerome Forissier uint64_t bit = ssl->in_window_top - rec_seqnum; 324411fa71b9SJerome Forissier 324511fa71b9SJerome Forissier if( bit < 64 ) /* Always true, but be extra sure */ 324611fa71b9SJerome Forissier ssl->in_window |= (uint64_t) 1 << bit; 324711fa71b9SJerome Forissier } 324811fa71b9SJerome Forissier } 324911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ 325011fa71b9SJerome Forissier 325111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 325211fa71b9SJerome Forissier /* 3253*039e02dfSJerome Forissier * Check if a datagram looks like a ClientHello with a valid cookie, 3254*039e02dfSJerome Forissier * and if it doesn't, generate a HelloVerifyRequest message. 325511fa71b9SJerome Forissier * Both input and output include full DTLS headers. 325611fa71b9SJerome Forissier * 325711fa71b9SJerome Forissier * - if cookie is valid, return 0 325811fa71b9SJerome Forissier * - if ClientHello looks superficially valid but cookie is not, 325911fa71b9SJerome Forissier * fill obuf and set olen, then 326011fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED 326111fa71b9SJerome Forissier * - otherwise return a specific error code 326211fa71b9SJerome Forissier */ 3263*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 3264*039e02dfSJerome Forissier MBEDTLS_STATIC_TESTABLE 3265*039e02dfSJerome Forissier int mbedtls_ssl_check_dtls_clihlo_cookie( 3266*039e02dfSJerome Forissier mbedtls_ssl_context *ssl, 326711fa71b9SJerome Forissier const unsigned char *cli_id, size_t cli_id_len, 326811fa71b9SJerome Forissier const unsigned char *in, size_t in_len, 326911fa71b9SJerome Forissier unsigned char *obuf, size_t buf_len, size_t *olen ) 327011fa71b9SJerome Forissier { 327111fa71b9SJerome Forissier size_t sid_len, cookie_len; 327211fa71b9SJerome Forissier unsigned char *p; 327311fa71b9SJerome Forissier 327411fa71b9SJerome Forissier /* 327511fa71b9SJerome Forissier * Structure of ClientHello with record and handshake headers, 327611fa71b9SJerome Forissier * and expected values. We don't need to check a lot, more checks will be 327711fa71b9SJerome Forissier * done when actually parsing the ClientHello - skipping those checks 327811fa71b9SJerome Forissier * avoids code duplication and does not make cookie forging any easier. 327911fa71b9SJerome Forissier * 328011fa71b9SJerome Forissier * 0-0 ContentType type; copied, must be handshake 328111fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 328211fa71b9SJerome Forissier * 3-4 uint16 epoch; copied, must be 0 328311fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 328411fa71b9SJerome Forissier * 11-12 uint16 length; (ignored) 328511fa71b9SJerome Forissier * 328611fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; (ignored) 328711fa71b9SJerome Forissier * 14-16 uint24 length; (ignored) 328811fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 328911fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied, must be 0 329011fa71b9SJerome Forissier * 22-24 uint24 fragment_length; (ignored) 329111fa71b9SJerome Forissier * 329211fa71b9SJerome Forissier * 25-26 ProtocolVersion client_version; (ignored) 329311fa71b9SJerome Forissier * 27-58 Random random; (ignored) 329411fa71b9SJerome Forissier * 59-xx SessionID session_id; 1 byte len + sid_len content 329511fa71b9SJerome Forissier * 60+ opaque cookie<0..2^8-1>; 1 byte len + content 329611fa71b9SJerome Forissier * ... 329711fa71b9SJerome Forissier * 329811fa71b9SJerome Forissier * Minimum length is 61 bytes. 329911fa71b9SJerome Forissier */ 3300*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: in_len=%u", 3301*039e02dfSJerome Forissier (unsigned) in_len ) ); 3302*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "cli_id", cli_id, cli_id_len ); 3303*039e02dfSJerome Forissier if( in_len < 61 ) 3304*039e02dfSJerome Forissier { 3305*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: record too short" ) ); 3306*039e02dfSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 3307*039e02dfSJerome Forissier } 3308*039e02dfSJerome Forissier if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || 330911fa71b9SJerome Forissier in[3] != 0 || in[4] != 0 || 331011fa71b9SJerome Forissier in[19] != 0 || in[20] != 0 || in[21] != 0 ) 331111fa71b9SJerome Forissier { 3312*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: not a good ClientHello" ) ); 3313*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( " type=%u epoch=%u fragment_offset=%u", 3314*039e02dfSJerome Forissier in[0], 3315*039e02dfSJerome Forissier (unsigned) in[3] << 8 | in[4], 3316*039e02dfSJerome Forissier (unsigned) in[19] << 16 | in[20] << 8 | in[21] ) ); 331711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 331811fa71b9SJerome Forissier } 331911fa71b9SJerome Forissier 332011fa71b9SJerome Forissier sid_len = in[59]; 3321*039e02dfSJerome Forissier if( 59 + 1 + sid_len + 1 > in_len ) 3322*039e02dfSJerome Forissier { 3323*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: sid_len=%u > %u", 3324*039e02dfSJerome Forissier (unsigned) sid_len, 3325*039e02dfSJerome Forissier (unsigned) in_len - 61 ) ); 332611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 3327*039e02dfSJerome Forissier } 3328*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "sid received from network", 3329*039e02dfSJerome Forissier in + 60, sid_len ); 333011fa71b9SJerome Forissier 333111fa71b9SJerome Forissier cookie_len = in[60 + sid_len]; 3332*039e02dfSJerome Forissier if( 59 + 1 + sid_len + 1 + cookie_len > in_len ) 3333*039e02dfSJerome Forissier { 3334*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: cookie_len=%u > %u", 3335*039e02dfSJerome Forissier (unsigned) cookie_len, 3336*039e02dfSJerome Forissier (unsigned) ( in_len - sid_len - 61 ) ) ); 333711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 3338*039e02dfSJerome Forissier } 333911fa71b9SJerome Forissier 3340*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "cookie received from network", 3341*039e02dfSJerome Forissier in + sid_len + 61, cookie_len ); 3342*039e02dfSJerome Forissier if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, 3343*039e02dfSJerome Forissier in + sid_len + 61, cookie_len, 334411fa71b9SJerome Forissier cli_id, cli_id_len ) == 0 ) 334511fa71b9SJerome Forissier { 3346*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: valid" ) ); 334711fa71b9SJerome Forissier return( 0 ); 334811fa71b9SJerome Forissier } 334911fa71b9SJerome Forissier 335011fa71b9SJerome Forissier /* 335111fa71b9SJerome Forissier * If we get here, we've got an invalid cookie, let's prepare HVR. 335211fa71b9SJerome Forissier * 335311fa71b9SJerome Forissier * 0-0 ContentType type; copied 335411fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 335511fa71b9SJerome Forissier * 3-4 uint16 epoch; copied 335611fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 335711fa71b9SJerome Forissier * 11-12 uint16 length; olen - 13 335811fa71b9SJerome Forissier * 335911fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; hello_verify_request 336011fa71b9SJerome Forissier * 14-16 uint24 length; olen - 25 336111fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 336211fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied 336311fa71b9SJerome Forissier * 22-24 uint24 fragment_length; olen - 25 336411fa71b9SJerome Forissier * 336511fa71b9SJerome Forissier * 25-26 ProtocolVersion server_version; 0xfe 0xff 336611fa71b9SJerome Forissier * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie 336711fa71b9SJerome Forissier * 336811fa71b9SJerome Forissier * Minimum length is 28. 336911fa71b9SJerome Forissier */ 337011fa71b9SJerome Forissier if( buf_len < 28 ) 337111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 337211fa71b9SJerome Forissier 337311fa71b9SJerome Forissier /* Copy most fields and adapt others */ 337411fa71b9SJerome Forissier memcpy( obuf, in, 25 ); 337511fa71b9SJerome Forissier obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; 337611fa71b9SJerome Forissier obuf[25] = 0xfe; 337711fa71b9SJerome Forissier obuf[26] = 0xff; 337811fa71b9SJerome Forissier 337911fa71b9SJerome Forissier /* Generate and write actual cookie */ 338011fa71b9SJerome Forissier p = obuf + 28; 3381*039e02dfSJerome Forissier if( ssl->conf->f_cookie_write( ssl->conf->p_cookie, 3382*039e02dfSJerome Forissier &p, obuf + buf_len, 3383*039e02dfSJerome Forissier cli_id, cli_id_len ) != 0 ) 338411fa71b9SJerome Forissier { 338511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 338611fa71b9SJerome Forissier } 338711fa71b9SJerome Forissier 338811fa71b9SJerome Forissier *olen = p - obuf; 338911fa71b9SJerome Forissier 339011fa71b9SJerome Forissier /* Go back and fill length fields */ 339111fa71b9SJerome Forissier obuf[27] = (unsigned char)( *olen - 28 ); 339211fa71b9SJerome Forissier 3393*039e02dfSJerome Forissier obuf[14] = obuf[22] = MBEDTLS_BYTE_2( *olen - 25 ); 3394*039e02dfSJerome Forissier obuf[15] = obuf[23] = MBEDTLS_BYTE_1( *olen - 25 ); 3395*039e02dfSJerome Forissier obuf[16] = obuf[24] = MBEDTLS_BYTE_0( *olen - 25 ); 339611fa71b9SJerome Forissier 3397*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( *olen - 13, obuf, 11 ); 339811fa71b9SJerome Forissier 339911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); 340011fa71b9SJerome Forissier } 340111fa71b9SJerome Forissier 340211fa71b9SJerome Forissier /* 340311fa71b9SJerome Forissier * Handle possible client reconnect with the same UDP quadruplet 340411fa71b9SJerome Forissier * (RFC 6347 Section 4.2.8). 340511fa71b9SJerome Forissier * 340611fa71b9SJerome Forissier * Called by ssl_parse_record_header() in case we receive an epoch 0 record 340711fa71b9SJerome Forissier * that looks like a ClientHello. 340811fa71b9SJerome Forissier * 340911fa71b9SJerome Forissier * - if the input looks like a ClientHello without cookies, 341011fa71b9SJerome Forissier * send back HelloVerifyRequest, then return 0 341111fa71b9SJerome Forissier * - if the input looks like a ClientHello with a valid cookie, 341211fa71b9SJerome Forissier * reset the session of the current context, and 341311fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT 341411fa71b9SJerome Forissier * - if anything goes wrong, return a specific error code 341511fa71b9SJerome Forissier * 341611fa71b9SJerome Forissier * This function is called (through ssl_check_client_reconnect()) when an 341711fa71b9SJerome Forissier * unexpected record is found in ssl_get_next_record(), which will discard the 341811fa71b9SJerome Forissier * record if we return 0, and bubble up the return value otherwise (this 341911fa71b9SJerome Forissier * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected 342011fa71b9SJerome Forissier * errors, and is the right thing to do in both cases). 342111fa71b9SJerome Forissier */ 3422*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 342311fa71b9SJerome Forissier static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) 342411fa71b9SJerome Forissier { 342511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 342611fa71b9SJerome Forissier size_t len; 342711fa71b9SJerome Forissier 342811fa71b9SJerome Forissier if( ssl->conf->f_cookie_write == NULL || 342911fa71b9SJerome Forissier ssl->conf->f_cookie_check == NULL ) 343011fa71b9SJerome Forissier { 343111fa71b9SJerome Forissier /* If we can't use cookies to verify reachability of the peer, 343211fa71b9SJerome Forissier * drop the record. */ 343311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, " 343411fa71b9SJerome Forissier "can't check reconnect validity" ) ); 343511fa71b9SJerome Forissier return( 0 ); 343611fa71b9SJerome Forissier } 343711fa71b9SJerome Forissier 3438*039e02dfSJerome Forissier ret = mbedtls_ssl_check_dtls_clihlo_cookie( 3439*039e02dfSJerome Forissier ssl, 344011fa71b9SJerome Forissier ssl->cli_id, ssl->cli_id_len, 344111fa71b9SJerome Forissier ssl->in_buf, ssl->in_left, 344211fa71b9SJerome Forissier ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); 344311fa71b9SJerome Forissier 3444*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret ); 344511fa71b9SJerome Forissier 344611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) 344711fa71b9SJerome Forissier { 344811fa71b9SJerome Forissier int send_ret; 344911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); 345011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", 345111fa71b9SJerome Forissier ssl->out_buf, len ); 345211fa71b9SJerome Forissier /* Don't check write errors as we can't do anything here. 345311fa71b9SJerome Forissier * If the error is permanent we'll catch it later, 345411fa71b9SJerome Forissier * if it's not, then hopefully it'll work next time. */ 345511fa71b9SJerome Forissier send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); 345611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); 345711fa71b9SJerome Forissier (void) send_ret; 345811fa71b9SJerome Forissier 345911fa71b9SJerome Forissier return( 0 ); 346011fa71b9SJerome Forissier } 346111fa71b9SJerome Forissier 346211fa71b9SJerome Forissier if( ret == 0 ) 346311fa71b9SJerome Forissier { 346411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); 346511fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 ) 346611fa71b9SJerome Forissier { 346711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); 346811fa71b9SJerome Forissier return( ret ); 346911fa71b9SJerome Forissier } 347011fa71b9SJerome Forissier 347111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); 347211fa71b9SJerome Forissier } 347311fa71b9SJerome Forissier 347411fa71b9SJerome Forissier return( ret ); 347511fa71b9SJerome Forissier } 347611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 347711fa71b9SJerome Forissier 3478*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 347911fa71b9SJerome Forissier static int ssl_check_record_type( uint8_t record_type ) 348011fa71b9SJerome Forissier { 348111fa71b9SJerome Forissier if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE && 348211fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_ALERT && 348311fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && 348411fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 348511fa71b9SJerome Forissier { 348611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 348711fa71b9SJerome Forissier } 348811fa71b9SJerome Forissier 348911fa71b9SJerome Forissier return( 0 ); 349011fa71b9SJerome Forissier } 349111fa71b9SJerome Forissier 349211fa71b9SJerome Forissier /* 349311fa71b9SJerome Forissier * ContentType type; 349411fa71b9SJerome Forissier * ProtocolVersion version; 349511fa71b9SJerome Forissier * uint16 epoch; // DTLS only 349611fa71b9SJerome Forissier * uint48 sequence_number; // DTLS only 349711fa71b9SJerome Forissier * uint16 length; 349811fa71b9SJerome Forissier * 349911fa71b9SJerome Forissier * Return 0 if header looks sane (and, for DTLS, the record is expected) 350011fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, 350111fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. 350211fa71b9SJerome Forissier * 350311fa71b9SJerome Forissier * With DTLS, mbedtls_ssl_read_record() will: 350411fa71b9SJerome Forissier * 1. proceed with the record if this function returns 0 350511fa71b9SJerome Forissier * 2. drop only the current record if this function returns UNEXPECTED_RECORD 350611fa71b9SJerome Forissier * 3. return CLIENT_RECONNECT if this function return that value 350711fa71b9SJerome Forissier * 4. drop the whole datagram if this function returns anything else. 350811fa71b9SJerome Forissier * Point 2 is needed when the peer is resending, and we have already received 350911fa71b9SJerome Forissier * the first record from a datagram but are still waiting for the others. 351011fa71b9SJerome Forissier */ 3511*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 351211fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, 351311fa71b9SJerome Forissier unsigned char *buf, 351411fa71b9SJerome Forissier size_t len, 351511fa71b9SJerome Forissier mbedtls_record *rec ) 351611fa71b9SJerome Forissier { 351711fa71b9SJerome Forissier int major_ver, minor_ver; 351811fa71b9SJerome Forissier 351911fa71b9SJerome Forissier size_t const rec_hdr_type_offset = 0; 352011fa71b9SJerome Forissier size_t const rec_hdr_type_len = 1; 352111fa71b9SJerome Forissier 352211fa71b9SJerome Forissier size_t const rec_hdr_version_offset = rec_hdr_type_offset + 352311fa71b9SJerome Forissier rec_hdr_type_len; 352411fa71b9SJerome Forissier size_t const rec_hdr_version_len = 2; 352511fa71b9SJerome Forissier 352611fa71b9SJerome Forissier size_t const rec_hdr_ctr_len = 8; 352711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 352811fa71b9SJerome Forissier uint32_t rec_epoch; 352911fa71b9SJerome Forissier size_t const rec_hdr_ctr_offset = rec_hdr_version_offset + 353011fa71b9SJerome Forissier rec_hdr_version_len; 353111fa71b9SJerome Forissier 353211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 353311fa71b9SJerome Forissier size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + 353411fa71b9SJerome Forissier rec_hdr_ctr_len; 353511fa71b9SJerome Forissier size_t rec_hdr_cid_len = 0; 353611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 353711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 353811fa71b9SJerome Forissier 353911fa71b9SJerome Forissier size_t rec_hdr_len_offset; /* To be determined */ 354011fa71b9SJerome Forissier size_t const rec_hdr_len_len = 2; 354111fa71b9SJerome Forissier 354211fa71b9SJerome Forissier /* 354311fa71b9SJerome Forissier * Check minimum lengths for record header. 354411fa71b9SJerome Forissier */ 354511fa71b9SJerome Forissier 354611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 354711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 354811fa71b9SJerome Forissier { 354911fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len; 355011fa71b9SJerome Forissier } 355111fa71b9SJerome Forissier else 355211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 355311fa71b9SJerome Forissier { 355411fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len; 355511fa71b9SJerome Forissier } 355611fa71b9SJerome Forissier 355711fa71b9SJerome Forissier if( len < rec_hdr_len_offset + rec_hdr_len_len ) 355811fa71b9SJerome Forissier { 355911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u", 356011fa71b9SJerome Forissier (unsigned) len, 356111fa71b9SJerome Forissier (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) ); 356211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 356311fa71b9SJerome Forissier } 356411fa71b9SJerome Forissier 356511fa71b9SJerome Forissier /* 356611fa71b9SJerome Forissier * Parse and validate record content type 356711fa71b9SJerome Forissier */ 356811fa71b9SJerome Forissier 356911fa71b9SJerome Forissier rec->type = buf[ rec_hdr_type_offset ]; 357011fa71b9SJerome Forissier 357111fa71b9SJerome Forissier /* Check record content type */ 357211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 357311fa71b9SJerome Forissier rec->cid_len = 0; 357411fa71b9SJerome Forissier 357511fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 357611fa71b9SJerome Forissier ssl->conf->cid_len != 0 && 357711fa71b9SJerome Forissier rec->type == MBEDTLS_SSL_MSG_CID ) 357811fa71b9SJerome Forissier { 357911fa71b9SJerome Forissier /* Shift pointers to account for record header including CID 358011fa71b9SJerome Forissier * struct { 358111fa71b9SJerome Forissier * ContentType special_type = tls12_cid; 358211fa71b9SJerome Forissier * ProtocolVersion version; 358311fa71b9SJerome Forissier * uint16 epoch; 358411fa71b9SJerome Forissier * uint48 sequence_number; 358511fa71b9SJerome Forissier * opaque cid[cid_length]; // Additional field compared to 358611fa71b9SJerome Forissier * // default DTLS record format 358711fa71b9SJerome Forissier * uint16 length; 358811fa71b9SJerome Forissier * opaque enc_content[DTLSCiphertext.length]; 358911fa71b9SJerome Forissier * } DTLSCiphertext; 359011fa71b9SJerome Forissier */ 359111fa71b9SJerome Forissier 359211fa71b9SJerome Forissier /* So far, we only support static CID lengths 359311fa71b9SJerome Forissier * fixed in the configuration. */ 359411fa71b9SJerome Forissier rec_hdr_cid_len = ssl->conf->cid_len; 359511fa71b9SJerome Forissier rec_hdr_len_offset += rec_hdr_cid_len; 359611fa71b9SJerome Forissier 359711fa71b9SJerome Forissier if( len < rec_hdr_len_offset + rec_hdr_len_len ) 359811fa71b9SJerome Forissier { 359911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u", 360011fa71b9SJerome Forissier (unsigned) len, 360111fa71b9SJerome Forissier (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) ); 360211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 360311fa71b9SJerome Forissier } 360411fa71b9SJerome Forissier 360511fa71b9SJerome Forissier /* configured CID len is guaranteed at most 255, see 360611fa71b9SJerome Forissier * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */ 360711fa71b9SJerome Forissier rec->cid_len = (uint8_t) rec_hdr_cid_len; 360811fa71b9SJerome Forissier memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len ); 360911fa71b9SJerome Forissier } 361011fa71b9SJerome Forissier else 361111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 361211fa71b9SJerome Forissier { 361311fa71b9SJerome Forissier if( ssl_check_record_type( rec->type ) ) 361411fa71b9SJerome Forissier { 361511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u", 361611fa71b9SJerome Forissier (unsigned) rec->type ) ); 361711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 361811fa71b9SJerome Forissier } 361911fa71b9SJerome Forissier } 362011fa71b9SJerome Forissier 362111fa71b9SJerome Forissier /* 362211fa71b9SJerome Forissier * Parse and validate record version 362311fa71b9SJerome Forissier */ 362411fa71b9SJerome Forissier rec->ver[0] = buf[ rec_hdr_version_offset + 0 ]; 362511fa71b9SJerome Forissier rec->ver[1] = buf[ rec_hdr_version_offset + 1 ]; 362611fa71b9SJerome Forissier mbedtls_ssl_read_version( &major_ver, &minor_ver, 362711fa71b9SJerome Forissier ssl->conf->transport, 362811fa71b9SJerome Forissier &rec->ver[0] ); 362911fa71b9SJerome Forissier 363011fa71b9SJerome Forissier if( major_ver != ssl->major_ver ) 363111fa71b9SJerome Forissier { 3632*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch: got %u, expected %u", 3633*039e02dfSJerome Forissier (unsigned) major_ver, 3634*039e02dfSJerome Forissier (unsigned) ssl->major_ver ) ); 363511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 363611fa71b9SJerome Forissier } 363711fa71b9SJerome Forissier 363811fa71b9SJerome Forissier if( minor_ver > ssl->conf->max_minor_ver ) 363911fa71b9SJerome Forissier { 3640*039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch: got %u, expected max %u", 3641*039e02dfSJerome Forissier (unsigned) minor_ver, 3642*039e02dfSJerome Forissier (unsigned) ssl->conf->max_minor_ver ) ); 364311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 364411fa71b9SJerome Forissier } 364511fa71b9SJerome Forissier /* 364611fa71b9SJerome Forissier * Parse/Copy record sequence number. 364711fa71b9SJerome Forissier */ 364811fa71b9SJerome Forissier 364911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 365011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 365111fa71b9SJerome Forissier { 365211fa71b9SJerome Forissier /* Copy explicit record sequence number from input buffer. */ 365311fa71b9SJerome Forissier memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset, 365411fa71b9SJerome Forissier rec_hdr_ctr_len ); 365511fa71b9SJerome Forissier } 365611fa71b9SJerome Forissier else 365711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 365811fa71b9SJerome Forissier { 365911fa71b9SJerome Forissier /* Copy implicit record sequence number from SSL context structure. */ 366011fa71b9SJerome Forissier memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len ); 366111fa71b9SJerome Forissier } 366211fa71b9SJerome Forissier 366311fa71b9SJerome Forissier /* 366411fa71b9SJerome Forissier * Parse record length. 366511fa71b9SJerome Forissier */ 366611fa71b9SJerome Forissier 366711fa71b9SJerome Forissier rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len; 366811fa71b9SJerome Forissier rec->data_len = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) | 366911fa71b9SJerome Forissier ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 ); 367011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset ); 367111fa71b9SJerome Forissier 36727901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %u, " 36737901324dSJerome Forissier "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET, 367411fa71b9SJerome Forissier rec->type, 367511fa71b9SJerome Forissier major_ver, minor_ver, rec->data_len ) ); 367611fa71b9SJerome Forissier 367711fa71b9SJerome Forissier rec->buf = buf; 367811fa71b9SJerome Forissier rec->buf_len = rec->data_offset + rec->data_len; 367911fa71b9SJerome Forissier 368011fa71b9SJerome Forissier if( rec->data_len == 0 ) 368111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 368211fa71b9SJerome Forissier 368311fa71b9SJerome Forissier /* 368411fa71b9SJerome Forissier * DTLS-related tests. 368511fa71b9SJerome Forissier * Check epoch before checking length constraint because 368611fa71b9SJerome Forissier * the latter varies with the epoch. E.g., if a ChangeCipherSpec 368711fa71b9SJerome Forissier * message gets duplicated before the corresponding Finished message, 368811fa71b9SJerome Forissier * the second ChangeCipherSpec should be discarded because it belongs 368911fa71b9SJerome Forissier * to an old epoch, but not because its length is shorter than 369011fa71b9SJerome Forissier * the minimum record length for packets using the new record transform. 369111fa71b9SJerome Forissier * Note that these two kinds of failures are handled differently, 369211fa71b9SJerome Forissier * as an unexpected record is silently skipped but an invalid 369311fa71b9SJerome Forissier * record leads to the entire datagram being dropped. 369411fa71b9SJerome Forissier */ 369511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 369611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 369711fa71b9SJerome Forissier { 369811fa71b9SJerome Forissier rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1]; 369911fa71b9SJerome Forissier 370011fa71b9SJerome Forissier /* Check that the datagram is large enough to contain a record 370111fa71b9SJerome Forissier * of the advertised length. */ 370211fa71b9SJerome Forissier if( len < rec->data_offset + rec->data_len ) 370311fa71b9SJerome Forissier { 370411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.", 370511fa71b9SJerome Forissier (unsigned) len, 370611fa71b9SJerome Forissier (unsigned)( rec->data_offset + rec->data_len ) ) ); 370711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 370811fa71b9SJerome Forissier } 370911fa71b9SJerome Forissier 371011fa71b9SJerome Forissier /* Records from other, non-matching epochs are silently discarded. 371111fa71b9SJerome Forissier * (The case of same-port Client reconnects must be considered in 371211fa71b9SJerome Forissier * the caller). */ 371311fa71b9SJerome Forissier if( rec_epoch != ssl->in_epoch ) 371411fa71b9SJerome Forissier { 371511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " 37167901324dSJerome Forissier "expected %u, received %lu", 37177901324dSJerome Forissier ssl->in_epoch, (unsigned long) rec_epoch ) ); 371811fa71b9SJerome Forissier 371911fa71b9SJerome Forissier /* Records from the next epoch are considered for buffering 372011fa71b9SJerome Forissier * (concretely: early Finished messages). */ 372111fa71b9SJerome Forissier if( rec_epoch == (unsigned) ssl->in_epoch + 1 ) 372211fa71b9SJerome Forissier { 372311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); 372411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 372511fa71b9SJerome Forissier } 372611fa71b9SJerome Forissier 372711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 372811fa71b9SJerome Forissier } 372911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 373011fa71b9SJerome Forissier /* For records from the correct epoch, check whether their 373111fa71b9SJerome Forissier * sequence number has been seen before. */ 373211fa71b9SJerome Forissier else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl, 373311fa71b9SJerome Forissier &rec->ctr[0] ) != 0 ) 373411fa71b9SJerome Forissier { 373511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); 373611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 373711fa71b9SJerome Forissier } 373811fa71b9SJerome Forissier #endif 373911fa71b9SJerome Forissier } 374011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 374111fa71b9SJerome Forissier 374211fa71b9SJerome Forissier return( 0 ); 374311fa71b9SJerome Forissier } 374411fa71b9SJerome Forissier 374511fa71b9SJerome Forissier 374611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 3747*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 374811fa71b9SJerome Forissier static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl ) 374911fa71b9SJerome Forissier { 375011fa71b9SJerome Forissier unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; 375111fa71b9SJerome Forissier 375211fa71b9SJerome Forissier /* 375311fa71b9SJerome Forissier * Check for an epoch 0 ClientHello. We can't use in_msg here to 375411fa71b9SJerome Forissier * access the first byte of record content (handshake type), as we 375511fa71b9SJerome Forissier * have an active transform (possibly iv_len != 0), so use the 375611fa71b9SJerome Forissier * fact that the record header len is 13 instead. 375711fa71b9SJerome Forissier */ 375811fa71b9SJerome Forissier if( rec_epoch == 0 && 375911fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 376011fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && 376111fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 376211fa71b9SJerome Forissier ssl->in_left > 13 && 376311fa71b9SJerome Forissier ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) 376411fa71b9SJerome Forissier { 376511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " 376611fa71b9SJerome Forissier "from the same port" ) ); 376711fa71b9SJerome Forissier return( ssl_handle_possible_reconnect( ssl ) ); 376811fa71b9SJerome Forissier } 376911fa71b9SJerome Forissier 377011fa71b9SJerome Forissier return( 0 ); 377111fa71b9SJerome Forissier } 377211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 377311fa71b9SJerome Forissier 377411fa71b9SJerome Forissier /* 377511fa71b9SJerome Forissier * If applicable, decrypt record content 377611fa71b9SJerome Forissier */ 3777*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 377811fa71b9SJerome Forissier static int ssl_prepare_record_content( mbedtls_ssl_context *ssl, 377911fa71b9SJerome Forissier mbedtls_record *rec ) 378011fa71b9SJerome Forissier { 378111fa71b9SJerome Forissier int ret, done = 0; 378211fa71b9SJerome Forissier 378311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", 378411fa71b9SJerome Forissier rec->buf, rec->buf_len ); 378511fa71b9SJerome Forissier 378611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 378711fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_read != NULL ) 378811fa71b9SJerome Forissier { 378911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); 379011fa71b9SJerome Forissier 379111fa71b9SJerome Forissier ret = mbedtls_ssl_hw_record_read( ssl ); 379211fa71b9SJerome Forissier if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) 379311fa71b9SJerome Forissier { 379411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); 379511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 379611fa71b9SJerome Forissier } 379711fa71b9SJerome Forissier 379811fa71b9SJerome Forissier if( ret == 0 ) 379911fa71b9SJerome Forissier done = 1; 380011fa71b9SJerome Forissier } 380111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 380211fa71b9SJerome Forissier if( !done && ssl->transform_in != NULL ) 380311fa71b9SJerome Forissier { 380411fa71b9SJerome Forissier unsigned char const old_msg_type = rec->type; 380511fa71b9SJerome Forissier 380611fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, 380711fa71b9SJerome Forissier rec ) ) != 0 ) 380811fa71b9SJerome Forissier { 380911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); 381011fa71b9SJerome Forissier 381111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 381211fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && 381311fa71b9SJerome Forissier ssl->conf->ignore_unexpected_cid 381411fa71b9SJerome Forissier == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) 381511fa71b9SJerome Forissier { 381611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) ); 381711fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 381811fa71b9SJerome Forissier } 381911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 382011fa71b9SJerome Forissier 382111fa71b9SJerome Forissier return( ret ); 382211fa71b9SJerome Forissier } 382311fa71b9SJerome Forissier 382411fa71b9SJerome Forissier if( old_msg_type != rec->type ) 382511fa71b9SJerome Forissier { 382611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d", 382711fa71b9SJerome Forissier old_msg_type, rec->type ) ); 382811fa71b9SJerome Forissier } 382911fa71b9SJerome Forissier 383011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", 383111fa71b9SJerome Forissier rec->buf + rec->data_offset, rec->data_len ); 383211fa71b9SJerome Forissier 383311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 383411fa71b9SJerome Forissier /* We have already checked the record content type 383511fa71b9SJerome Forissier * in ssl_parse_record_header(), failing or silently 383611fa71b9SJerome Forissier * dropping the record in the case of an unknown type. 383711fa71b9SJerome Forissier * 383811fa71b9SJerome Forissier * Since with the use of CIDs, the record content type 383911fa71b9SJerome Forissier * might change during decryption, re-check the record 384011fa71b9SJerome Forissier * content type, but treat a failure as fatal this time. */ 384111fa71b9SJerome Forissier if( ssl_check_record_type( rec->type ) ) 384211fa71b9SJerome Forissier { 384311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); 384411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 384511fa71b9SJerome Forissier } 384611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 384711fa71b9SJerome Forissier 384811fa71b9SJerome Forissier if( rec->data_len == 0 ) 384911fa71b9SJerome Forissier { 385011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 385111fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 385211fa71b9SJerome Forissier && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 385311fa71b9SJerome Forissier { 385411fa71b9SJerome Forissier /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ 385511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); 385611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 385711fa71b9SJerome Forissier } 385811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 385911fa71b9SJerome Forissier 386011fa71b9SJerome Forissier ssl->nb_zero++; 386111fa71b9SJerome Forissier 386211fa71b9SJerome Forissier /* 386311fa71b9SJerome Forissier * Three or more empty messages may be a DoS attack 386411fa71b9SJerome Forissier * (excessive CPU consumption). 386511fa71b9SJerome Forissier */ 386611fa71b9SJerome Forissier if( ssl->nb_zero > 3 ) 386711fa71b9SJerome Forissier { 386811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " 386911fa71b9SJerome Forissier "messages, possible DoS attack" ) ); 387011fa71b9SJerome Forissier /* Treat the records as if they were not properly authenticated, 387111fa71b9SJerome Forissier * thereby failing the connection if we see more than allowed 387211fa71b9SJerome Forissier * by the configured bad MAC threshold. */ 387311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 387411fa71b9SJerome Forissier } 387511fa71b9SJerome Forissier } 387611fa71b9SJerome Forissier else 387711fa71b9SJerome Forissier ssl->nb_zero = 0; 387811fa71b9SJerome Forissier 387911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 388011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 388111fa71b9SJerome Forissier { 388211fa71b9SJerome Forissier ; /* in_ctr read from peer, not maintained internally */ 388311fa71b9SJerome Forissier } 388411fa71b9SJerome Forissier else 388511fa71b9SJerome Forissier #endif 388611fa71b9SJerome Forissier { 388711fa71b9SJerome Forissier unsigned i; 388811fa71b9SJerome Forissier for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- ) 388911fa71b9SJerome Forissier if( ++ssl->in_ctr[i - 1] != 0 ) 389011fa71b9SJerome Forissier break; 389111fa71b9SJerome Forissier 389211fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */ 389311fa71b9SJerome Forissier if( i == mbedtls_ssl_ep_len( ssl ) ) 389411fa71b9SJerome Forissier { 389511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); 389611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 389711fa71b9SJerome Forissier } 389811fa71b9SJerome Forissier } 389911fa71b9SJerome Forissier 390011fa71b9SJerome Forissier } 390111fa71b9SJerome Forissier 390211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 390311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 390411fa71b9SJerome Forissier { 390511fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_update( ssl ); 390611fa71b9SJerome Forissier } 390711fa71b9SJerome Forissier #endif 390811fa71b9SJerome Forissier 390911fa71b9SJerome Forissier /* Check actual (decrypted) record content length against 391011fa71b9SJerome Forissier * configured maximum. */ 3911*039e02dfSJerome Forissier if( rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN ) 391211fa71b9SJerome Forissier { 391311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); 391411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 391511fa71b9SJerome Forissier } 391611fa71b9SJerome Forissier 391711fa71b9SJerome Forissier return( 0 ); 391811fa71b9SJerome Forissier } 391911fa71b9SJerome Forissier 392011fa71b9SJerome Forissier /* 392111fa71b9SJerome Forissier * Read a record. 392211fa71b9SJerome Forissier * 392311fa71b9SJerome Forissier * Silently ignore non-fatal alert (and for DTLS, invalid records as well, 392411fa71b9SJerome Forissier * RFC 6347 4.1.2.7) and continue reading until a valid record is found. 392511fa71b9SJerome Forissier * 392611fa71b9SJerome Forissier */ 392711fa71b9SJerome Forissier 392811fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */ 3929*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 393011fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); 3931*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 393211fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl ); 3933*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 393411fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); 393511fa71b9SJerome Forissier 393611fa71b9SJerome Forissier int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, 393711fa71b9SJerome Forissier unsigned update_hs_digest ) 393811fa71b9SJerome Forissier { 393911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 394011fa71b9SJerome Forissier 394111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); 394211fa71b9SJerome Forissier 394311fa71b9SJerome Forissier if( ssl->keep_current_message == 0 ) 394411fa71b9SJerome Forissier { 394511fa71b9SJerome Forissier do { 394611fa71b9SJerome Forissier 394711fa71b9SJerome Forissier ret = ssl_consume_current_message( ssl ); 394811fa71b9SJerome Forissier if( ret != 0 ) 394911fa71b9SJerome Forissier return( ret ); 395011fa71b9SJerome Forissier 395111fa71b9SJerome Forissier if( ssl_record_is_in_progress( ssl ) == 0 ) 395211fa71b9SJerome Forissier { 395311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 395411fa71b9SJerome Forissier int have_buffered = 0; 395511fa71b9SJerome Forissier 395611fa71b9SJerome Forissier /* We only check for buffered messages if the 395711fa71b9SJerome Forissier * current datagram is fully consumed. */ 395811fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 395911fa71b9SJerome Forissier ssl_next_record_is_in_datagram( ssl ) == 0 ) 396011fa71b9SJerome Forissier { 396111fa71b9SJerome Forissier if( ssl_load_buffered_message( ssl ) == 0 ) 396211fa71b9SJerome Forissier have_buffered = 1; 396311fa71b9SJerome Forissier } 396411fa71b9SJerome Forissier 396511fa71b9SJerome Forissier if( have_buffered == 0 ) 396611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 396711fa71b9SJerome Forissier { 396811fa71b9SJerome Forissier ret = ssl_get_next_record( ssl ); 396911fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) 397011fa71b9SJerome Forissier continue; 397111fa71b9SJerome Forissier 397211fa71b9SJerome Forissier if( ret != 0 ) 397311fa71b9SJerome Forissier { 397411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); 397511fa71b9SJerome Forissier return( ret ); 397611fa71b9SJerome Forissier } 397711fa71b9SJerome Forissier } 397811fa71b9SJerome Forissier } 397911fa71b9SJerome Forissier 398011fa71b9SJerome Forissier ret = mbedtls_ssl_handle_message_type( ssl ); 398111fa71b9SJerome Forissier 398211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 398311fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 398411fa71b9SJerome Forissier { 398511fa71b9SJerome Forissier /* Buffer future message */ 398611fa71b9SJerome Forissier ret = ssl_buffer_message( ssl ); 398711fa71b9SJerome Forissier if( ret != 0 ) 398811fa71b9SJerome Forissier return( ret ); 398911fa71b9SJerome Forissier 399011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 399111fa71b9SJerome Forissier } 399211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 399311fa71b9SJerome Forissier 399411fa71b9SJerome Forissier } while( MBEDTLS_ERR_SSL_NON_FATAL == ret || 399511fa71b9SJerome Forissier MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); 399611fa71b9SJerome Forissier 399711fa71b9SJerome Forissier if( 0 != ret ) 399811fa71b9SJerome Forissier { 399911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); 400011fa71b9SJerome Forissier return( ret ); 400111fa71b9SJerome Forissier } 400211fa71b9SJerome Forissier 400311fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 400411fa71b9SJerome Forissier update_hs_digest == 1 ) 400511fa71b9SJerome Forissier { 400611fa71b9SJerome Forissier mbedtls_ssl_update_handshake_status( ssl ); 400711fa71b9SJerome Forissier } 400811fa71b9SJerome Forissier } 400911fa71b9SJerome Forissier else 401011fa71b9SJerome Forissier { 401111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); 401211fa71b9SJerome Forissier ssl->keep_current_message = 0; 401311fa71b9SJerome Forissier } 401411fa71b9SJerome Forissier 401511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); 401611fa71b9SJerome Forissier 401711fa71b9SJerome Forissier return( 0 ); 401811fa71b9SJerome Forissier } 401911fa71b9SJerome Forissier 402011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 4021*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 402211fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) 402311fa71b9SJerome Forissier { 402411fa71b9SJerome Forissier if( ssl->in_left > ssl->next_record_offset ) 402511fa71b9SJerome Forissier return( 1 ); 402611fa71b9SJerome Forissier 402711fa71b9SJerome Forissier return( 0 ); 402811fa71b9SJerome Forissier } 402911fa71b9SJerome Forissier 4030*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 403111fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) 403211fa71b9SJerome Forissier { 403311fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 403411fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * hs_buf; 403511fa71b9SJerome Forissier int ret = 0; 403611fa71b9SJerome Forissier 403711fa71b9SJerome Forissier if( hs == NULL ) 403811fa71b9SJerome Forissier return( -1 ); 403911fa71b9SJerome Forissier 404011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); 404111fa71b9SJerome Forissier 404211fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || 404311fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) 404411fa71b9SJerome Forissier { 404511fa71b9SJerome Forissier /* Check if we have seen a ChangeCipherSpec before. 404611fa71b9SJerome Forissier * If yes, synthesize a CCS record. */ 404711fa71b9SJerome Forissier if( !hs->buffering.seen_ccs ) 404811fa71b9SJerome Forissier { 404911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); 405011fa71b9SJerome Forissier ret = -1; 405111fa71b9SJerome Forissier goto exit; 405211fa71b9SJerome Forissier } 405311fa71b9SJerome Forissier 405411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); 405511fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 405611fa71b9SJerome Forissier ssl->in_msglen = 1; 405711fa71b9SJerome Forissier ssl->in_msg[0] = 1; 405811fa71b9SJerome Forissier 405911fa71b9SJerome Forissier /* As long as they are equal, the exact value doesn't matter. */ 406011fa71b9SJerome Forissier ssl->in_left = 0; 406111fa71b9SJerome Forissier ssl->next_record_offset = 0; 406211fa71b9SJerome Forissier 406311fa71b9SJerome Forissier hs->buffering.seen_ccs = 0; 406411fa71b9SJerome Forissier goto exit; 406511fa71b9SJerome Forissier } 406611fa71b9SJerome Forissier 406711fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C) 406811fa71b9SJerome Forissier /* Debug only */ 406911fa71b9SJerome Forissier { 407011fa71b9SJerome Forissier unsigned offset; 407111fa71b9SJerome Forissier for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) 407211fa71b9SJerome Forissier { 407311fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[offset]; 407411fa71b9SJerome Forissier if( hs_buf->is_valid == 1 ) 407511fa71b9SJerome Forissier { 407611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", 407711fa71b9SJerome Forissier hs->in_msg_seq + offset, 407811fa71b9SJerome Forissier hs_buf->is_complete ? "fully" : "partially" ) ); 407911fa71b9SJerome Forissier } 408011fa71b9SJerome Forissier } 408111fa71b9SJerome Forissier } 408211fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */ 408311fa71b9SJerome Forissier 408411fa71b9SJerome Forissier /* Check if we have buffered and/or fully reassembled the 408511fa71b9SJerome Forissier * next handshake message. */ 408611fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[0]; 408711fa71b9SJerome Forissier if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) 408811fa71b9SJerome Forissier { 408911fa71b9SJerome Forissier /* Synthesize a record containing the buffered HS message. */ 409011fa71b9SJerome Forissier size_t msg_len = ( hs_buf->data[1] << 16 ) | 409111fa71b9SJerome Forissier ( hs_buf->data[2] << 8 ) | 409211fa71b9SJerome Forissier hs_buf->data[3]; 409311fa71b9SJerome Forissier 409411fa71b9SJerome Forissier /* Double-check that we haven't accidentally buffered 409511fa71b9SJerome Forissier * a message that doesn't fit into the input buffer. */ 409611fa71b9SJerome Forissier if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) 409711fa71b9SJerome Forissier { 409811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 409911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 410011fa71b9SJerome Forissier } 410111fa71b9SJerome Forissier 410211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); 410311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", 410411fa71b9SJerome Forissier hs_buf->data, msg_len + 12 ); 410511fa71b9SJerome Forissier 410611fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 410711fa71b9SJerome Forissier ssl->in_hslen = msg_len + 12; 410811fa71b9SJerome Forissier ssl->in_msglen = msg_len + 12; 410911fa71b9SJerome Forissier memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); 411011fa71b9SJerome Forissier 411111fa71b9SJerome Forissier ret = 0; 411211fa71b9SJerome Forissier goto exit; 411311fa71b9SJerome Forissier } 411411fa71b9SJerome Forissier else 411511fa71b9SJerome Forissier { 411611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", 411711fa71b9SJerome Forissier hs->in_msg_seq ) ); 411811fa71b9SJerome Forissier } 411911fa71b9SJerome Forissier 412011fa71b9SJerome Forissier ret = -1; 412111fa71b9SJerome Forissier 412211fa71b9SJerome Forissier exit: 412311fa71b9SJerome Forissier 412411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); 412511fa71b9SJerome Forissier return( ret ); 412611fa71b9SJerome Forissier } 412711fa71b9SJerome Forissier 4128*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 412911fa71b9SJerome Forissier static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, 413011fa71b9SJerome Forissier size_t desired ) 413111fa71b9SJerome Forissier { 413211fa71b9SJerome Forissier int offset; 413311fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 413411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", 413511fa71b9SJerome Forissier (unsigned) desired ) ); 413611fa71b9SJerome Forissier 413711fa71b9SJerome Forissier /* Get rid of future records epoch first, if such exist. */ 413811fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 413911fa71b9SJerome Forissier 414011fa71b9SJerome Forissier /* Check if we have enough space available now. */ 414111fa71b9SJerome Forissier if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 414211fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 414311fa71b9SJerome Forissier { 414411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); 414511fa71b9SJerome Forissier return( 0 ); 414611fa71b9SJerome Forissier } 414711fa71b9SJerome Forissier 414811fa71b9SJerome Forissier /* We don't have enough space to buffer the next expected handshake 414911fa71b9SJerome Forissier * message. Remove buffers used for future messages to gain space, 415011fa71b9SJerome Forissier * starting with the most distant one. */ 415111fa71b9SJerome Forissier for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; 415211fa71b9SJerome Forissier offset >= 0; offset-- ) 415311fa71b9SJerome Forissier { 415411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", 415511fa71b9SJerome Forissier offset ) ); 415611fa71b9SJerome Forissier 415711fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, (uint8_t) offset ); 415811fa71b9SJerome Forissier 415911fa71b9SJerome Forissier /* Check if we have enough space available now. */ 416011fa71b9SJerome Forissier if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 416111fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 416211fa71b9SJerome Forissier { 416311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); 416411fa71b9SJerome Forissier return( 0 ); 416511fa71b9SJerome Forissier } 416611fa71b9SJerome Forissier } 416711fa71b9SJerome Forissier 416811fa71b9SJerome Forissier return( -1 ); 416911fa71b9SJerome Forissier } 417011fa71b9SJerome Forissier 4171*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 417211fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl ) 417311fa71b9SJerome Forissier { 417411fa71b9SJerome Forissier int ret = 0; 417511fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 417611fa71b9SJerome Forissier 417711fa71b9SJerome Forissier if( hs == NULL ) 417811fa71b9SJerome Forissier return( 0 ); 417911fa71b9SJerome Forissier 418011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); 418111fa71b9SJerome Forissier 418211fa71b9SJerome Forissier switch( ssl->in_msgtype ) 418311fa71b9SJerome Forissier { 418411fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: 418511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); 418611fa71b9SJerome Forissier 418711fa71b9SJerome Forissier hs->buffering.seen_ccs = 1; 418811fa71b9SJerome Forissier break; 418911fa71b9SJerome Forissier 419011fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_HANDSHAKE: 419111fa71b9SJerome Forissier { 419211fa71b9SJerome Forissier unsigned recv_msg_seq_offset; 419311fa71b9SJerome Forissier unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; 419411fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 419511fa71b9SJerome Forissier size_t msg_len = ssl->in_hslen - 12; 419611fa71b9SJerome Forissier 419711fa71b9SJerome Forissier /* We should never receive an old handshake 419811fa71b9SJerome Forissier * message - double-check nonetheless. */ 419911fa71b9SJerome Forissier if( recv_msg_seq < ssl->handshake->in_msg_seq ) 420011fa71b9SJerome Forissier { 420111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 420211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 420311fa71b9SJerome Forissier } 420411fa71b9SJerome Forissier 420511fa71b9SJerome Forissier recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; 420611fa71b9SJerome Forissier if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) 420711fa71b9SJerome Forissier { 420811fa71b9SJerome Forissier /* Silently ignore -- message too far in the future */ 420911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, 421011fa71b9SJerome Forissier ( "Ignore future HS message with sequence number %u, " 421111fa71b9SJerome Forissier "buffering window %u - %u", 421211fa71b9SJerome Forissier recv_msg_seq, ssl->handshake->in_msg_seq, 421311fa71b9SJerome Forissier ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); 421411fa71b9SJerome Forissier 421511fa71b9SJerome Forissier goto exit; 421611fa71b9SJerome Forissier } 421711fa71b9SJerome Forissier 421811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", 421911fa71b9SJerome Forissier recv_msg_seq, recv_msg_seq_offset ) ); 422011fa71b9SJerome Forissier 422111fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; 422211fa71b9SJerome Forissier 422311fa71b9SJerome Forissier /* Check if the buffering for this seq nr has already commenced. */ 422411fa71b9SJerome Forissier if( !hs_buf->is_valid ) 422511fa71b9SJerome Forissier { 422611fa71b9SJerome Forissier size_t reassembly_buf_sz; 422711fa71b9SJerome Forissier 422811fa71b9SJerome Forissier hs_buf->is_fragmented = 422911fa71b9SJerome Forissier ( ssl_hs_is_proper_fragment( ssl ) == 1 ); 423011fa71b9SJerome Forissier 423111fa71b9SJerome Forissier /* We copy the message back into the input buffer 423211fa71b9SJerome Forissier * after reassembly, so check that it's not too large. 423311fa71b9SJerome Forissier * This is an implementation-specific limitation 423411fa71b9SJerome Forissier * and not one from the standard, hence it is not 423511fa71b9SJerome Forissier * checked in ssl_check_hs_header(). */ 423611fa71b9SJerome Forissier if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) 423711fa71b9SJerome Forissier { 423811fa71b9SJerome Forissier /* Ignore message */ 423911fa71b9SJerome Forissier goto exit; 424011fa71b9SJerome Forissier } 424111fa71b9SJerome Forissier 424211fa71b9SJerome Forissier /* Check if we have enough space to buffer the message. */ 424311fa71b9SJerome Forissier if( hs->buffering.total_bytes_buffered > 424411fa71b9SJerome Forissier MBEDTLS_SSL_DTLS_MAX_BUFFERING ) 424511fa71b9SJerome Forissier { 424611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 424711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 424811fa71b9SJerome Forissier } 424911fa71b9SJerome Forissier 425011fa71b9SJerome Forissier reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, 425111fa71b9SJerome Forissier hs_buf->is_fragmented ); 425211fa71b9SJerome Forissier 425311fa71b9SJerome Forissier if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 425411fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 425511fa71b9SJerome Forissier { 425611fa71b9SJerome Forissier if( recv_msg_seq_offset > 0 ) 425711fa71b9SJerome Forissier { 425811fa71b9SJerome Forissier /* If we can't buffer a future message because 425911fa71b9SJerome Forissier * of space limitations -- ignore. */ 42607901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET 42617901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 42627901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 42637901324dSJerome Forissier " bytes buffered) -- ignore\n", 42647901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 42657901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 426611fa71b9SJerome Forissier goto exit; 426711fa71b9SJerome Forissier } 426811fa71b9SJerome Forissier else 426911fa71b9SJerome Forissier { 42707901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET 42717901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 42727901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 42737901324dSJerome Forissier " bytes buffered) -- attempt to make space by freeing buffered future messages\n", 42747901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 42757901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 427611fa71b9SJerome Forissier } 427711fa71b9SJerome Forissier 427811fa71b9SJerome Forissier if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) 427911fa71b9SJerome Forissier { 42807901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET 42817901324dSJerome Forissier " (%" MBEDTLS_PRINTF_SIZET " with bitmap) would exceed" 42827901324dSJerome Forissier " the compile-time limit %" MBEDTLS_PRINTF_SIZET 42837901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 42847901324dSJerome Forissier " bytes buffered) -- fail\n", 42857901324dSJerome Forissier msg_len, 42867901324dSJerome Forissier reassembly_buf_sz, 42877901324dSJerome Forissier (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 42887901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 428911fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 429011fa71b9SJerome Forissier goto exit; 429111fa71b9SJerome Forissier } 429211fa71b9SJerome Forissier } 429311fa71b9SJerome Forissier 42947901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET, 429511fa71b9SJerome Forissier msg_len ) ); 429611fa71b9SJerome Forissier 429711fa71b9SJerome Forissier hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); 429811fa71b9SJerome Forissier if( hs_buf->data == NULL ) 429911fa71b9SJerome Forissier { 430011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 430111fa71b9SJerome Forissier goto exit; 430211fa71b9SJerome Forissier } 430311fa71b9SJerome Forissier hs_buf->data_len = reassembly_buf_sz; 430411fa71b9SJerome Forissier 430511fa71b9SJerome Forissier /* Prepare final header: copy msg_type, length and message_seq, 430611fa71b9SJerome Forissier * then add standardised fragment_offset and fragment_length */ 430711fa71b9SJerome Forissier memcpy( hs_buf->data, ssl->in_msg, 6 ); 430811fa71b9SJerome Forissier memset( hs_buf->data + 6, 0, 3 ); 430911fa71b9SJerome Forissier memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ); 431011fa71b9SJerome Forissier 431111fa71b9SJerome Forissier hs_buf->is_valid = 1; 431211fa71b9SJerome Forissier 431311fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += reassembly_buf_sz; 431411fa71b9SJerome Forissier } 431511fa71b9SJerome Forissier else 431611fa71b9SJerome Forissier { 431711fa71b9SJerome Forissier /* Make sure msg_type and length are consistent */ 431811fa71b9SJerome Forissier if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) 431911fa71b9SJerome Forissier { 432011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); 432111fa71b9SJerome Forissier /* Ignore */ 432211fa71b9SJerome Forissier goto exit; 432311fa71b9SJerome Forissier } 432411fa71b9SJerome Forissier } 432511fa71b9SJerome Forissier 432611fa71b9SJerome Forissier if( !hs_buf->is_complete ) 432711fa71b9SJerome Forissier { 432811fa71b9SJerome Forissier size_t frag_len, frag_off; 432911fa71b9SJerome Forissier unsigned char * const msg = hs_buf->data + 12; 433011fa71b9SJerome Forissier 433111fa71b9SJerome Forissier /* 433211fa71b9SJerome Forissier * Check and copy current fragment 433311fa71b9SJerome Forissier */ 433411fa71b9SJerome Forissier 433511fa71b9SJerome Forissier /* Validation of header fields already done in 433611fa71b9SJerome Forissier * mbedtls_ssl_prepare_handshake_record(). */ 433711fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off( ssl ); 433811fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len( ssl ); 433911fa71b9SJerome Forissier 43407901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %" MBEDTLS_PRINTF_SIZET 43417901324dSJerome Forissier ", length = %" MBEDTLS_PRINTF_SIZET, 434211fa71b9SJerome Forissier frag_off, frag_len ) ); 434311fa71b9SJerome Forissier memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); 434411fa71b9SJerome Forissier 434511fa71b9SJerome Forissier if( hs_buf->is_fragmented ) 434611fa71b9SJerome Forissier { 434711fa71b9SJerome Forissier unsigned char * const bitmask = msg + msg_len; 434811fa71b9SJerome Forissier ssl_bitmask_set( bitmask, frag_off, frag_len ); 434911fa71b9SJerome Forissier hs_buf->is_complete = ( ssl_bitmask_check( bitmask, 435011fa71b9SJerome Forissier msg_len ) == 0 ); 435111fa71b9SJerome Forissier } 435211fa71b9SJerome Forissier else 435311fa71b9SJerome Forissier { 435411fa71b9SJerome Forissier hs_buf->is_complete = 1; 435511fa71b9SJerome Forissier } 435611fa71b9SJerome Forissier 435711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", 435811fa71b9SJerome Forissier hs_buf->is_complete ? "" : "not yet " ) ); 435911fa71b9SJerome Forissier } 436011fa71b9SJerome Forissier 436111fa71b9SJerome Forissier break; 436211fa71b9SJerome Forissier } 436311fa71b9SJerome Forissier 436411fa71b9SJerome Forissier default: 436511fa71b9SJerome Forissier /* We don't buffer other types of messages. */ 436611fa71b9SJerome Forissier break; 436711fa71b9SJerome Forissier } 436811fa71b9SJerome Forissier 436911fa71b9SJerome Forissier exit: 437011fa71b9SJerome Forissier 437111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); 437211fa71b9SJerome Forissier return( ret ); 437311fa71b9SJerome Forissier } 437411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 437511fa71b9SJerome Forissier 4376*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 437711fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) 437811fa71b9SJerome Forissier { 437911fa71b9SJerome Forissier /* 438011fa71b9SJerome Forissier * Consume last content-layer message and potentially 438111fa71b9SJerome Forissier * update in_msglen which keeps track of the contents' 438211fa71b9SJerome Forissier * consumption state. 438311fa71b9SJerome Forissier * 438411fa71b9SJerome Forissier * (1) Handshake messages: 438511fa71b9SJerome Forissier * Remove last handshake message, move content 438611fa71b9SJerome Forissier * and adapt in_msglen. 438711fa71b9SJerome Forissier * 438811fa71b9SJerome Forissier * (2) Alert messages: 438911fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 439011fa71b9SJerome Forissier * 439111fa71b9SJerome Forissier * (3) Change cipher spec: 439211fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 439311fa71b9SJerome Forissier * 439411fa71b9SJerome Forissier * (4) Application data: 439511fa71b9SJerome Forissier * Don't do anything - the record layer provides 439611fa71b9SJerome Forissier * the application data as a stream transport 439711fa71b9SJerome Forissier * and consumes through mbedtls_ssl_read only. 439811fa71b9SJerome Forissier * 439911fa71b9SJerome Forissier */ 440011fa71b9SJerome Forissier 440111fa71b9SJerome Forissier /* Case (1): Handshake messages */ 440211fa71b9SJerome Forissier if( ssl->in_hslen != 0 ) 440311fa71b9SJerome Forissier { 440411fa71b9SJerome Forissier /* Hard assertion to be sure that no application data 440511fa71b9SJerome Forissier * is in flight, as corrupting ssl->in_msglen during 440611fa71b9SJerome Forissier * ssl->in_offt != NULL is fatal. */ 440711fa71b9SJerome Forissier if( ssl->in_offt != NULL ) 440811fa71b9SJerome Forissier { 440911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 441011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 441111fa71b9SJerome Forissier } 441211fa71b9SJerome Forissier 441311fa71b9SJerome Forissier /* 441411fa71b9SJerome Forissier * Get next Handshake message in the current record 441511fa71b9SJerome Forissier */ 441611fa71b9SJerome Forissier 441711fa71b9SJerome Forissier /* Notes: 441811fa71b9SJerome Forissier * (1) in_hslen is not necessarily the size of the 441911fa71b9SJerome Forissier * current handshake content: If DTLS handshake 442011fa71b9SJerome Forissier * fragmentation is used, that's the fragment 442111fa71b9SJerome Forissier * size instead. Using the total handshake message 442211fa71b9SJerome Forissier * size here is faulty and should be changed at 442311fa71b9SJerome Forissier * some point. 442411fa71b9SJerome Forissier * (2) While it doesn't seem to cause problems, one 442511fa71b9SJerome Forissier * has to be very careful not to assume that in_hslen 442611fa71b9SJerome Forissier * is always <= in_msglen in a sensible communication. 442711fa71b9SJerome Forissier * Again, it's wrong for DTLS handshake fragmentation. 442811fa71b9SJerome Forissier * The following check is therefore mandatory, and 442911fa71b9SJerome Forissier * should not be treated as a silently corrected assertion. 443011fa71b9SJerome Forissier * Additionally, ssl->in_hslen might be arbitrarily out of 443111fa71b9SJerome Forissier * bounds after handling a DTLS message with an unexpected 443211fa71b9SJerome Forissier * sequence number, see mbedtls_ssl_prepare_handshake_record. 443311fa71b9SJerome Forissier */ 443411fa71b9SJerome Forissier if( ssl->in_hslen < ssl->in_msglen ) 443511fa71b9SJerome Forissier { 443611fa71b9SJerome Forissier ssl->in_msglen -= ssl->in_hslen; 443711fa71b9SJerome Forissier memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, 443811fa71b9SJerome Forissier ssl->in_msglen ); 443911fa71b9SJerome Forissier 444011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", 444111fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 444211fa71b9SJerome Forissier } 444311fa71b9SJerome Forissier else 444411fa71b9SJerome Forissier { 444511fa71b9SJerome Forissier ssl->in_msglen = 0; 444611fa71b9SJerome Forissier } 444711fa71b9SJerome Forissier 444811fa71b9SJerome Forissier ssl->in_hslen = 0; 444911fa71b9SJerome Forissier } 445011fa71b9SJerome Forissier /* Case (4): Application data */ 445111fa71b9SJerome Forissier else if( ssl->in_offt != NULL ) 445211fa71b9SJerome Forissier { 445311fa71b9SJerome Forissier return( 0 ); 445411fa71b9SJerome Forissier } 445511fa71b9SJerome Forissier /* Everything else (CCS & Alerts) */ 445611fa71b9SJerome Forissier else 445711fa71b9SJerome Forissier { 445811fa71b9SJerome Forissier ssl->in_msglen = 0; 445911fa71b9SJerome Forissier } 446011fa71b9SJerome Forissier 446111fa71b9SJerome Forissier return( 0 ); 446211fa71b9SJerome Forissier } 446311fa71b9SJerome Forissier 4464*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 446511fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) 446611fa71b9SJerome Forissier { 446711fa71b9SJerome Forissier if( ssl->in_msglen > 0 ) 446811fa71b9SJerome Forissier return( 1 ); 446911fa71b9SJerome Forissier 447011fa71b9SJerome Forissier return( 0 ); 447111fa71b9SJerome Forissier } 447211fa71b9SJerome Forissier 447311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 447411fa71b9SJerome Forissier 447511fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) 447611fa71b9SJerome Forissier { 447711fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 447811fa71b9SJerome Forissier if( hs == NULL ) 447911fa71b9SJerome Forissier return; 448011fa71b9SJerome Forissier 448111fa71b9SJerome Forissier if( hs->buffering.future_record.data != NULL ) 448211fa71b9SJerome Forissier { 448311fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= 448411fa71b9SJerome Forissier hs->buffering.future_record.len; 448511fa71b9SJerome Forissier 448611fa71b9SJerome Forissier mbedtls_free( hs->buffering.future_record.data ); 448711fa71b9SJerome Forissier hs->buffering.future_record.data = NULL; 448811fa71b9SJerome Forissier } 448911fa71b9SJerome Forissier } 449011fa71b9SJerome Forissier 4491*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 449211fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) 449311fa71b9SJerome Forissier { 449411fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 449511fa71b9SJerome Forissier unsigned char * rec; 449611fa71b9SJerome Forissier size_t rec_len; 449711fa71b9SJerome Forissier unsigned rec_epoch; 449811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 449911fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 450011fa71b9SJerome Forissier #else 450111fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 450211fa71b9SJerome Forissier #endif 450311fa71b9SJerome Forissier if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 450411fa71b9SJerome Forissier return( 0 ); 450511fa71b9SJerome Forissier 450611fa71b9SJerome Forissier if( hs == NULL ) 450711fa71b9SJerome Forissier return( 0 ); 450811fa71b9SJerome Forissier 450911fa71b9SJerome Forissier rec = hs->buffering.future_record.data; 451011fa71b9SJerome Forissier rec_len = hs->buffering.future_record.len; 451111fa71b9SJerome Forissier rec_epoch = hs->buffering.future_record.epoch; 451211fa71b9SJerome Forissier 451311fa71b9SJerome Forissier if( rec == NULL ) 451411fa71b9SJerome Forissier return( 0 ); 451511fa71b9SJerome Forissier 451611fa71b9SJerome Forissier /* Only consider loading future records if the 451711fa71b9SJerome Forissier * input buffer is empty. */ 451811fa71b9SJerome Forissier if( ssl_next_record_is_in_datagram( ssl ) == 1 ) 451911fa71b9SJerome Forissier return( 0 ); 452011fa71b9SJerome Forissier 452111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); 452211fa71b9SJerome Forissier 452311fa71b9SJerome Forissier if( rec_epoch != ssl->in_epoch ) 452411fa71b9SJerome Forissier { 452511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); 452611fa71b9SJerome Forissier goto exit; 452711fa71b9SJerome Forissier } 452811fa71b9SJerome Forissier 452911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); 453011fa71b9SJerome Forissier 453111fa71b9SJerome Forissier /* Double-check that the record is not too large */ 453211fa71b9SJerome Forissier if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) 453311fa71b9SJerome Forissier { 453411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 453511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 453611fa71b9SJerome Forissier } 453711fa71b9SJerome Forissier 453811fa71b9SJerome Forissier memcpy( ssl->in_hdr, rec, rec_len ); 453911fa71b9SJerome Forissier ssl->in_left = rec_len; 454011fa71b9SJerome Forissier ssl->next_record_offset = 0; 454111fa71b9SJerome Forissier 454211fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 454311fa71b9SJerome Forissier 454411fa71b9SJerome Forissier exit: 454511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); 454611fa71b9SJerome Forissier return( 0 ); 454711fa71b9SJerome Forissier } 454811fa71b9SJerome Forissier 4549*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 455011fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, 455111fa71b9SJerome Forissier mbedtls_record const *rec ) 455211fa71b9SJerome Forissier { 455311fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 455411fa71b9SJerome Forissier 455511fa71b9SJerome Forissier /* Don't buffer future records outside handshakes. */ 455611fa71b9SJerome Forissier if( hs == NULL ) 455711fa71b9SJerome Forissier return( 0 ); 455811fa71b9SJerome Forissier 455911fa71b9SJerome Forissier /* Only buffer handshake records (we are only interested 456011fa71b9SJerome Forissier * in Finished messages). */ 456111fa71b9SJerome Forissier if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE ) 456211fa71b9SJerome Forissier return( 0 ); 456311fa71b9SJerome Forissier 456411fa71b9SJerome Forissier /* Don't buffer more than one future epoch record. */ 456511fa71b9SJerome Forissier if( hs->buffering.future_record.data != NULL ) 456611fa71b9SJerome Forissier return( 0 ); 456711fa71b9SJerome Forissier 456811fa71b9SJerome Forissier /* Don't buffer record if there's not enough buffering space remaining. */ 456911fa71b9SJerome Forissier if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 457011fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 457111fa71b9SJerome Forissier { 45727901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET 45737901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 45747901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 45757901324dSJerome Forissier " bytes buffered) -- ignore\n", 45767901324dSJerome Forissier rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 45777901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 457811fa71b9SJerome Forissier return( 0 ); 457911fa71b9SJerome Forissier } 458011fa71b9SJerome Forissier 458111fa71b9SJerome Forissier /* Buffer record */ 458211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", 45837901324dSJerome Forissier ssl->in_epoch + 1U ) ); 458411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len ); 458511fa71b9SJerome Forissier 458611fa71b9SJerome Forissier /* ssl_parse_record_header() only considers records 458711fa71b9SJerome Forissier * of the next epoch as candidates for buffering. */ 458811fa71b9SJerome Forissier hs->buffering.future_record.epoch = ssl->in_epoch + 1; 458911fa71b9SJerome Forissier hs->buffering.future_record.len = rec->buf_len; 459011fa71b9SJerome Forissier 459111fa71b9SJerome Forissier hs->buffering.future_record.data = 459211fa71b9SJerome Forissier mbedtls_calloc( 1, hs->buffering.future_record.len ); 459311fa71b9SJerome Forissier if( hs->buffering.future_record.data == NULL ) 459411fa71b9SJerome Forissier { 459511fa71b9SJerome Forissier /* If we run out of RAM trying to buffer a 459611fa71b9SJerome Forissier * record from the next epoch, just ignore. */ 459711fa71b9SJerome Forissier return( 0 ); 459811fa71b9SJerome Forissier } 459911fa71b9SJerome Forissier 460011fa71b9SJerome Forissier memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len ); 460111fa71b9SJerome Forissier 460211fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += rec->buf_len; 460311fa71b9SJerome Forissier return( 0 ); 460411fa71b9SJerome Forissier } 460511fa71b9SJerome Forissier 460611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 460711fa71b9SJerome Forissier 4608*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 460911fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl ) 461011fa71b9SJerome Forissier { 461111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 461211fa71b9SJerome Forissier mbedtls_record rec; 461311fa71b9SJerome Forissier 461411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 461511fa71b9SJerome Forissier /* We might have buffered a future record; if so, 461611fa71b9SJerome Forissier * and if the epoch matches now, load it. 461711fa71b9SJerome Forissier * On success, this call will set ssl->in_left to 461811fa71b9SJerome Forissier * the length of the buffered record, so that 461911fa71b9SJerome Forissier * the calls to ssl_fetch_input() below will 462011fa71b9SJerome Forissier * essentially be no-ops. */ 462111fa71b9SJerome Forissier ret = ssl_load_buffered_record( ssl ); 462211fa71b9SJerome Forissier if( ret != 0 ) 462311fa71b9SJerome Forissier return( ret ); 462411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 462511fa71b9SJerome Forissier 462611fa71b9SJerome Forissier /* Ensure that we have enough space available for the default form 462711fa71b9SJerome Forissier * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, 462811fa71b9SJerome Forissier * with no space for CIDs counted in). */ 462911fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) ); 463011fa71b9SJerome Forissier if( ret != 0 ) 463111fa71b9SJerome Forissier { 463211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); 463311fa71b9SJerome Forissier return( ret ); 463411fa71b9SJerome Forissier } 463511fa71b9SJerome Forissier 463611fa71b9SJerome Forissier ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec ); 463711fa71b9SJerome Forissier if( ret != 0 ) 463811fa71b9SJerome Forissier { 463911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 464011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 464111fa71b9SJerome Forissier { 464211fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 464311fa71b9SJerome Forissier { 464411fa71b9SJerome Forissier ret = ssl_buffer_future_record( ssl, &rec ); 464511fa71b9SJerome Forissier if( ret != 0 ) 464611fa71b9SJerome Forissier return( ret ); 464711fa71b9SJerome Forissier 464811fa71b9SJerome Forissier /* Fall through to handling of unexpected records */ 464911fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 465011fa71b9SJerome Forissier } 465111fa71b9SJerome Forissier 465211fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) 465311fa71b9SJerome Forissier { 465411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 465511fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 465611fa71b9SJerome Forissier * assuming no CID and no offset between record content and 465711fa71b9SJerome Forissier * record plaintext. */ 465811fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 465911fa71b9SJerome Forissier 466011fa71b9SJerome Forissier /* Setup internal message pointers from record structure. */ 466111fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 466211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 466311fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 466411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 466511fa71b9SJerome Forissier ssl->in_iv = ssl->in_msg = ssl->in_len + 2; 466611fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 466711fa71b9SJerome Forissier 466811fa71b9SJerome Forissier ret = ssl_check_client_reconnect( ssl ); 466911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret ); 467011fa71b9SJerome Forissier if( ret != 0 ) 467111fa71b9SJerome Forissier return( ret ); 467211fa71b9SJerome Forissier #endif 467311fa71b9SJerome Forissier 467411fa71b9SJerome Forissier /* Skip unexpected record (but not whole datagram) */ 467511fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 467611fa71b9SJerome Forissier 467711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " 467811fa71b9SJerome Forissier "(header)" ) ); 467911fa71b9SJerome Forissier } 468011fa71b9SJerome Forissier else 468111fa71b9SJerome Forissier { 468211fa71b9SJerome Forissier /* Skip invalid record and the rest of the datagram */ 468311fa71b9SJerome Forissier ssl->next_record_offset = 0; 468411fa71b9SJerome Forissier ssl->in_left = 0; 468511fa71b9SJerome Forissier 468611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " 468711fa71b9SJerome Forissier "(header)" ) ); 468811fa71b9SJerome Forissier } 468911fa71b9SJerome Forissier 469011fa71b9SJerome Forissier /* Get next record */ 469111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 469211fa71b9SJerome Forissier } 469311fa71b9SJerome Forissier else 469411fa71b9SJerome Forissier #endif 469511fa71b9SJerome Forissier { 469611fa71b9SJerome Forissier return( ret ); 469711fa71b9SJerome Forissier } 469811fa71b9SJerome Forissier } 469911fa71b9SJerome Forissier 470011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 470111fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 470211fa71b9SJerome Forissier { 470311fa71b9SJerome Forissier /* Remember offset of next record within datagram. */ 470411fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 470511fa71b9SJerome Forissier if( ssl->next_record_offset < ssl->in_left ) 470611fa71b9SJerome Forissier { 470711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); 470811fa71b9SJerome Forissier } 470911fa71b9SJerome Forissier } 471011fa71b9SJerome Forissier else 471111fa71b9SJerome Forissier #endif 471211fa71b9SJerome Forissier { 471311fa71b9SJerome Forissier /* 471411fa71b9SJerome Forissier * Fetch record contents from underlying transport. 471511fa71b9SJerome Forissier */ 471611fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len ); 471711fa71b9SJerome Forissier if( ret != 0 ) 471811fa71b9SJerome Forissier { 471911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); 472011fa71b9SJerome Forissier return( ret ); 472111fa71b9SJerome Forissier } 472211fa71b9SJerome Forissier 472311fa71b9SJerome Forissier ssl->in_left = 0; 472411fa71b9SJerome Forissier } 472511fa71b9SJerome Forissier 472611fa71b9SJerome Forissier /* 472711fa71b9SJerome Forissier * Decrypt record contents. 472811fa71b9SJerome Forissier */ 472911fa71b9SJerome Forissier 473011fa71b9SJerome Forissier if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 ) 473111fa71b9SJerome Forissier { 473211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 473311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 473411fa71b9SJerome Forissier { 473511fa71b9SJerome Forissier /* Silently discard invalid records */ 473611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 473711fa71b9SJerome Forissier { 473811fa71b9SJerome Forissier /* Except when waiting for Finished as a bad mac here 473911fa71b9SJerome Forissier * probably means something went wrong in the handshake 474011fa71b9SJerome Forissier * (eg wrong psk used, mitm downgrade attempt, etc.) */ 474111fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || 474211fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) 474311fa71b9SJerome Forissier { 474411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 474511fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 474611fa71b9SJerome Forissier { 474711fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, 474811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 474911fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); 475011fa71b9SJerome Forissier } 475111fa71b9SJerome Forissier #endif 475211fa71b9SJerome Forissier return( ret ); 475311fa71b9SJerome Forissier } 475411fa71b9SJerome Forissier 475511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) 475611fa71b9SJerome Forissier if( ssl->conf->badmac_limit != 0 && 475711fa71b9SJerome Forissier ++ssl->badmac_seen >= ssl->conf->badmac_limit ) 475811fa71b9SJerome Forissier { 475911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); 476011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 476111fa71b9SJerome Forissier } 476211fa71b9SJerome Forissier #endif 476311fa71b9SJerome Forissier 476411fa71b9SJerome Forissier /* As above, invalid records cause 476511fa71b9SJerome Forissier * dismissal of the whole datagram. */ 476611fa71b9SJerome Forissier 476711fa71b9SJerome Forissier ssl->next_record_offset = 0; 476811fa71b9SJerome Forissier ssl->in_left = 0; 476911fa71b9SJerome Forissier 477011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); 477111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 477211fa71b9SJerome Forissier } 477311fa71b9SJerome Forissier 477411fa71b9SJerome Forissier return( ret ); 477511fa71b9SJerome Forissier } 477611fa71b9SJerome Forissier else 477711fa71b9SJerome Forissier #endif 477811fa71b9SJerome Forissier { 477911fa71b9SJerome Forissier /* Error out (and send alert) on invalid records */ 478011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 478111fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 478211fa71b9SJerome Forissier { 478311fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, 478411fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 478511fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); 478611fa71b9SJerome Forissier } 478711fa71b9SJerome Forissier #endif 478811fa71b9SJerome Forissier return( ret ); 478911fa71b9SJerome Forissier } 479011fa71b9SJerome Forissier } 479111fa71b9SJerome Forissier 479211fa71b9SJerome Forissier 479311fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 479411fa71b9SJerome Forissier * assuming no CID and no offset between record content and 479511fa71b9SJerome Forissier * record plaintext. */ 479611fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 479711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 479811fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 479911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 480011fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 480111fa71b9SJerome Forissier 480211fa71b9SJerome Forissier /* The record content type may change during decryption, 480311fa71b9SJerome Forissier * so re-read it. */ 480411fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 480511fa71b9SJerome Forissier /* Also update the input buffer, because unfortunately 480611fa71b9SJerome Forissier * the server-side ssl_parse_client_hello() reparses the 480711fa71b9SJerome Forissier * record header when receiving a ClientHello initiating 480811fa71b9SJerome Forissier * a renegotiation. */ 480911fa71b9SJerome Forissier ssl->in_hdr[0] = rec.type; 481011fa71b9SJerome Forissier ssl->in_msg = rec.buf + rec.data_offset; 481111fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 4812*039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->in_len, 0 ); 481311fa71b9SJerome Forissier 481411fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 481511fa71b9SJerome Forissier if( ssl->transform_in != NULL && 481611fa71b9SJerome Forissier ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) 481711fa71b9SJerome Forissier { 481811fa71b9SJerome Forissier if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) 481911fa71b9SJerome Forissier { 482011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); 482111fa71b9SJerome Forissier return( ret ); 482211fa71b9SJerome Forissier } 482311fa71b9SJerome Forissier 482411fa71b9SJerome Forissier /* Check actual (decompress) record content length against 482511fa71b9SJerome Forissier * configured maximum. */ 482611fa71b9SJerome Forissier if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) 482711fa71b9SJerome Forissier { 482811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); 482911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 483011fa71b9SJerome Forissier } 483111fa71b9SJerome Forissier } 483211fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */ 483311fa71b9SJerome Forissier 483411fa71b9SJerome Forissier return( 0 ); 483511fa71b9SJerome Forissier } 483611fa71b9SJerome Forissier 483711fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) 483811fa71b9SJerome Forissier { 483911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 484011fa71b9SJerome Forissier 484111fa71b9SJerome Forissier /* 484211fa71b9SJerome Forissier * Handle particular types of records 484311fa71b9SJerome Forissier */ 484411fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 484511fa71b9SJerome Forissier { 484611fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) 484711fa71b9SJerome Forissier { 484811fa71b9SJerome Forissier return( ret ); 484911fa71b9SJerome Forissier } 485011fa71b9SJerome Forissier } 485111fa71b9SJerome Forissier 485211fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 485311fa71b9SJerome Forissier { 485411fa71b9SJerome Forissier if( ssl->in_msglen != 1 ) 485511fa71b9SJerome Forissier { 48567901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET, 485711fa71b9SJerome Forissier ssl->in_msglen ) ); 485811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 485911fa71b9SJerome Forissier } 486011fa71b9SJerome Forissier 486111fa71b9SJerome Forissier if( ssl->in_msg[0] != 1 ) 486211fa71b9SJerome Forissier { 486311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", 486411fa71b9SJerome Forissier ssl->in_msg[0] ) ); 486511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 486611fa71b9SJerome Forissier } 486711fa71b9SJerome Forissier 486811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 486911fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 487011fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && 487111fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) 487211fa71b9SJerome Forissier { 487311fa71b9SJerome Forissier if( ssl->handshake == NULL ) 487411fa71b9SJerome Forissier { 487511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); 487611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 487711fa71b9SJerome Forissier } 487811fa71b9SJerome Forissier 487911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); 488011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 488111fa71b9SJerome Forissier } 488211fa71b9SJerome Forissier #endif 488311fa71b9SJerome Forissier } 488411fa71b9SJerome Forissier 488511fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) 488611fa71b9SJerome Forissier { 488711fa71b9SJerome Forissier if( ssl->in_msglen != 2 ) 488811fa71b9SJerome Forissier { 488911fa71b9SJerome Forissier /* Note: Standard allows for more than one 2 byte alert 489011fa71b9SJerome Forissier to be packed in a single message, but Mbed TLS doesn't 489111fa71b9SJerome Forissier currently support this. */ 48927901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %" MBEDTLS_PRINTF_SIZET, 489311fa71b9SJerome Forissier ssl->in_msglen ) ); 489411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 489511fa71b9SJerome Forissier } 489611fa71b9SJerome Forissier 48977901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%u:%u]", 489811fa71b9SJerome Forissier ssl->in_msg[0], ssl->in_msg[1] ) ); 489911fa71b9SJerome Forissier 490011fa71b9SJerome Forissier /* 490111fa71b9SJerome Forissier * Ignore non-fatal alerts, except close_notify and no_renegotiation 490211fa71b9SJerome Forissier */ 490311fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) 490411fa71b9SJerome Forissier { 490511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", 490611fa71b9SJerome Forissier ssl->in_msg[1] ) ); 490711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); 490811fa71b9SJerome Forissier } 490911fa71b9SJerome Forissier 491011fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 491111fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) 491211fa71b9SJerome Forissier { 491311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); 491411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); 491511fa71b9SJerome Forissier } 491611fa71b9SJerome Forissier 491711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) 491811fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 491911fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) 492011fa71b9SJerome Forissier { 492111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); 492211fa71b9SJerome Forissier /* Will be handled when trying to parse ServerHello */ 492311fa71b9SJerome Forissier return( 0 ); 492411fa71b9SJerome Forissier } 492511fa71b9SJerome Forissier #endif 492611fa71b9SJerome Forissier 492711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) 492811fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && 492911fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 493011fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 493111fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) 493211fa71b9SJerome Forissier { 493311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); 493411fa71b9SJerome Forissier /* Will be handled in mbedtls_ssl_parse_certificate() */ 493511fa71b9SJerome Forissier return( 0 ); 493611fa71b9SJerome Forissier } 493711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ 493811fa71b9SJerome Forissier 493911fa71b9SJerome Forissier /* Silently ignore: fetch new message */ 494011fa71b9SJerome Forissier return MBEDTLS_ERR_SSL_NON_FATAL; 494111fa71b9SJerome Forissier } 494211fa71b9SJerome Forissier 494311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 494411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 494511fa71b9SJerome Forissier { 494611fa71b9SJerome Forissier /* Drop unexpected ApplicationData records, 494711fa71b9SJerome Forissier * except at the beginning of renegotiations */ 494811fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && 494911fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER 495011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 495111fa71b9SJerome Forissier && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 495211fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_HELLO ) 495311fa71b9SJerome Forissier #endif 495411fa71b9SJerome Forissier ) 495511fa71b9SJerome Forissier { 495611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); 495711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_NON_FATAL ); 495811fa71b9SJerome Forissier } 495911fa71b9SJerome Forissier 496011fa71b9SJerome Forissier if( ssl->handshake != NULL && 496111fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 496211fa71b9SJerome Forissier { 496311fa71b9SJerome Forissier mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); 496411fa71b9SJerome Forissier } 496511fa71b9SJerome Forissier } 496611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 496711fa71b9SJerome Forissier 496811fa71b9SJerome Forissier return( 0 ); 496911fa71b9SJerome Forissier } 497011fa71b9SJerome Forissier 497111fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) 497211fa71b9SJerome Forissier { 497311fa71b9SJerome Forissier return( mbedtls_ssl_send_alert_message( ssl, 497411fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 497511fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ); 497611fa71b9SJerome Forissier } 497711fa71b9SJerome Forissier 497811fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, 497911fa71b9SJerome Forissier unsigned char level, 498011fa71b9SJerome Forissier unsigned char message ) 498111fa71b9SJerome Forissier { 498211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 498311fa71b9SJerome Forissier 498411fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 498511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 498611fa71b9SJerome Forissier 4987*039e02dfSJerome Forissier if( ssl->out_left != 0 ) 4988*039e02dfSJerome Forissier return( mbedtls_ssl_flush_output( ssl ) ); 4989*039e02dfSJerome Forissier 499011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); 499111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); 499211fa71b9SJerome Forissier 499311fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; 499411fa71b9SJerome Forissier ssl->out_msglen = 2; 499511fa71b9SJerome Forissier ssl->out_msg[0] = level; 499611fa71b9SJerome Forissier ssl->out_msg[1] = message; 499711fa71b9SJerome Forissier 499811fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 499911fa71b9SJerome Forissier { 500011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 500111fa71b9SJerome Forissier return( ret ); 500211fa71b9SJerome Forissier } 500311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); 500411fa71b9SJerome Forissier 500511fa71b9SJerome Forissier return( 0 ); 500611fa71b9SJerome Forissier } 500711fa71b9SJerome Forissier 500811fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) 500911fa71b9SJerome Forissier { 501011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 501111fa71b9SJerome Forissier 501211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); 501311fa71b9SJerome Forissier 501411fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 501511fa71b9SJerome Forissier ssl->out_msglen = 1; 501611fa71b9SJerome Forissier ssl->out_msg[0] = 1; 501711fa71b9SJerome Forissier 501811fa71b9SJerome Forissier ssl->state++; 501911fa71b9SJerome Forissier 502011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) 502111fa71b9SJerome Forissier { 502211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); 502311fa71b9SJerome Forissier return( ret ); 502411fa71b9SJerome Forissier } 502511fa71b9SJerome Forissier 502611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); 502711fa71b9SJerome Forissier 502811fa71b9SJerome Forissier return( 0 ); 502911fa71b9SJerome Forissier } 503011fa71b9SJerome Forissier 503111fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) 503211fa71b9SJerome Forissier { 503311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 503411fa71b9SJerome Forissier 503511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); 503611fa71b9SJerome Forissier 503711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 503811fa71b9SJerome Forissier { 503911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 504011fa71b9SJerome Forissier return( ret ); 504111fa71b9SJerome Forissier } 504211fa71b9SJerome Forissier 504311fa71b9SJerome Forissier if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 504411fa71b9SJerome Forissier { 504511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); 504611fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 504711fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); 504811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 504911fa71b9SJerome Forissier } 505011fa71b9SJerome Forissier 505111fa71b9SJerome Forissier /* CCS records are only accepted if they have length 1 and content '1', 505211fa71b9SJerome Forissier * so we don't need to check this here. */ 505311fa71b9SJerome Forissier 505411fa71b9SJerome Forissier /* 505511fa71b9SJerome Forissier * Switch to our negotiated transform and session parameters for inbound 505611fa71b9SJerome Forissier * data. 505711fa71b9SJerome Forissier */ 505811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); 505911fa71b9SJerome Forissier ssl->transform_in = ssl->transform_negotiate; 506011fa71b9SJerome Forissier ssl->session_in = ssl->session_negotiate; 506111fa71b9SJerome Forissier 506211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 506311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 506411fa71b9SJerome Forissier { 506511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 506611fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_reset( ssl ); 506711fa71b9SJerome Forissier #endif 506811fa71b9SJerome Forissier 506911fa71b9SJerome Forissier /* Increment epoch */ 507011fa71b9SJerome Forissier if( ++ssl->in_epoch == 0 ) 507111fa71b9SJerome Forissier { 507211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); 507311fa71b9SJerome Forissier /* This is highly unlikely to happen for legitimate reasons, so 507411fa71b9SJerome Forissier treat it as an attack and don't send an alert. */ 507511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 507611fa71b9SJerome Forissier } 507711fa71b9SJerome Forissier } 507811fa71b9SJerome Forissier else 507911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 508011fa71b9SJerome Forissier memset( ssl->in_ctr, 0, 8 ); 508111fa71b9SJerome Forissier 508211fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 508311fa71b9SJerome Forissier 508411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 508511fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_activate != NULL ) 508611fa71b9SJerome Forissier { 508711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) 508811fa71b9SJerome Forissier { 508911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); 509011fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 509111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); 509211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 509311fa71b9SJerome Forissier } 509411fa71b9SJerome Forissier } 509511fa71b9SJerome Forissier #endif 509611fa71b9SJerome Forissier 509711fa71b9SJerome Forissier ssl->state++; 509811fa71b9SJerome Forissier 509911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); 510011fa71b9SJerome Forissier 510111fa71b9SJerome Forissier return( 0 ); 510211fa71b9SJerome Forissier } 510311fa71b9SJerome Forissier 510411fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the 510511fa71b9SJerome Forissier * next outgoing record is set, deduce the other pointers. 510611fa71b9SJerome Forissier * 510711fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 510811fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->out_hdr, 510911fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 511011fa71b9SJerome Forissier */ 511111fa71b9SJerome Forissier 51127901324dSJerome Forissier static size_t ssl_transform_get_explicit_iv_len( 51137901324dSJerome Forissier mbedtls_ssl_transform const *transform ) 51147901324dSJerome Forissier { 51157901324dSJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 51167901324dSJerome Forissier return( 0 ); 51177901324dSJerome Forissier 51187901324dSJerome Forissier return( transform->ivlen - transform->fixed_ivlen ); 51197901324dSJerome Forissier } 51207901324dSJerome Forissier 512111fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl, 512211fa71b9SJerome Forissier mbedtls_ssl_transform *transform ) 512311fa71b9SJerome Forissier { 512411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 512511fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 512611fa71b9SJerome Forissier { 512711fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr + 3; 512811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 512911fa71b9SJerome Forissier ssl->out_cid = ssl->out_ctr + 8; 513011fa71b9SJerome Forissier ssl->out_len = ssl->out_cid; 513111fa71b9SJerome Forissier if( transform != NULL ) 513211fa71b9SJerome Forissier ssl->out_len += transform->out_cid_len; 513311fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 513411fa71b9SJerome Forissier ssl->out_len = ssl->out_ctr + 8; 513511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 513611fa71b9SJerome Forissier ssl->out_iv = ssl->out_len + 2; 513711fa71b9SJerome Forissier } 513811fa71b9SJerome Forissier else 513911fa71b9SJerome Forissier #endif 514011fa71b9SJerome Forissier { 514111fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr - 8; 514211fa71b9SJerome Forissier ssl->out_len = ssl->out_hdr + 3; 514311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 514411fa71b9SJerome Forissier ssl->out_cid = ssl->out_len; 514511fa71b9SJerome Forissier #endif 514611fa71b9SJerome Forissier ssl->out_iv = ssl->out_hdr + 5; 514711fa71b9SJerome Forissier } 514811fa71b9SJerome Forissier 514911fa71b9SJerome Forissier ssl->out_msg = ssl->out_iv; 51507901324dSJerome Forissier /* Adjust out_msg to make space for explicit IV, if used. */ 51517901324dSJerome Forissier if( transform != NULL ) 51527901324dSJerome Forissier ssl->out_msg += ssl_transform_get_explicit_iv_len( transform ); 515311fa71b9SJerome Forissier } 515411fa71b9SJerome Forissier 515511fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the 515611fa71b9SJerome Forissier * next incoming record is set, deduce the other pointers. 515711fa71b9SJerome Forissier * 515811fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 515911fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->in_hdr, 516011fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 516111fa71b9SJerome Forissier */ 516211fa71b9SJerome Forissier 516311fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl ) 516411fa71b9SJerome Forissier { 516511fa71b9SJerome Forissier /* This function sets the pointers to match the case 516611fa71b9SJerome Forissier * of unprotected TLS/DTLS records, with both ssl->in_iv 516711fa71b9SJerome Forissier * and ssl->in_msg pointing to the beginning of the record 516811fa71b9SJerome Forissier * content. 516911fa71b9SJerome Forissier * 517011fa71b9SJerome Forissier * When decrypting a protected record, ssl->in_msg 517111fa71b9SJerome Forissier * will be shifted to point to the beginning of the 517211fa71b9SJerome Forissier * record plaintext. 517311fa71b9SJerome Forissier */ 517411fa71b9SJerome Forissier 517511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 517611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 517711fa71b9SJerome Forissier { 517811fa71b9SJerome Forissier /* This sets the header pointers to match records 517911fa71b9SJerome Forissier * without CID. When we receive a record containing 518011fa71b9SJerome Forissier * a CID, the fields are shifted accordingly in 518111fa71b9SJerome Forissier * ssl_parse_record_header(). */ 518211fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr + 3; 518311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 518411fa71b9SJerome Forissier ssl->in_cid = ssl->in_ctr + 8; 518511fa71b9SJerome Forissier ssl->in_len = ssl->in_cid; /* Default: no CID */ 518611fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 518711fa71b9SJerome Forissier ssl->in_len = ssl->in_ctr + 8; 518811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 518911fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 519011fa71b9SJerome Forissier } 519111fa71b9SJerome Forissier else 519211fa71b9SJerome Forissier #endif 519311fa71b9SJerome Forissier { 519411fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr - 8; 519511fa71b9SJerome Forissier ssl->in_len = ssl->in_hdr + 3; 519611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 519711fa71b9SJerome Forissier ssl->in_cid = ssl->in_len; 519811fa71b9SJerome Forissier #endif 519911fa71b9SJerome Forissier ssl->in_iv = ssl->in_hdr + 5; 520011fa71b9SJerome Forissier } 520111fa71b9SJerome Forissier 520211fa71b9SJerome Forissier /* This will be adjusted at record decryption time. */ 520311fa71b9SJerome Forissier ssl->in_msg = ssl->in_iv; 520411fa71b9SJerome Forissier } 520511fa71b9SJerome Forissier 520611fa71b9SJerome Forissier /* 520711fa71b9SJerome Forissier * Setup an SSL context 520811fa71b9SJerome Forissier */ 520911fa71b9SJerome Forissier 521011fa71b9SJerome Forissier void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) 521111fa71b9SJerome Forissier { 521211fa71b9SJerome Forissier /* Set the incoming and outgoing record pointers. */ 521311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 521411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 521511fa71b9SJerome Forissier { 521611fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 521711fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf; 521811fa71b9SJerome Forissier } 521911fa71b9SJerome Forissier else 522011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 522111fa71b9SJerome Forissier { 522211fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 522311fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf + 8; 522411fa71b9SJerome Forissier } 522511fa71b9SJerome Forissier 522611fa71b9SJerome Forissier /* Derive other internal pointers. */ 522711fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); 522811fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers ( ssl ); 522911fa71b9SJerome Forissier } 523011fa71b9SJerome Forissier 523111fa71b9SJerome Forissier /* 523211fa71b9SJerome Forissier * SSL get accessors 523311fa71b9SJerome Forissier */ 523411fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) 523511fa71b9SJerome Forissier { 523611fa71b9SJerome Forissier return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); 523711fa71b9SJerome Forissier } 523811fa71b9SJerome Forissier 523911fa71b9SJerome Forissier int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) 524011fa71b9SJerome Forissier { 524111fa71b9SJerome Forissier /* 524211fa71b9SJerome Forissier * Case A: We're currently holding back 524311fa71b9SJerome Forissier * a message for further processing. 524411fa71b9SJerome Forissier */ 524511fa71b9SJerome Forissier 524611fa71b9SJerome Forissier if( ssl->keep_current_message == 1 ) 524711fa71b9SJerome Forissier { 524811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); 524911fa71b9SJerome Forissier return( 1 ); 525011fa71b9SJerome Forissier } 525111fa71b9SJerome Forissier 525211fa71b9SJerome Forissier /* 525311fa71b9SJerome Forissier * Case B: Further records are pending in the current datagram. 525411fa71b9SJerome Forissier */ 525511fa71b9SJerome Forissier 525611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 525711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 525811fa71b9SJerome Forissier ssl->in_left > ssl->next_record_offset ) 525911fa71b9SJerome Forissier { 526011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); 526111fa71b9SJerome Forissier return( 1 ); 526211fa71b9SJerome Forissier } 526311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 526411fa71b9SJerome Forissier 526511fa71b9SJerome Forissier /* 526611fa71b9SJerome Forissier * Case C: A handshake message is being processed. 526711fa71b9SJerome Forissier */ 526811fa71b9SJerome Forissier 526911fa71b9SJerome Forissier if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) 527011fa71b9SJerome Forissier { 527111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); 527211fa71b9SJerome Forissier return( 1 ); 527311fa71b9SJerome Forissier } 527411fa71b9SJerome Forissier 527511fa71b9SJerome Forissier /* 527611fa71b9SJerome Forissier * Case D: An application data message is being processed 527711fa71b9SJerome Forissier */ 527811fa71b9SJerome Forissier if( ssl->in_offt != NULL ) 527911fa71b9SJerome Forissier { 528011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); 528111fa71b9SJerome Forissier return( 1 ); 528211fa71b9SJerome Forissier } 528311fa71b9SJerome Forissier 528411fa71b9SJerome Forissier /* 528511fa71b9SJerome Forissier * In all other cases, the rest of the message can be dropped. 528611fa71b9SJerome Forissier * As in ssl_get_next_record, this needs to be adapted if 528711fa71b9SJerome Forissier * we implement support for multiple alerts in single records. 528811fa71b9SJerome Forissier */ 528911fa71b9SJerome Forissier 529011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); 529111fa71b9SJerome Forissier return( 0 ); 529211fa71b9SJerome Forissier } 529311fa71b9SJerome Forissier 529411fa71b9SJerome Forissier 529511fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) 529611fa71b9SJerome Forissier { 529711fa71b9SJerome Forissier size_t transform_expansion = 0; 529811fa71b9SJerome Forissier const mbedtls_ssl_transform *transform = ssl->transform_out; 529911fa71b9SJerome Forissier unsigned block_size; 530011fa71b9SJerome Forissier 530111fa71b9SJerome Forissier size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl ); 530211fa71b9SJerome Forissier 530311fa71b9SJerome Forissier if( transform == NULL ) 530411fa71b9SJerome Forissier return( (int) out_hdr_len ); 530511fa71b9SJerome Forissier 530611fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 530711fa71b9SJerome Forissier if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) 530811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 530911fa71b9SJerome Forissier #endif 531011fa71b9SJerome Forissier 531111fa71b9SJerome Forissier switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) 531211fa71b9SJerome Forissier { 531311fa71b9SJerome Forissier case MBEDTLS_MODE_GCM: 531411fa71b9SJerome Forissier case MBEDTLS_MODE_CCM: 531511fa71b9SJerome Forissier case MBEDTLS_MODE_CHACHAPOLY: 531611fa71b9SJerome Forissier case MBEDTLS_MODE_STREAM: 531711fa71b9SJerome Forissier transform_expansion = transform->minlen; 531811fa71b9SJerome Forissier break; 531911fa71b9SJerome Forissier 532011fa71b9SJerome Forissier case MBEDTLS_MODE_CBC: 532111fa71b9SJerome Forissier 532211fa71b9SJerome Forissier block_size = mbedtls_cipher_get_block_size( 532311fa71b9SJerome Forissier &transform->cipher_ctx_enc ); 532411fa71b9SJerome Forissier 532511fa71b9SJerome Forissier /* Expansion due to the addition of the MAC. */ 532611fa71b9SJerome Forissier transform_expansion += transform->maclen; 532711fa71b9SJerome Forissier 532811fa71b9SJerome Forissier /* Expansion due to the addition of CBC padding; 532911fa71b9SJerome Forissier * Theoretically up to 256 bytes, but we never use 533011fa71b9SJerome Forissier * more than the block size of the underlying cipher. */ 533111fa71b9SJerome Forissier transform_expansion += block_size; 533211fa71b9SJerome Forissier 533311fa71b9SJerome Forissier /* For TLS 1.1 or higher, an explicit IV is added 533411fa71b9SJerome Forissier * after the record header. */ 533511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 533611fa71b9SJerome Forissier if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 533711fa71b9SJerome Forissier transform_expansion += block_size; 533811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 533911fa71b9SJerome Forissier 534011fa71b9SJerome Forissier break; 534111fa71b9SJerome Forissier 534211fa71b9SJerome Forissier default: 534311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 534411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 534511fa71b9SJerome Forissier } 534611fa71b9SJerome Forissier 534711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 534811fa71b9SJerome Forissier if( transform->out_cid_len != 0 ) 534911fa71b9SJerome Forissier transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; 535011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 535111fa71b9SJerome Forissier 535211fa71b9SJerome Forissier return( (int)( out_hdr_len + transform_expansion ) ); 535311fa71b9SJerome Forissier } 535411fa71b9SJerome Forissier 535511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 535611fa71b9SJerome Forissier /* 535711fa71b9SJerome Forissier * Check record counters and renegotiate if they're above the limit. 535811fa71b9SJerome Forissier */ 5359*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 536011fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) 536111fa71b9SJerome Forissier { 536211fa71b9SJerome Forissier size_t ep_len = mbedtls_ssl_ep_len( ssl ); 536311fa71b9SJerome Forissier int in_ctr_cmp; 536411fa71b9SJerome Forissier int out_ctr_cmp; 536511fa71b9SJerome Forissier 536611fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || 536711fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || 536811fa71b9SJerome Forissier ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) 536911fa71b9SJerome Forissier { 537011fa71b9SJerome Forissier return( 0 ); 537111fa71b9SJerome Forissier } 537211fa71b9SJerome Forissier 537311fa71b9SJerome Forissier in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, 537411fa71b9SJerome Forissier ssl->conf->renego_period + ep_len, 8 - ep_len ); 537511fa71b9SJerome Forissier out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, 537611fa71b9SJerome Forissier ssl->conf->renego_period + ep_len, 8 - ep_len ); 537711fa71b9SJerome Forissier 537811fa71b9SJerome Forissier if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) 537911fa71b9SJerome Forissier { 538011fa71b9SJerome Forissier return( 0 ); 538111fa71b9SJerome Forissier } 538211fa71b9SJerome Forissier 538311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); 538411fa71b9SJerome Forissier return( mbedtls_ssl_renegotiate( ssl ) ); 538511fa71b9SJerome Forissier } 538611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 538711fa71b9SJerome Forissier 538811fa71b9SJerome Forissier /* 538911fa71b9SJerome Forissier * Receive application data decrypted from the SSL layer 539011fa71b9SJerome Forissier */ 539111fa71b9SJerome Forissier int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) 539211fa71b9SJerome Forissier { 539311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 539411fa71b9SJerome Forissier size_t n; 539511fa71b9SJerome Forissier 539611fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 539711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 539811fa71b9SJerome Forissier 539911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); 540011fa71b9SJerome Forissier 540111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 540211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 540311fa71b9SJerome Forissier { 540411fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 540511fa71b9SJerome Forissier return( ret ); 540611fa71b9SJerome Forissier 540711fa71b9SJerome Forissier if( ssl->handshake != NULL && 540811fa71b9SJerome Forissier ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) 540911fa71b9SJerome Forissier { 541011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) 541111fa71b9SJerome Forissier return( ret ); 541211fa71b9SJerome Forissier } 541311fa71b9SJerome Forissier } 541411fa71b9SJerome Forissier #endif 541511fa71b9SJerome Forissier 541611fa71b9SJerome Forissier /* 541711fa71b9SJerome Forissier * Check if renegotiation is necessary and/or handshake is 541811fa71b9SJerome Forissier * in process. If yes, perform/continue, and fall through 541911fa71b9SJerome Forissier * if an unexpected packet is received while the client 542011fa71b9SJerome Forissier * is waiting for the ServerHello. 542111fa71b9SJerome Forissier * 542211fa71b9SJerome Forissier * (There is no equivalent to the last condition on 542311fa71b9SJerome Forissier * the server-side as it is not treated as within 542411fa71b9SJerome Forissier * a handshake while waiting for the ClientHello 542511fa71b9SJerome Forissier * after a renegotiation request.) 542611fa71b9SJerome Forissier */ 542711fa71b9SJerome Forissier 542811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 542911fa71b9SJerome Forissier ret = ssl_check_ctr_renegotiate( ssl ); 543011fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 543111fa71b9SJerome Forissier ret != 0 ) 543211fa71b9SJerome Forissier { 543311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); 543411fa71b9SJerome Forissier return( ret ); 543511fa71b9SJerome Forissier } 543611fa71b9SJerome Forissier #endif 543711fa71b9SJerome Forissier 543811fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 543911fa71b9SJerome Forissier { 544011fa71b9SJerome Forissier ret = mbedtls_ssl_handshake( ssl ); 544111fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 544211fa71b9SJerome Forissier ret != 0 ) 544311fa71b9SJerome Forissier { 544411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); 544511fa71b9SJerome Forissier return( ret ); 544611fa71b9SJerome Forissier } 544711fa71b9SJerome Forissier } 544811fa71b9SJerome Forissier 544911fa71b9SJerome Forissier /* Loop as long as no application data record is available */ 545011fa71b9SJerome Forissier while( ssl->in_offt == NULL ) 545111fa71b9SJerome Forissier { 545211fa71b9SJerome Forissier /* Start timer if not already running */ 545311fa71b9SJerome Forissier if( ssl->f_get_timer != NULL && 545411fa71b9SJerome Forissier ssl->f_get_timer( ssl->p_timer ) == -1 ) 545511fa71b9SJerome Forissier { 545611fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout ); 545711fa71b9SJerome Forissier } 545811fa71b9SJerome Forissier 545911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 546011fa71b9SJerome Forissier { 546111fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) 546211fa71b9SJerome Forissier return( 0 ); 546311fa71b9SJerome Forissier 546411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 546511fa71b9SJerome Forissier return( ret ); 546611fa71b9SJerome Forissier } 546711fa71b9SJerome Forissier 546811fa71b9SJerome Forissier if( ssl->in_msglen == 0 && 546911fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) 547011fa71b9SJerome Forissier { 547111fa71b9SJerome Forissier /* 547211fa71b9SJerome Forissier * OpenSSL sends empty messages to randomize the IV 547311fa71b9SJerome Forissier */ 547411fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 547511fa71b9SJerome Forissier { 547611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) 547711fa71b9SJerome Forissier return( 0 ); 547811fa71b9SJerome Forissier 547911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 548011fa71b9SJerome Forissier return( ret ); 548111fa71b9SJerome Forissier } 548211fa71b9SJerome Forissier } 548311fa71b9SJerome Forissier 548411fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 548511fa71b9SJerome Forissier { 548611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); 548711fa71b9SJerome Forissier 548811fa71b9SJerome Forissier /* 548911fa71b9SJerome Forissier * - For client-side, expect SERVER_HELLO_REQUEST. 549011fa71b9SJerome Forissier * - For server-side, expect CLIENT_HELLO. 549111fa71b9SJerome Forissier * - Fail (TLS) or silently drop record (DTLS) in other cases. 549211fa71b9SJerome Forissier */ 549311fa71b9SJerome Forissier 549411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C) 549511fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && 549611fa71b9SJerome Forissier ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || 549711fa71b9SJerome Forissier ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) 549811fa71b9SJerome Forissier { 549911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); 550011fa71b9SJerome Forissier 550111fa71b9SJerome Forissier /* With DTLS, drop the packet (probably from last handshake) */ 550211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 550311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 550411fa71b9SJerome Forissier { 550511fa71b9SJerome Forissier continue; 550611fa71b9SJerome Forissier } 550711fa71b9SJerome Forissier #endif 550811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 550911fa71b9SJerome Forissier } 551011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */ 551111fa71b9SJerome Forissier 551211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) 551311fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 551411fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) 551511fa71b9SJerome Forissier { 551611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); 551711fa71b9SJerome Forissier 551811fa71b9SJerome Forissier /* With DTLS, drop the packet (probably from last handshake) */ 551911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 552011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 552111fa71b9SJerome Forissier { 552211fa71b9SJerome Forissier continue; 552311fa71b9SJerome Forissier } 552411fa71b9SJerome Forissier #endif 552511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 552611fa71b9SJerome Forissier } 552711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C */ 552811fa71b9SJerome Forissier 552911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 553011fa71b9SJerome Forissier /* Determine whether renegotiation attempt should be accepted */ 553111fa71b9SJerome Forissier if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || 553211fa71b9SJerome Forissier ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 553311fa71b9SJerome Forissier ssl->conf->allow_legacy_renegotiation == 553411fa71b9SJerome Forissier MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) 553511fa71b9SJerome Forissier { 553611fa71b9SJerome Forissier /* 553711fa71b9SJerome Forissier * Accept renegotiation request 553811fa71b9SJerome Forissier */ 553911fa71b9SJerome Forissier 554011fa71b9SJerome Forissier /* DTLS clients need to know renego is server-initiated */ 554111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 554211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 554311fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) 554411fa71b9SJerome Forissier { 554511fa71b9SJerome Forissier ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; 554611fa71b9SJerome Forissier } 554711fa71b9SJerome Forissier #endif 554811fa71b9SJerome Forissier ret = mbedtls_ssl_start_renegotiation( ssl ); 554911fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 555011fa71b9SJerome Forissier ret != 0 ) 555111fa71b9SJerome Forissier { 555211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation", 555311fa71b9SJerome Forissier ret ); 555411fa71b9SJerome Forissier return( ret ); 555511fa71b9SJerome Forissier } 555611fa71b9SJerome Forissier } 555711fa71b9SJerome Forissier else 555811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 555911fa71b9SJerome Forissier { 556011fa71b9SJerome Forissier /* 556111fa71b9SJerome Forissier * Refuse renegotiation 556211fa71b9SJerome Forissier */ 556311fa71b9SJerome Forissier 556411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); 556511fa71b9SJerome Forissier 556611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 556711fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 556811fa71b9SJerome Forissier { 556911fa71b9SJerome Forissier /* SSLv3 does not have a "no_renegotiation" warning, so 557011fa71b9SJerome Forissier we send a fatal alert and abort the connection. */ 557111fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 557211fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); 557311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 557411fa71b9SJerome Forissier } 557511fa71b9SJerome Forissier else 557611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 557711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 557811fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 557911fa71b9SJerome Forissier if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) 558011fa71b9SJerome Forissier { 558111fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_send_alert_message( ssl, 558211fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING, 558311fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) 558411fa71b9SJerome Forissier { 558511fa71b9SJerome Forissier return( ret ); 558611fa71b9SJerome Forissier } 558711fa71b9SJerome Forissier } 558811fa71b9SJerome Forissier else 558911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || 559011fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 559111fa71b9SJerome Forissier { 559211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 559311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 559411fa71b9SJerome Forissier } 559511fa71b9SJerome Forissier } 559611fa71b9SJerome Forissier 559711fa71b9SJerome Forissier /* At this point, we don't know whether the renegotiation has been 559811fa71b9SJerome Forissier * completed or not. The cases to consider are the following: 559911fa71b9SJerome Forissier * 1) The renegotiation is complete. In this case, no new record 560011fa71b9SJerome Forissier * has been read yet. 560111fa71b9SJerome Forissier * 2) The renegotiation is incomplete because the client received 560211fa71b9SJerome Forissier * an application data record while awaiting the ServerHello. 560311fa71b9SJerome Forissier * 3) The renegotiation is incomplete because the client received 560411fa71b9SJerome Forissier * a non-handshake, non-application data message while awaiting 560511fa71b9SJerome Forissier * the ServerHello. 560611fa71b9SJerome Forissier * In each of these case, looping will be the proper action: 560711fa71b9SJerome Forissier * - For 1), the next iteration will read a new record and check 560811fa71b9SJerome Forissier * if it's application data. 560911fa71b9SJerome Forissier * - For 2), the loop condition isn't satisfied as application data 561011fa71b9SJerome Forissier * is present, hence continue is the same as break 561111fa71b9SJerome Forissier * - For 3), the loop condition is satisfied and read_record 561211fa71b9SJerome Forissier * will re-deliver the message that was held back by the client 561311fa71b9SJerome Forissier * when expecting the ServerHello. 561411fa71b9SJerome Forissier */ 561511fa71b9SJerome Forissier continue; 561611fa71b9SJerome Forissier } 561711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 561811fa71b9SJerome Forissier else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 561911fa71b9SJerome Forissier { 562011fa71b9SJerome Forissier if( ssl->conf->renego_max_records >= 0 ) 562111fa71b9SJerome Forissier { 562211fa71b9SJerome Forissier if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) 562311fa71b9SJerome Forissier { 562411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " 562511fa71b9SJerome Forissier "but not honored by client" ) ); 562611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 562711fa71b9SJerome Forissier } 562811fa71b9SJerome Forissier } 562911fa71b9SJerome Forissier } 563011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 563111fa71b9SJerome Forissier 563211fa71b9SJerome Forissier /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ 563311fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) 563411fa71b9SJerome Forissier { 563511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); 563611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 563711fa71b9SJerome Forissier } 563811fa71b9SJerome Forissier 563911fa71b9SJerome Forissier if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 564011fa71b9SJerome Forissier { 564111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); 564211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 564311fa71b9SJerome Forissier } 564411fa71b9SJerome Forissier 564511fa71b9SJerome Forissier ssl->in_offt = ssl->in_msg; 564611fa71b9SJerome Forissier 564711fa71b9SJerome Forissier /* We're going to return something now, cancel timer, 564811fa71b9SJerome Forissier * except if handshake (renegotiation) is in progress */ 564911fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 565011fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 565111fa71b9SJerome Forissier 565211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 565311fa71b9SJerome Forissier /* If we requested renego but received AppData, resend HelloRequest. 565411fa71b9SJerome Forissier * Do it now, after setting in_offt, to avoid taking this branch 565511fa71b9SJerome Forissier * again if ssl_write_hello_request() returns WANT_WRITE */ 565611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 565711fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 565811fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 565911fa71b9SJerome Forissier { 566011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 ) 566111fa71b9SJerome Forissier { 566211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request", 566311fa71b9SJerome Forissier ret ); 566411fa71b9SJerome Forissier return( ret ); 566511fa71b9SJerome Forissier } 566611fa71b9SJerome Forissier } 566711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 566811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 566911fa71b9SJerome Forissier } 567011fa71b9SJerome Forissier 567111fa71b9SJerome Forissier n = ( len < ssl->in_msglen ) 567211fa71b9SJerome Forissier ? len : ssl->in_msglen; 567311fa71b9SJerome Forissier 567411fa71b9SJerome Forissier memcpy( buf, ssl->in_offt, n ); 567511fa71b9SJerome Forissier ssl->in_msglen -= n; 567611fa71b9SJerome Forissier 56777901324dSJerome Forissier /* Zeroising the plaintext buffer to erase unused application data 56787901324dSJerome Forissier from the memory. */ 56797901324dSJerome Forissier mbedtls_platform_zeroize( ssl->in_offt, n ); 56807901324dSJerome Forissier 568111fa71b9SJerome Forissier if( ssl->in_msglen == 0 ) 568211fa71b9SJerome Forissier { 568311fa71b9SJerome Forissier /* all bytes consumed */ 568411fa71b9SJerome Forissier ssl->in_offt = NULL; 568511fa71b9SJerome Forissier ssl->keep_current_message = 0; 568611fa71b9SJerome Forissier } 568711fa71b9SJerome Forissier else 568811fa71b9SJerome Forissier { 568911fa71b9SJerome Forissier /* more data available */ 569011fa71b9SJerome Forissier ssl->in_offt += n; 569111fa71b9SJerome Forissier } 569211fa71b9SJerome Forissier 569311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); 569411fa71b9SJerome Forissier 569511fa71b9SJerome Forissier return( (int) n ); 569611fa71b9SJerome Forissier } 569711fa71b9SJerome Forissier 569811fa71b9SJerome Forissier /* 569911fa71b9SJerome Forissier * Send application data to be encrypted by the SSL layer, taking care of max 570011fa71b9SJerome Forissier * fragment length and buffer size. 570111fa71b9SJerome Forissier * 570211fa71b9SJerome Forissier * According to RFC 5246 Section 6.2.1: 570311fa71b9SJerome Forissier * 570411fa71b9SJerome Forissier * Zero-length fragments of Application data MAY be sent as they are 570511fa71b9SJerome Forissier * potentially useful as a traffic analysis countermeasure. 570611fa71b9SJerome Forissier * 570711fa71b9SJerome Forissier * Therefore, it is possible that the input message length is 0 and the 570811fa71b9SJerome Forissier * corresponding return code is 0 on success. 570911fa71b9SJerome Forissier */ 5710*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 571111fa71b9SJerome Forissier static int ssl_write_real( mbedtls_ssl_context *ssl, 571211fa71b9SJerome Forissier const unsigned char *buf, size_t len ) 571311fa71b9SJerome Forissier { 571411fa71b9SJerome Forissier int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); 571511fa71b9SJerome Forissier const size_t max_len = (size_t) ret; 571611fa71b9SJerome Forissier 571711fa71b9SJerome Forissier if( ret < 0 ) 571811fa71b9SJerome Forissier { 571911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); 572011fa71b9SJerome Forissier return( ret ); 572111fa71b9SJerome Forissier } 572211fa71b9SJerome Forissier 572311fa71b9SJerome Forissier if( len > max_len ) 572411fa71b9SJerome Forissier { 572511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 572611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 572711fa71b9SJerome Forissier { 572811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " 57297901324dSJerome Forissier "maximum fragment length: %" MBEDTLS_PRINTF_SIZET 57307901324dSJerome Forissier " > %" MBEDTLS_PRINTF_SIZET, 573111fa71b9SJerome Forissier len, max_len ) ); 573211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 573311fa71b9SJerome Forissier } 573411fa71b9SJerome Forissier else 573511fa71b9SJerome Forissier #endif 573611fa71b9SJerome Forissier len = max_len; 573711fa71b9SJerome Forissier } 573811fa71b9SJerome Forissier 573911fa71b9SJerome Forissier if( ssl->out_left != 0 ) 574011fa71b9SJerome Forissier { 574111fa71b9SJerome Forissier /* 574211fa71b9SJerome Forissier * The user has previously tried to send the data and 574311fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially 574411fa71b9SJerome Forissier * written. In this case, we expect the high-level write function 574511fa71b9SJerome Forissier * (e.g. mbedtls_ssl_write()) to be called with the same parameters 574611fa71b9SJerome Forissier */ 574711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 574811fa71b9SJerome Forissier { 574911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); 575011fa71b9SJerome Forissier return( ret ); 575111fa71b9SJerome Forissier } 575211fa71b9SJerome Forissier } 575311fa71b9SJerome Forissier else 575411fa71b9SJerome Forissier { 575511fa71b9SJerome Forissier /* 575611fa71b9SJerome Forissier * The user is trying to send a message the first time, so we need to 575711fa71b9SJerome Forissier * copy the data into the internal buffers and setup the data structure 575811fa71b9SJerome Forissier * to keep track of partial writes 575911fa71b9SJerome Forissier */ 576011fa71b9SJerome Forissier ssl->out_msglen = len; 576111fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; 576211fa71b9SJerome Forissier memcpy( ssl->out_msg, buf, len ); 576311fa71b9SJerome Forissier 576411fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 576511fa71b9SJerome Forissier { 576611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 576711fa71b9SJerome Forissier return( ret ); 576811fa71b9SJerome Forissier } 576911fa71b9SJerome Forissier } 577011fa71b9SJerome Forissier 577111fa71b9SJerome Forissier return( (int) len ); 577211fa71b9SJerome Forissier } 577311fa71b9SJerome Forissier 577411fa71b9SJerome Forissier /* 577511fa71b9SJerome Forissier * Write application data, doing 1/n-1 splitting if necessary. 577611fa71b9SJerome Forissier * 577711fa71b9SJerome Forissier * With non-blocking I/O, ssl_write_real() may return WANT_WRITE, 577811fa71b9SJerome Forissier * then the caller will call us again with the same arguments, so 577911fa71b9SJerome Forissier * remember whether we already did the split or not. 578011fa71b9SJerome Forissier */ 578111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) 5782*039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL 578311fa71b9SJerome Forissier static int ssl_write_split( mbedtls_ssl_context *ssl, 578411fa71b9SJerome Forissier const unsigned char *buf, size_t len ) 578511fa71b9SJerome Forissier { 578611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 578711fa71b9SJerome Forissier 578811fa71b9SJerome Forissier if( ssl->conf->cbc_record_splitting == 578911fa71b9SJerome Forissier MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || 579011fa71b9SJerome Forissier len <= 1 || 579111fa71b9SJerome Forissier ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || 579211fa71b9SJerome Forissier mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) 579311fa71b9SJerome Forissier != MBEDTLS_MODE_CBC ) 579411fa71b9SJerome Forissier { 579511fa71b9SJerome Forissier return( ssl_write_real( ssl, buf, len ) ); 579611fa71b9SJerome Forissier } 579711fa71b9SJerome Forissier 579811fa71b9SJerome Forissier if( ssl->split_done == 0 ) 579911fa71b9SJerome Forissier { 580011fa71b9SJerome Forissier if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) 580111fa71b9SJerome Forissier return( ret ); 580211fa71b9SJerome Forissier ssl->split_done = 1; 580311fa71b9SJerome Forissier } 580411fa71b9SJerome Forissier 580511fa71b9SJerome Forissier if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) 580611fa71b9SJerome Forissier return( ret ); 580711fa71b9SJerome Forissier ssl->split_done = 0; 580811fa71b9SJerome Forissier 580911fa71b9SJerome Forissier return( ret + 1 ); 581011fa71b9SJerome Forissier } 581111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ 581211fa71b9SJerome Forissier 581311fa71b9SJerome Forissier /* 581411fa71b9SJerome Forissier * Write application data (public-facing wrapper) 581511fa71b9SJerome Forissier */ 581611fa71b9SJerome Forissier int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) 581711fa71b9SJerome Forissier { 581811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 581911fa71b9SJerome Forissier 582011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); 582111fa71b9SJerome Forissier 582211fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 582311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 582411fa71b9SJerome Forissier 582511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 582611fa71b9SJerome Forissier if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) 582711fa71b9SJerome Forissier { 582811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); 582911fa71b9SJerome Forissier return( ret ); 583011fa71b9SJerome Forissier } 583111fa71b9SJerome Forissier #endif 583211fa71b9SJerome Forissier 583311fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 583411fa71b9SJerome Forissier { 583511fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) 583611fa71b9SJerome Forissier { 583711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); 583811fa71b9SJerome Forissier return( ret ); 583911fa71b9SJerome Forissier } 584011fa71b9SJerome Forissier } 584111fa71b9SJerome Forissier 584211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) 584311fa71b9SJerome Forissier ret = ssl_write_split( ssl, buf, len ); 584411fa71b9SJerome Forissier #else 584511fa71b9SJerome Forissier ret = ssl_write_real( ssl, buf, len ); 584611fa71b9SJerome Forissier #endif 584711fa71b9SJerome Forissier 584811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); 584911fa71b9SJerome Forissier 585011fa71b9SJerome Forissier return( ret ); 585111fa71b9SJerome Forissier } 585211fa71b9SJerome Forissier 585311fa71b9SJerome Forissier /* 585411fa71b9SJerome Forissier * Notify the peer that the connection is being closed 585511fa71b9SJerome Forissier */ 585611fa71b9SJerome Forissier int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) 585711fa71b9SJerome Forissier { 585811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 585911fa71b9SJerome Forissier 586011fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 586111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 586211fa71b9SJerome Forissier 586311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); 586411fa71b9SJerome Forissier 586511fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 586611fa71b9SJerome Forissier { 586711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_send_alert_message( ssl, 586811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING, 586911fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) 587011fa71b9SJerome Forissier { 587111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); 587211fa71b9SJerome Forissier return( ret ); 587311fa71b9SJerome Forissier } 587411fa71b9SJerome Forissier } 587511fa71b9SJerome Forissier 587611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); 587711fa71b9SJerome Forissier 587811fa71b9SJerome Forissier return( 0 ); 587911fa71b9SJerome Forissier } 588011fa71b9SJerome Forissier 588111fa71b9SJerome Forissier void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) 588211fa71b9SJerome Forissier { 588311fa71b9SJerome Forissier if( transform == NULL ) 588411fa71b9SJerome Forissier return; 588511fa71b9SJerome Forissier 588611fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 588711fa71b9SJerome Forissier deflateEnd( &transform->ctx_deflate ); 588811fa71b9SJerome Forissier inflateEnd( &transform->ctx_inflate ); 588911fa71b9SJerome Forissier #endif 589011fa71b9SJerome Forissier 589111fa71b9SJerome Forissier mbedtls_cipher_free( &transform->cipher_ctx_enc ); 589211fa71b9SJerome Forissier mbedtls_cipher_free( &transform->cipher_ctx_dec ); 589311fa71b9SJerome Forissier 589411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 589511fa71b9SJerome Forissier mbedtls_md_free( &transform->md_ctx_enc ); 589611fa71b9SJerome Forissier mbedtls_md_free( &transform->md_ctx_dec ); 589711fa71b9SJerome Forissier #endif 589811fa71b9SJerome Forissier 589911fa71b9SJerome Forissier mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); 590011fa71b9SJerome Forissier } 590111fa71b9SJerome Forissier 590211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 590311fa71b9SJerome Forissier 590411fa71b9SJerome Forissier void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl ) 590511fa71b9SJerome Forissier { 590611fa71b9SJerome Forissier unsigned offset; 590711fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 590811fa71b9SJerome Forissier 590911fa71b9SJerome Forissier if( hs == NULL ) 591011fa71b9SJerome Forissier return; 591111fa71b9SJerome Forissier 591211fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 591311fa71b9SJerome Forissier 591411fa71b9SJerome Forissier for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) 591511fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, offset ); 591611fa71b9SJerome Forissier } 591711fa71b9SJerome Forissier 591811fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, 591911fa71b9SJerome Forissier uint8_t slot ) 592011fa71b9SJerome Forissier { 592111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 592211fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; 592311fa71b9SJerome Forissier 592411fa71b9SJerome Forissier if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) 592511fa71b9SJerome Forissier return; 592611fa71b9SJerome Forissier 592711fa71b9SJerome Forissier if( hs_buf->is_valid == 1 ) 592811fa71b9SJerome Forissier { 592911fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= hs_buf->data_len; 593011fa71b9SJerome Forissier mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); 593111fa71b9SJerome Forissier mbedtls_free( hs_buf->data ); 593211fa71b9SJerome Forissier memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); 593311fa71b9SJerome Forissier } 593411fa71b9SJerome Forissier } 593511fa71b9SJerome Forissier 593611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 593711fa71b9SJerome Forissier 593811fa71b9SJerome Forissier /* 593911fa71b9SJerome Forissier * Convert version numbers to/from wire format 594011fa71b9SJerome Forissier * and, for DTLS, to/from TLS equivalent. 594111fa71b9SJerome Forissier * 594211fa71b9SJerome Forissier * For TLS this is the identity. 594311fa71b9SJerome Forissier * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: 594411fa71b9SJerome Forissier * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) 594511fa71b9SJerome Forissier * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) 594611fa71b9SJerome Forissier */ 594711fa71b9SJerome Forissier void mbedtls_ssl_write_version( int major, int minor, int transport, 594811fa71b9SJerome Forissier unsigned char ver[2] ) 594911fa71b9SJerome Forissier { 595011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 595111fa71b9SJerome Forissier if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 595211fa71b9SJerome Forissier { 595311fa71b9SJerome Forissier if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) 595411fa71b9SJerome Forissier --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ 595511fa71b9SJerome Forissier 595611fa71b9SJerome Forissier ver[0] = (unsigned char)( 255 - ( major - 2 ) ); 595711fa71b9SJerome Forissier ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); 595811fa71b9SJerome Forissier } 595911fa71b9SJerome Forissier else 596011fa71b9SJerome Forissier #else 596111fa71b9SJerome Forissier ((void) transport); 596211fa71b9SJerome Forissier #endif 596311fa71b9SJerome Forissier { 596411fa71b9SJerome Forissier ver[0] = (unsigned char) major; 596511fa71b9SJerome Forissier ver[1] = (unsigned char) minor; 596611fa71b9SJerome Forissier } 596711fa71b9SJerome Forissier } 596811fa71b9SJerome Forissier 596911fa71b9SJerome Forissier void mbedtls_ssl_read_version( int *major, int *minor, int transport, 597011fa71b9SJerome Forissier const unsigned char ver[2] ) 597111fa71b9SJerome Forissier { 597211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 597311fa71b9SJerome Forissier if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 597411fa71b9SJerome Forissier { 597511fa71b9SJerome Forissier *major = 255 - ver[0] + 2; 597611fa71b9SJerome Forissier *minor = 255 - ver[1] + 1; 597711fa71b9SJerome Forissier 597811fa71b9SJerome Forissier if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) 597911fa71b9SJerome Forissier ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ 598011fa71b9SJerome Forissier } 598111fa71b9SJerome Forissier else 598211fa71b9SJerome Forissier #else 598311fa71b9SJerome Forissier ((void) transport); 598411fa71b9SJerome Forissier #endif 598511fa71b9SJerome Forissier { 598611fa71b9SJerome Forissier *major = ver[0]; 598711fa71b9SJerome Forissier *minor = ver[1]; 598811fa71b9SJerome Forissier } 598911fa71b9SJerome Forissier } 599011fa71b9SJerome Forissier 599111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */ 5992