111fa71b9SJerome Forissier /* 211fa71b9SJerome Forissier * Generic SSL/TLS messaging layer functions 311fa71b9SJerome Forissier * (record layer + retransmission state machine) 411fa71b9SJerome Forissier * 5*7901324dSJerome 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 29*7901324dSJerome 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" 4711fa71b9SJerome Forissier 48*7901324dSJerome Forissier #include "ssl_invasive.h" 49*7901324dSJerome 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) 9411fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, 9511fa71b9SJerome Forissier unsigned char *buf, 9611fa71b9SJerome Forissier size_t len, 9711fa71b9SJerome Forissier mbedtls_record *rec ); 9811fa71b9SJerome Forissier 9911fa71b9SJerome Forissier int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl, 10011fa71b9SJerome Forissier unsigned char *buf, 10111fa71b9SJerome Forissier size_t buflen ) 10211fa71b9SJerome Forissier { 10311fa71b9SJerome Forissier int ret = 0; 10411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) ); 10511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen ); 10611fa71b9SJerome Forissier 10711fa71b9SJerome Forissier /* We don't support record checking in TLS because 10811fa71b9SJerome Forissier * (a) there doesn't seem to be a usecase for it, and 10911fa71b9SJerome Forissier * (b) In SSLv3 and TLS 1.0, CBC record decryption has state 11011fa71b9SJerome Forissier * and we'd need to backup the transform here. 11111fa71b9SJerome Forissier */ 11211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) 11311fa71b9SJerome Forissier { 11411fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 11511fa71b9SJerome Forissier goto exit; 11611fa71b9SJerome Forissier } 11711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 11811fa71b9SJerome Forissier else 11911fa71b9SJerome Forissier { 12011fa71b9SJerome Forissier mbedtls_record rec; 12111fa71b9SJerome Forissier 12211fa71b9SJerome Forissier ret = ssl_parse_record_header( ssl, buf, buflen, &rec ); 12311fa71b9SJerome Forissier if( ret != 0 ) 12411fa71b9SJerome Forissier { 12511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret ); 12611fa71b9SJerome Forissier goto exit; 12711fa71b9SJerome Forissier } 12811fa71b9SJerome Forissier 12911fa71b9SJerome Forissier if( ssl->transform_in != NULL ) 13011fa71b9SJerome Forissier { 13111fa71b9SJerome Forissier ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec ); 13211fa71b9SJerome Forissier if( ret != 0 ) 13311fa71b9SJerome Forissier { 13411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret ); 13511fa71b9SJerome Forissier goto exit; 13611fa71b9SJerome Forissier } 13711fa71b9SJerome Forissier } 13811fa71b9SJerome Forissier } 13911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 14011fa71b9SJerome Forissier 14111fa71b9SJerome Forissier exit: 14211fa71b9SJerome Forissier /* On success, we have decrypted the buffer in-place, so make 14311fa71b9SJerome Forissier * sure we don't leak any plaintext data. */ 14411fa71b9SJerome Forissier mbedtls_platform_zeroize( buf, buflen ); 14511fa71b9SJerome Forissier 14611fa71b9SJerome Forissier /* For the purpose of this API, treat messages with unexpected CID 14711fa71b9SJerome Forissier * as well as such from future epochs as unexpected. */ 14811fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID || 14911fa71b9SJerome Forissier ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 15011fa71b9SJerome Forissier { 15111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 15211fa71b9SJerome Forissier } 15311fa71b9SJerome Forissier 15411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) ); 15511fa71b9SJerome Forissier return( ret ); 15611fa71b9SJerome Forissier } 15711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RECORD_CHECKING */ 15811fa71b9SJerome Forissier 15911fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0 16011fa71b9SJerome Forissier #define SSL_FORCE_FLUSH 1 16111fa71b9SJerome Forissier 16211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 16311fa71b9SJerome Forissier 16411fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */ 16511fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, 16611fa71b9SJerome Forissier uint8_t slot ); 16711fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ); 16811fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ); 16911fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ); 17011fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl ); 17111fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, 17211fa71b9SJerome Forissier mbedtls_record const *rec ); 17311fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ); 17411fa71b9SJerome Forissier 17511fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl ) 17611fa71b9SJerome Forissier { 17711fa71b9SJerome Forissier size_t mtu = mbedtls_ssl_get_current_mtu( ssl ); 17811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 17911fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 18011fa71b9SJerome Forissier #else 18111fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 18211fa71b9SJerome Forissier #endif 18311fa71b9SJerome Forissier 18411fa71b9SJerome Forissier if( mtu != 0 && mtu < out_buf_len ) 18511fa71b9SJerome Forissier return( mtu ); 18611fa71b9SJerome Forissier 18711fa71b9SJerome Forissier return( out_buf_len ); 18811fa71b9SJerome Forissier } 18911fa71b9SJerome Forissier 19011fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl ) 19111fa71b9SJerome Forissier { 19211fa71b9SJerome Forissier size_t const bytes_written = ssl->out_left; 19311fa71b9SJerome Forissier size_t const mtu = ssl_get_maximum_datagram_size( ssl ); 19411fa71b9SJerome Forissier 19511fa71b9SJerome Forissier /* Double-check that the write-index hasn't gone 19611fa71b9SJerome Forissier * past what we can transmit in a single datagram. */ 19711fa71b9SJerome Forissier if( bytes_written > mtu ) 19811fa71b9SJerome Forissier { 19911fa71b9SJerome Forissier /* Should never happen... */ 20011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 20111fa71b9SJerome Forissier } 20211fa71b9SJerome Forissier 20311fa71b9SJerome Forissier return( (int) ( mtu - bytes_written ) ); 20411fa71b9SJerome Forissier } 20511fa71b9SJerome Forissier 20611fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl ) 20711fa71b9SJerome Forissier { 20811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 20911fa71b9SJerome Forissier size_t remaining, expansion; 21011fa71b9SJerome Forissier size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; 21111fa71b9SJerome Forissier 21211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 21311fa71b9SJerome Forissier const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl ); 21411fa71b9SJerome Forissier 21511fa71b9SJerome Forissier if( max_len > mfl ) 21611fa71b9SJerome Forissier max_len = mfl; 21711fa71b9SJerome Forissier 21811fa71b9SJerome Forissier /* By the standard (RFC 6066 Sect. 4), the MFL extension 21911fa71b9SJerome Forissier * only limits the maximum record payload size, so in theory 22011fa71b9SJerome Forissier * we would be allowed to pack multiple records of payload size 22111fa71b9SJerome Forissier * MFL into a single datagram. However, this would mean that there's 22211fa71b9SJerome Forissier * no way to explicitly communicate MTU restrictions to the peer. 22311fa71b9SJerome Forissier * 22411fa71b9SJerome Forissier * The following reduction of max_len makes sure that we never 22511fa71b9SJerome Forissier * write datagrams larger than MFL + Record Expansion Overhead. 22611fa71b9SJerome Forissier */ 22711fa71b9SJerome Forissier if( max_len <= ssl->out_left ) 22811fa71b9SJerome Forissier return( 0 ); 22911fa71b9SJerome Forissier 23011fa71b9SJerome Forissier max_len -= ssl->out_left; 23111fa71b9SJerome Forissier #endif 23211fa71b9SJerome Forissier 23311fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram( ssl ); 23411fa71b9SJerome Forissier if( ret < 0 ) 23511fa71b9SJerome Forissier return( ret ); 23611fa71b9SJerome Forissier remaining = (size_t) ret; 23711fa71b9SJerome Forissier 23811fa71b9SJerome Forissier ret = mbedtls_ssl_get_record_expansion( ssl ); 23911fa71b9SJerome Forissier if( ret < 0 ) 24011fa71b9SJerome Forissier return( ret ); 24111fa71b9SJerome Forissier expansion = (size_t) ret; 24211fa71b9SJerome Forissier 24311fa71b9SJerome Forissier if( remaining <= expansion ) 24411fa71b9SJerome Forissier return( 0 ); 24511fa71b9SJerome Forissier 24611fa71b9SJerome Forissier remaining -= expansion; 24711fa71b9SJerome Forissier if( remaining >= max_len ) 24811fa71b9SJerome Forissier remaining = max_len; 24911fa71b9SJerome Forissier 25011fa71b9SJerome Forissier return( (int) remaining ); 25111fa71b9SJerome Forissier } 25211fa71b9SJerome Forissier 25311fa71b9SJerome Forissier /* 25411fa71b9SJerome Forissier * Double the retransmit timeout value, within the allowed range, 25511fa71b9SJerome Forissier * returning -1 if the maximum value has already been reached. 25611fa71b9SJerome Forissier */ 25711fa71b9SJerome Forissier static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) 25811fa71b9SJerome Forissier { 25911fa71b9SJerome Forissier uint32_t new_timeout; 26011fa71b9SJerome Forissier 26111fa71b9SJerome Forissier if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) 26211fa71b9SJerome Forissier return( -1 ); 26311fa71b9SJerome Forissier 26411fa71b9SJerome Forissier /* Implement the final paragraph of RFC 6347 section 4.1.1.1 26511fa71b9SJerome Forissier * in the following way: after the initial transmission and a first 26611fa71b9SJerome Forissier * retransmission, back off to a temporary estimated MTU of 508 bytes. 26711fa71b9SJerome Forissier * This value is guaranteed to be deliverable (if not guaranteed to be 26811fa71b9SJerome Forissier * delivered) of any compliant IPv4 (and IPv6) network, and should work 26911fa71b9SJerome Forissier * on most non-IP stacks too. */ 27011fa71b9SJerome Forissier if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) 27111fa71b9SJerome Forissier { 27211fa71b9SJerome Forissier ssl->handshake->mtu = 508; 27311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); 27411fa71b9SJerome Forissier } 27511fa71b9SJerome Forissier 27611fa71b9SJerome Forissier new_timeout = 2 * ssl->handshake->retransmit_timeout; 27711fa71b9SJerome Forissier 27811fa71b9SJerome Forissier /* Avoid arithmetic overflow and range overflow */ 27911fa71b9SJerome Forissier if( new_timeout < ssl->handshake->retransmit_timeout || 28011fa71b9SJerome Forissier new_timeout > ssl->conf->hs_timeout_max ) 28111fa71b9SJerome Forissier { 28211fa71b9SJerome Forissier new_timeout = ssl->conf->hs_timeout_max; 28311fa71b9SJerome Forissier } 28411fa71b9SJerome Forissier 28511fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = new_timeout; 286*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs", 287*7901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout ) ); 28811fa71b9SJerome Forissier 28911fa71b9SJerome Forissier return( 0 ); 29011fa71b9SJerome Forissier } 29111fa71b9SJerome Forissier 29211fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) 29311fa71b9SJerome Forissier { 29411fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; 295*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs", 296*7901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout ) ); 29711fa71b9SJerome Forissier } 29811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 29911fa71b9SJerome Forissier 30011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 30111fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, 30211fa71b9SJerome Forissier const unsigned char *key_enc, const unsigned char *key_dec, 30311fa71b9SJerome Forissier size_t keylen, 30411fa71b9SJerome Forissier const unsigned char *iv_enc, const unsigned char *iv_dec, 30511fa71b9SJerome Forissier size_t ivlen, 30611fa71b9SJerome Forissier const unsigned char *mac_enc, const unsigned char *mac_dec, 30711fa71b9SJerome Forissier size_t maclen ) = NULL; 30811fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; 30911fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; 31011fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; 31111fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; 31211fa71b9SJerome Forissier int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; 31311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 31411fa71b9SJerome Forissier 31511fa71b9SJerome Forissier /* 31611fa71b9SJerome Forissier * Encryption/decryption functions 31711fa71b9SJerome Forissier */ 31811fa71b9SJerome Forissier 319*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \ 320*7901324dSJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 321*7901324dSJerome Forissier 322*7901324dSJerome Forissier static size_t ssl_compute_padding_length( size_t len, 323*7901324dSJerome Forissier size_t granularity ) 324*7901324dSJerome Forissier { 325*7901324dSJerome Forissier return( ( granularity - ( len + 1 ) % granularity ) % granularity ); 326*7901324dSJerome Forissier } 327*7901324dSJerome Forissier 328*7901324dSJerome Forissier /* This functions transforms a (D)TLS plaintext fragment and a record content 329*7901324dSJerome Forissier * type into an instance of the (D)TLSInnerPlaintext structure. This is used 330*7901324dSJerome Forissier * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect 331*7901324dSJerome Forissier * a record's content type. 33211fa71b9SJerome Forissier * 33311fa71b9SJerome Forissier * struct { 33411fa71b9SJerome Forissier * opaque content[DTLSPlaintext.length]; 33511fa71b9SJerome Forissier * ContentType real_type; 33611fa71b9SJerome Forissier * uint8 zeros[length_of_padding]; 337*7901324dSJerome Forissier * } (D)TLSInnerPlaintext; 33811fa71b9SJerome Forissier * 33911fa71b9SJerome Forissier * Input: 34011fa71b9SJerome Forissier * - `content`: The beginning of the buffer holding the 34111fa71b9SJerome Forissier * plaintext to be wrapped. 34211fa71b9SJerome Forissier * - `*content_size`: The length of the plaintext in Bytes. 34311fa71b9SJerome Forissier * - `max_len`: The number of Bytes available starting from 34411fa71b9SJerome Forissier * `content`. This must be `>= *content_size`. 34511fa71b9SJerome Forissier * - `rec_type`: The desired record content type. 34611fa71b9SJerome Forissier * 34711fa71b9SJerome Forissier * Output: 348*7901324dSJerome Forissier * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure. 349*7901324dSJerome Forissier * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure. 35011fa71b9SJerome Forissier * 35111fa71b9SJerome Forissier * Returns: 35211fa71b9SJerome Forissier * - `0` on success. 35311fa71b9SJerome Forissier * - A negative error code if `max_len` didn't offer enough space 35411fa71b9SJerome Forissier * for the expansion. 35511fa71b9SJerome Forissier */ 356*7901324dSJerome Forissier static int ssl_build_inner_plaintext( unsigned char *content, 35711fa71b9SJerome Forissier size_t *content_size, 35811fa71b9SJerome Forissier size_t remaining, 359*7901324dSJerome Forissier uint8_t rec_type, 360*7901324dSJerome Forissier size_t pad ) 36111fa71b9SJerome Forissier { 36211fa71b9SJerome Forissier size_t len = *content_size; 36311fa71b9SJerome Forissier 36411fa71b9SJerome Forissier /* Write real content type */ 36511fa71b9SJerome Forissier if( remaining == 0 ) 36611fa71b9SJerome Forissier return( -1 ); 36711fa71b9SJerome Forissier content[ len ] = rec_type; 36811fa71b9SJerome Forissier len++; 36911fa71b9SJerome Forissier remaining--; 37011fa71b9SJerome Forissier 37111fa71b9SJerome Forissier if( remaining < pad ) 37211fa71b9SJerome Forissier return( -1 ); 37311fa71b9SJerome Forissier memset( content + len, 0, pad ); 37411fa71b9SJerome Forissier len += pad; 37511fa71b9SJerome Forissier remaining -= pad; 37611fa71b9SJerome Forissier 37711fa71b9SJerome Forissier *content_size = len; 37811fa71b9SJerome Forissier return( 0 ); 37911fa71b9SJerome Forissier } 38011fa71b9SJerome Forissier 381*7901324dSJerome Forissier /* This function parses a (D)TLSInnerPlaintext structure. 382*7901324dSJerome Forissier * See ssl_build_inner_plaintext() for details. */ 383*7901324dSJerome Forissier static int ssl_parse_inner_plaintext( unsigned char const *content, 38411fa71b9SJerome Forissier size_t *content_size, 38511fa71b9SJerome Forissier uint8_t *rec_type ) 38611fa71b9SJerome Forissier { 38711fa71b9SJerome Forissier size_t remaining = *content_size; 38811fa71b9SJerome Forissier 38911fa71b9SJerome Forissier /* Determine length of padding by skipping zeroes from the back. */ 39011fa71b9SJerome Forissier do 39111fa71b9SJerome Forissier { 39211fa71b9SJerome Forissier if( remaining == 0 ) 39311fa71b9SJerome Forissier return( -1 ); 39411fa71b9SJerome Forissier remaining--; 39511fa71b9SJerome Forissier } while( content[ remaining ] == 0 ); 39611fa71b9SJerome Forissier 39711fa71b9SJerome Forissier *content_size = remaining; 39811fa71b9SJerome Forissier *rec_type = content[ remaining ]; 39911fa71b9SJerome Forissier 40011fa71b9SJerome Forissier return( 0 ); 40111fa71b9SJerome Forissier } 402*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || 403*7901324dSJerome Forissier MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 40411fa71b9SJerome Forissier 40511fa71b9SJerome Forissier /* `add_data` must have size 13 Bytes if the CID extension is disabled, 40611fa71b9SJerome Forissier * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */ 40711fa71b9SJerome Forissier static void ssl_extract_add_data_from_record( unsigned char* add_data, 40811fa71b9SJerome Forissier size_t *add_data_len, 409*7901324dSJerome Forissier mbedtls_record *rec, 410*7901324dSJerome Forissier unsigned minor_ver ) 41111fa71b9SJerome Forissier { 41211fa71b9SJerome Forissier /* Quoting RFC 5246 (TLS 1.2): 41311fa71b9SJerome Forissier * 41411fa71b9SJerome Forissier * additional_data = seq_num + TLSCompressed.type + 41511fa71b9SJerome Forissier * TLSCompressed.version + TLSCompressed.length; 41611fa71b9SJerome Forissier * 41711fa71b9SJerome Forissier * For the CID extension, this is extended as follows 41811fa71b9SJerome Forissier * (quoting draft-ietf-tls-dtls-connection-id-05, 41911fa71b9SJerome Forissier * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05): 42011fa71b9SJerome Forissier * 42111fa71b9SJerome Forissier * additional_data = seq_num + DTLSPlaintext.type + 42211fa71b9SJerome Forissier * DTLSPlaintext.version + 42311fa71b9SJerome Forissier * cid + 42411fa71b9SJerome Forissier * cid_length + 42511fa71b9SJerome Forissier * length_of_DTLSInnerPlaintext; 426*7901324dSJerome Forissier * 427*7901324dSJerome Forissier * For TLS 1.3, the record sequence number is dropped from the AAD 428*7901324dSJerome Forissier * and encoded within the nonce of the AEAD operation instead. 42911fa71b9SJerome Forissier */ 43011fa71b9SJerome Forissier 431*7901324dSJerome Forissier unsigned char *cur = add_data; 432*7901324dSJerome Forissier 433*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 434*7901324dSJerome Forissier if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 ) 435*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 436*7901324dSJerome Forissier { 437*7901324dSJerome Forissier ((void) minor_ver); 438*7901324dSJerome Forissier memcpy( cur, rec->ctr, sizeof( rec->ctr ) ); 439*7901324dSJerome Forissier cur += sizeof( rec->ctr ); 440*7901324dSJerome Forissier } 441*7901324dSJerome Forissier 442*7901324dSJerome Forissier *cur = rec->type; 443*7901324dSJerome Forissier cur++; 444*7901324dSJerome Forissier 445*7901324dSJerome Forissier memcpy( cur, rec->ver, sizeof( rec->ver ) ); 446*7901324dSJerome Forissier cur += sizeof( rec->ver ); 44711fa71b9SJerome Forissier 44811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 44911fa71b9SJerome Forissier if( rec->cid_len != 0 ) 45011fa71b9SJerome Forissier { 451*7901324dSJerome Forissier memcpy( cur, rec->cid, rec->cid_len ); 452*7901324dSJerome Forissier cur += rec->cid_len; 453*7901324dSJerome Forissier 454*7901324dSJerome Forissier *cur = rec->cid_len; 455*7901324dSJerome Forissier cur++; 456*7901324dSJerome Forissier 457*7901324dSJerome Forissier cur[0] = ( rec->data_len >> 8 ) & 0xFF; 458*7901324dSJerome Forissier cur[1] = ( rec->data_len >> 0 ) & 0xFF; 459*7901324dSJerome Forissier cur += 2; 46011fa71b9SJerome Forissier } 46111fa71b9SJerome Forissier else 46211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 46311fa71b9SJerome Forissier { 464*7901324dSJerome Forissier cur[0] = ( rec->data_len >> 8 ) & 0xFF; 465*7901324dSJerome Forissier cur[1] = ( rec->data_len >> 0 ) & 0xFF; 466*7901324dSJerome Forissier cur += 2; 46711fa71b9SJerome Forissier } 468*7901324dSJerome Forissier 469*7901324dSJerome Forissier *add_data_len = cur - add_data; 47011fa71b9SJerome Forissier } 47111fa71b9SJerome Forissier 47211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 47311fa71b9SJerome Forissier 47411fa71b9SJerome Forissier #define SSL3_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */ 47511fa71b9SJerome Forissier 47611fa71b9SJerome Forissier /* 47711fa71b9SJerome Forissier * SSLv3.0 MAC functions 47811fa71b9SJerome Forissier */ 47911fa71b9SJerome Forissier static void ssl_mac( mbedtls_md_context_t *md_ctx, 48011fa71b9SJerome Forissier const unsigned char *secret, 48111fa71b9SJerome Forissier const unsigned char *buf, size_t len, 48211fa71b9SJerome Forissier const unsigned char *ctr, int type, 48311fa71b9SJerome Forissier unsigned char out[SSL3_MAC_MAX_BYTES] ) 48411fa71b9SJerome Forissier { 48511fa71b9SJerome Forissier unsigned char header[11]; 48611fa71b9SJerome Forissier unsigned char padding[48]; 48711fa71b9SJerome Forissier int padlen; 48811fa71b9SJerome Forissier int md_size = mbedtls_md_get_size( md_ctx->md_info ); 48911fa71b9SJerome Forissier int md_type = mbedtls_md_get_type( md_ctx->md_info ); 49011fa71b9SJerome Forissier 49111fa71b9SJerome Forissier /* Only MD5 and SHA-1 supported */ 49211fa71b9SJerome Forissier if( md_type == MBEDTLS_MD_MD5 ) 49311fa71b9SJerome Forissier padlen = 48; 49411fa71b9SJerome Forissier else 49511fa71b9SJerome Forissier padlen = 40; 49611fa71b9SJerome Forissier 49711fa71b9SJerome Forissier memcpy( header, ctr, 8 ); 49811fa71b9SJerome Forissier header[ 8] = (unsigned char) type; 49911fa71b9SJerome Forissier header[ 9] = (unsigned char)( len >> 8 ); 50011fa71b9SJerome Forissier header[10] = (unsigned char)( len ); 50111fa71b9SJerome Forissier 50211fa71b9SJerome Forissier memset( padding, 0x36, padlen ); 50311fa71b9SJerome Forissier mbedtls_md_starts( md_ctx ); 50411fa71b9SJerome Forissier mbedtls_md_update( md_ctx, secret, md_size ); 50511fa71b9SJerome Forissier mbedtls_md_update( md_ctx, padding, padlen ); 50611fa71b9SJerome Forissier mbedtls_md_update( md_ctx, header, 11 ); 50711fa71b9SJerome Forissier mbedtls_md_update( md_ctx, buf, len ); 50811fa71b9SJerome Forissier mbedtls_md_finish( md_ctx, out ); 50911fa71b9SJerome Forissier 51011fa71b9SJerome Forissier memset( padding, 0x5C, padlen ); 51111fa71b9SJerome Forissier mbedtls_md_starts( md_ctx ); 51211fa71b9SJerome Forissier mbedtls_md_update( md_ctx, secret, md_size ); 51311fa71b9SJerome Forissier mbedtls_md_update( md_ctx, padding, padlen ); 51411fa71b9SJerome Forissier mbedtls_md_update( md_ctx, out, md_size ); 51511fa71b9SJerome Forissier mbedtls_md_finish( md_ctx, out ); 51611fa71b9SJerome Forissier } 51711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 51811fa71b9SJerome Forissier 519*7901324dSJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 520*7901324dSJerome Forissier defined(MBEDTLS_CCM_C) || \ 521*7901324dSJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 522*7901324dSJerome Forissier static int ssl_transform_aead_dynamic_iv_is_explicit( 523*7901324dSJerome Forissier mbedtls_ssl_transform const *transform ) 524*7901324dSJerome Forissier { 525*7901324dSJerome Forissier return( transform->ivlen != transform->fixed_ivlen ); 526*7901324dSJerome Forissier } 527*7901324dSJerome Forissier 528*7901324dSJerome Forissier /* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV ) 529*7901324dSJerome Forissier * 530*7901324dSJerome Forissier * Concretely, this occurs in two variants: 531*7901324dSJerome Forissier * 532*7901324dSJerome Forissier * a) Fixed and dynamic IV lengths add up to total IV length, giving 533*7901324dSJerome Forissier * IV = fixed_iv || dynamic_iv 534*7901324dSJerome Forissier * 535*7901324dSJerome Forissier * This variant is used in TLS 1.2 when used with GCM or CCM. 536*7901324dSJerome Forissier * 537*7901324dSJerome Forissier * b) Fixed IV lengths matches total IV length, giving 538*7901324dSJerome Forissier * IV = fixed_iv XOR ( 0 || dynamic_iv ) 539*7901324dSJerome Forissier * 540*7901324dSJerome Forissier * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly. 541*7901324dSJerome Forissier * 542*7901324dSJerome Forissier * See also the documentation of mbedtls_ssl_transform. 543*7901324dSJerome Forissier * 544*7901324dSJerome Forissier * This function has the precondition that 545*7901324dSJerome Forissier * 546*7901324dSJerome Forissier * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len ) 547*7901324dSJerome Forissier * 548*7901324dSJerome Forissier * which has to be ensured by the caller. If this precondition 549*7901324dSJerome Forissier * violated, the behavior of this function is undefined. 550*7901324dSJerome Forissier */ 551*7901324dSJerome Forissier static void ssl_build_record_nonce( unsigned char *dst_iv, 552*7901324dSJerome Forissier size_t dst_iv_len, 553*7901324dSJerome Forissier unsigned char const *fixed_iv, 554*7901324dSJerome Forissier size_t fixed_iv_len, 555*7901324dSJerome Forissier unsigned char const *dynamic_iv, 556*7901324dSJerome Forissier size_t dynamic_iv_len ) 557*7901324dSJerome Forissier { 558*7901324dSJerome Forissier size_t i; 559*7901324dSJerome Forissier 560*7901324dSJerome Forissier /* Start with Fixed IV || 0 */ 561*7901324dSJerome Forissier memset( dst_iv, 0, dst_iv_len ); 562*7901324dSJerome Forissier memcpy( dst_iv, fixed_iv, fixed_iv_len ); 563*7901324dSJerome Forissier 564*7901324dSJerome Forissier dst_iv += dst_iv_len - dynamic_iv_len; 565*7901324dSJerome Forissier for( i = 0; i < dynamic_iv_len; i++ ) 566*7901324dSJerome Forissier dst_iv[i] ^= dynamic_iv[i]; 567*7901324dSJerome Forissier } 568*7901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 569*7901324dSJerome Forissier 57011fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, 57111fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 57211fa71b9SJerome Forissier mbedtls_record *rec, 57311fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t), 57411fa71b9SJerome Forissier void *p_rng ) 57511fa71b9SJerome Forissier { 57611fa71b9SJerome Forissier mbedtls_cipher_mode_t mode; 57711fa71b9SJerome Forissier int auth_done = 0; 57811fa71b9SJerome Forissier unsigned char * data; 57911fa71b9SJerome Forissier unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ]; 58011fa71b9SJerome Forissier size_t add_data_len; 58111fa71b9SJerome Forissier size_t post_avail; 58211fa71b9SJerome Forissier 58311fa71b9SJerome Forissier /* The SSL context is only used for debugging purposes! */ 58411fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 58511fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 58611fa71b9SJerome Forissier ((void) ssl); 58711fa71b9SJerome Forissier #endif 58811fa71b9SJerome Forissier 58911fa71b9SJerome Forissier /* The PRNG is used for dynamic IV generation that's used 59011fa71b9SJerome Forissier * for CBC transformations in TLS 1.1 and TLS 1.2. */ 591*7901324dSJerome Forissier #if !( defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \ 59211fa71b9SJerome Forissier ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) ) 59311fa71b9SJerome Forissier ((void) f_rng); 59411fa71b9SJerome Forissier ((void) p_rng); 59511fa71b9SJerome Forissier #endif 59611fa71b9SJerome Forissier 59711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); 59811fa71b9SJerome Forissier 59911fa71b9SJerome Forissier if( transform == NULL ) 60011fa71b9SJerome Forissier { 60111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) ); 60211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 60311fa71b9SJerome Forissier } 60411fa71b9SJerome Forissier if( rec == NULL 60511fa71b9SJerome Forissier || rec->buf == NULL 60611fa71b9SJerome Forissier || rec->buf_len < rec->data_offset 60711fa71b9SJerome Forissier || rec->buf_len - rec->data_offset < rec->data_len 60811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 60911fa71b9SJerome Forissier || rec->cid_len != 0 61011fa71b9SJerome Forissier #endif 61111fa71b9SJerome Forissier ) 61211fa71b9SJerome Forissier { 61311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) ); 61411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 61511fa71b9SJerome Forissier } 61611fa71b9SJerome Forissier 61711fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 61811fa71b9SJerome Forissier post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); 61911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", 62011fa71b9SJerome Forissier data, rec->data_len ); 62111fa71b9SJerome Forissier 62211fa71b9SJerome Forissier mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ); 62311fa71b9SJerome Forissier 62411fa71b9SJerome Forissier if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) 62511fa71b9SJerome Forissier { 626*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %" MBEDTLS_PRINTF_SIZET 627*7901324dSJerome Forissier " too large, maximum %" MBEDTLS_PRINTF_SIZET, 628*7901324dSJerome Forissier rec->data_len, 629*7901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); 63011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 63111fa71b9SJerome Forissier } 63211fa71b9SJerome Forissier 633*7901324dSJerome Forissier /* The following two code paths implement the (D)TLSInnerPlaintext 634*7901324dSJerome Forissier * structure present in TLS 1.3 and DTLS 1.2 + CID. 635*7901324dSJerome Forissier * 636*7901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 637*7901324dSJerome Forissier * 638*7901324dSJerome Forissier * Note that this changes `rec->data_len`, and hence 639*7901324dSJerome Forissier * `post_avail` needs to be recalculated afterwards. 640*7901324dSJerome Forissier * 641*7901324dSJerome Forissier * Note also that the two code paths cannot occur simultaneously 642*7901324dSJerome Forissier * since they apply to different versions of the protocol. There 643*7901324dSJerome Forissier * is hence no risk of double-addition of the inner plaintext. 644*7901324dSJerome Forissier */ 645*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 646*7901324dSJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) 647*7901324dSJerome Forissier { 648*7901324dSJerome Forissier size_t padding = 649*7901324dSJerome Forissier ssl_compute_padding_length( rec->data_len, 650*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY ); 651*7901324dSJerome Forissier if( ssl_build_inner_plaintext( data, 652*7901324dSJerome Forissier &rec->data_len, 653*7901324dSJerome Forissier post_avail, 654*7901324dSJerome Forissier rec->type, 655*7901324dSJerome Forissier padding ) != 0 ) 656*7901324dSJerome Forissier { 657*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 658*7901324dSJerome Forissier } 659*7901324dSJerome Forissier 660*7901324dSJerome Forissier rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA; 661*7901324dSJerome Forissier } 662*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 663*7901324dSJerome Forissier 66411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 66511fa71b9SJerome Forissier /* 66611fa71b9SJerome Forissier * Add CID information 66711fa71b9SJerome Forissier */ 66811fa71b9SJerome Forissier rec->cid_len = transform->out_cid_len; 66911fa71b9SJerome Forissier memcpy( rec->cid, transform->out_cid, transform->out_cid_len ); 67011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len ); 67111fa71b9SJerome Forissier 67211fa71b9SJerome Forissier if( rec->cid_len != 0 ) 67311fa71b9SJerome Forissier { 674*7901324dSJerome Forissier size_t padding = 675*7901324dSJerome Forissier ssl_compute_padding_length( rec->data_len, 676*7901324dSJerome Forissier MBEDTLS_SSL_CID_PADDING_GRANULARITY ); 67711fa71b9SJerome Forissier /* 67811fa71b9SJerome Forissier * Wrap plaintext into DTLSInnerPlaintext structure. 679*7901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information. 68011fa71b9SJerome Forissier * 68111fa71b9SJerome Forissier * Note that this changes `rec->data_len`, and hence 68211fa71b9SJerome Forissier * `post_avail` needs to be recalculated afterwards. 68311fa71b9SJerome Forissier */ 684*7901324dSJerome Forissier if( ssl_build_inner_plaintext( data, 68511fa71b9SJerome Forissier &rec->data_len, 68611fa71b9SJerome Forissier post_avail, 687*7901324dSJerome Forissier rec->type, 688*7901324dSJerome Forissier padding ) != 0 ) 68911fa71b9SJerome Forissier { 69011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 69111fa71b9SJerome Forissier } 69211fa71b9SJerome Forissier 69311fa71b9SJerome Forissier rec->type = MBEDTLS_SSL_MSG_CID; 69411fa71b9SJerome Forissier } 69511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 69611fa71b9SJerome Forissier 69711fa71b9SJerome Forissier post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); 69811fa71b9SJerome Forissier 69911fa71b9SJerome Forissier /* 70011fa71b9SJerome Forissier * Add MAC before if needed 70111fa71b9SJerome Forissier */ 70211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 70311fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM || 70411fa71b9SJerome Forissier ( mode == MBEDTLS_MODE_CBC 70511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 70611fa71b9SJerome Forissier && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED 70711fa71b9SJerome Forissier #endif 70811fa71b9SJerome Forissier ) ) 70911fa71b9SJerome Forissier { 71011fa71b9SJerome Forissier if( post_avail < transform->maclen ) 71111fa71b9SJerome Forissier { 71211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 71311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 71411fa71b9SJerome Forissier } 71511fa71b9SJerome Forissier 71611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 71711fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 71811fa71b9SJerome Forissier { 71911fa71b9SJerome Forissier unsigned char mac[SSL3_MAC_MAX_BYTES]; 72011fa71b9SJerome Forissier ssl_mac( &transform->md_ctx_enc, transform->mac_enc, 72111fa71b9SJerome Forissier data, rec->data_len, rec->ctr, rec->type, mac ); 72211fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 72311fa71b9SJerome Forissier } 72411fa71b9SJerome Forissier else 72511fa71b9SJerome Forissier #endif 72611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 72711fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 72811fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) 72911fa71b9SJerome Forissier { 73011fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 73111fa71b9SJerome Forissier 732*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 733*7901324dSJerome Forissier transform->minor_ver ); 73411fa71b9SJerome Forissier 73511fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, 73611fa71b9SJerome Forissier add_data_len ); 73711fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_enc, 73811fa71b9SJerome Forissier data, rec->data_len ); 73911fa71b9SJerome Forissier mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); 74011fa71b9SJerome Forissier mbedtls_md_hmac_reset( &transform->md_ctx_enc ); 74111fa71b9SJerome Forissier 74211fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 74311fa71b9SJerome Forissier } 74411fa71b9SJerome Forissier else 74511fa71b9SJerome Forissier #endif 74611fa71b9SJerome Forissier { 74711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 74811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 74911fa71b9SJerome Forissier } 75011fa71b9SJerome Forissier 75111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len, 75211fa71b9SJerome Forissier transform->maclen ); 75311fa71b9SJerome Forissier 75411fa71b9SJerome Forissier rec->data_len += transform->maclen; 75511fa71b9SJerome Forissier post_avail -= transform->maclen; 75611fa71b9SJerome Forissier auth_done++; 75711fa71b9SJerome Forissier } 75811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ 75911fa71b9SJerome Forissier 76011fa71b9SJerome Forissier /* 76111fa71b9SJerome Forissier * Encrypt 76211fa71b9SJerome Forissier */ 76311fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) 76411fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM ) 76511fa71b9SJerome Forissier { 76611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 76711fa71b9SJerome Forissier size_t olen; 768*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 76911fa71b9SJerome Forissier "including %d bytes of padding", 77011fa71b9SJerome Forissier rec->data_len, 0 ) ); 77111fa71b9SJerome Forissier 77211fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, 77311fa71b9SJerome Forissier transform->iv_enc, transform->ivlen, 77411fa71b9SJerome Forissier data, rec->data_len, 77511fa71b9SJerome Forissier data, &olen ) ) != 0 ) 77611fa71b9SJerome Forissier { 77711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 77811fa71b9SJerome Forissier return( ret ); 77911fa71b9SJerome Forissier } 78011fa71b9SJerome Forissier 78111fa71b9SJerome Forissier if( rec->data_len != olen ) 78211fa71b9SJerome Forissier { 78311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 78411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 78511fa71b9SJerome Forissier } 78611fa71b9SJerome Forissier } 78711fa71b9SJerome Forissier else 78811fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ 78911fa71b9SJerome Forissier 79011fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 79111fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 79211fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 79311fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_GCM || 79411fa71b9SJerome Forissier mode == MBEDTLS_MODE_CCM || 79511fa71b9SJerome Forissier mode == MBEDTLS_MODE_CHACHAPOLY ) 79611fa71b9SJerome Forissier { 79711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 79811fa71b9SJerome Forissier unsigned char iv[12]; 799*7901324dSJerome Forissier unsigned char *dynamic_iv; 800*7901324dSJerome Forissier size_t dynamic_iv_len; 801*7901324dSJerome Forissier int dynamic_iv_is_explicit = 802*7901324dSJerome Forissier ssl_transform_aead_dynamic_iv_is_explicit( transform ); 80311fa71b9SJerome Forissier 804*7901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 805*7901324dSJerome Forissier if( post_avail < transform->taglen ) 80611fa71b9SJerome Forissier { 80711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 80811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 80911fa71b9SJerome Forissier } 81011fa71b9SJerome Forissier 81111fa71b9SJerome Forissier /* 812*7901324dSJerome Forissier * Build nonce for AEAD encryption. 813*7901324dSJerome Forissier * 814*7901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 815*7901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 816*7901324dSJerome Forissier * can be chosen freely - in particular, it need not 817*7901324dSJerome Forissier * agree with the record sequence number. 818*7901324dSJerome Forissier * However, since ChaChaPoly as well as all AEAD modes 819*7901324dSJerome Forissier * in TLS 1.3 use the record sequence number as the 820*7901324dSJerome Forissier * dynamic part of the nonce, we uniformly use the 821*7901324dSJerome Forissier * record sequence number here in all cases. 82211fa71b9SJerome Forissier */ 823*7901324dSJerome Forissier dynamic_iv = rec->ctr; 824*7901324dSJerome Forissier dynamic_iv_len = sizeof( rec->ctr ); 82511fa71b9SJerome Forissier 826*7901324dSJerome Forissier ssl_build_record_nonce( iv, sizeof( iv ), 827*7901324dSJerome Forissier transform->iv_enc, 828*7901324dSJerome Forissier transform->fixed_ivlen, 829*7901324dSJerome Forissier dynamic_iv, 830*7901324dSJerome Forissier dynamic_iv_len ); 83111fa71b9SJerome Forissier 832*7901324dSJerome Forissier /* 833*7901324dSJerome Forissier * Build additional data for AEAD encryption. 834*7901324dSJerome Forissier * This depends on the TLS version. 835*7901324dSJerome Forissier */ 836*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 837*7901324dSJerome Forissier transform->minor_ver ); 83811fa71b9SJerome Forissier 83911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", 84011fa71b9SJerome Forissier iv, transform->ivlen ); 84111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", 842*7901324dSJerome Forissier dynamic_iv, 843*7901324dSJerome Forissier dynamic_iv_is_explicit ? dynamic_iv_len : 0 ); 84411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", 84511fa71b9SJerome Forissier add_data, add_data_len ); 846*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 84711fa71b9SJerome Forissier "including 0 bytes of padding", 84811fa71b9SJerome Forissier rec->data_len ) ); 84911fa71b9SJerome Forissier 85011fa71b9SJerome Forissier /* 85111fa71b9SJerome Forissier * Encrypt and authenticate 85211fa71b9SJerome Forissier */ 85311fa71b9SJerome Forissier 854*7901324dSJerome Forissier if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc, 85511fa71b9SJerome Forissier iv, transform->ivlen, 856*7901324dSJerome Forissier add_data, add_data_len, 857*7901324dSJerome Forissier data, rec->data_len, /* src */ 858*7901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), /* dst */ 859*7901324dSJerome Forissier &rec->data_len, 860*7901324dSJerome Forissier transform->taglen ) ) != 0 ) 86111fa71b9SJerome Forissier { 86211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); 86311fa71b9SJerome Forissier return( ret ); 86411fa71b9SJerome Forissier } 86511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", 866*7901324dSJerome Forissier data + rec->data_len - transform->taglen, 867*7901324dSJerome Forissier transform->taglen ); 868*7901324dSJerome Forissier /* Account for authentication tag. */ 86911fa71b9SJerome Forissier post_avail -= transform->taglen; 870*7901324dSJerome Forissier 871*7901324dSJerome Forissier /* 872*7901324dSJerome Forissier * Prefix record content with dynamic IV in case it is explicit. 873*7901324dSJerome Forissier */ 874*7901324dSJerome Forissier if( dynamic_iv_is_explicit != 0 ) 875*7901324dSJerome Forissier { 876*7901324dSJerome Forissier if( rec->data_offset < dynamic_iv_len ) 877*7901324dSJerome Forissier { 878*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 879*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 880*7901324dSJerome Forissier } 881*7901324dSJerome Forissier 882*7901324dSJerome Forissier memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len ); 883*7901324dSJerome Forissier rec->data_offset -= dynamic_iv_len; 884*7901324dSJerome Forissier rec->data_len += dynamic_iv_len; 885*7901324dSJerome Forissier } 886*7901324dSJerome Forissier 88711fa71b9SJerome Forissier auth_done++; 88811fa71b9SJerome Forissier } 88911fa71b9SJerome Forissier else 890*7901324dSJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */ 891*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 89211fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_CBC ) 89311fa71b9SJerome Forissier { 89411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 89511fa71b9SJerome Forissier size_t padlen, i; 89611fa71b9SJerome Forissier size_t olen; 89711fa71b9SJerome Forissier 89811fa71b9SJerome Forissier /* Currently we're always using minimal padding 89911fa71b9SJerome Forissier * (up to 255 bytes would be allowed). */ 90011fa71b9SJerome Forissier padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen; 90111fa71b9SJerome Forissier if( padlen == transform->ivlen ) 90211fa71b9SJerome Forissier padlen = 0; 90311fa71b9SJerome Forissier 90411fa71b9SJerome Forissier /* Check there's enough space in the buffer for the padding. */ 90511fa71b9SJerome Forissier if( post_avail < padlen + 1 ) 90611fa71b9SJerome Forissier { 90711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 90811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 90911fa71b9SJerome Forissier } 91011fa71b9SJerome Forissier 91111fa71b9SJerome Forissier for( i = 0; i <= padlen; i++ ) 91211fa71b9SJerome Forissier data[rec->data_len + i] = (unsigned char) padlen; 91311fa71b9SJerome Forissier 91411fa71b9SJerome Forissier rec->data_len += padlen + 1; 91511fa71b9SJerome Forissier post_avail -= padlen + 1; 91611fa71b9SJerome Forissier 91711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 91811fa71b9SJerome Forissier /* 91911fa71b9SJerome Forissier * Prepend per-record IV for block cipher in TLS v1.1 and up as per 92011fa71b9SJerome Forissier * Method 1 (6.2.3.2. in RFC4346 and RFC5246) 92111fa71b9SJerome Forissier */ 92211fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 92311fa71b9SJerome Forissier { 92411fa71b9SJerome Forissier if( f_rng == NULL ) 92511fa71b9SJerome Forissier { 92611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) ); 92711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 92811fa71b9SJerome Forissier } 92911fa71b9SJerome Forissier 93011fa71b9SJerome Forissier if( rec->data_offset < transform->ivlen ) 93111fa71b9SJerome Forissier { 93211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 93311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 93411fa71b9SJerome Forissier } 93511fa71b9SJerome Forissier 93611fa71b9SJerome Forissier /* 93711fa71b9SJerome Forissier * Generate IV 93811fa71b9SJerome Forissier */ 93911fa71b9SJerome Forissier ret = f_rng( p_rng, transform->iv_enc, transform->ivlen ); 94011fa71b9SJerome Forissier if( ret != 0 ) 94111fa71b9SJerome Forissier return( ret ); 94211fa71b9SJerome Forissier 94311fa71b9SJerome Forissier memcpy( data - transform->ivlen, transform->iv_enc, 94411fa71b9SJerome Forissier transform->ivlen ); 94511fa71b9SJerome Forissier 94611fa71b9SJerome Forissier } 94711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 94811fa71b9SJerome Forissier 949*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", " 950*7901324dSJerome Forissier "including %" MBEDTLS_PRINTF_SIZET 951*7901324dSJerome Forissier " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding", 95211fa71b9SJerome Forissier rec->data_len, transform->ivlen, 95311fa71b9SJerome Forissier padlen + 1 ) ); 95411fa71b9SJerome Forissier 95511fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc, 95611fa71b9SJerome Forissier transform->iv_enc, 95711fa71b9SJerome Forissier transform->ivlen, 95811fa71b9SJerome Forissier data, rec->data_len, 95911fa71b9SJerome Forissier data, &olen ) ) != 0 ) 96011fa71b9SJerome Forissier { 96111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 96211fa71b9SJerome Forissier return( ret ); 96311fa71b9SJerome Forissier } 96411fa71b9SJerome Forissier 96511fa71b9SJerome Forissier if( rec->data_len != olen ) 96611fa71b9SJerome Forissier { 96711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 96811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 96911fa71b9SJerome Forissier } 97011fa71b9SJerome Forissier 97111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) 97211fa71b9SJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 97311fa71b9SJerome Forissier { 97411fa71b9SJerome Forissier /* 97511fa71b9SJerome Forissier * Save IV in SSL3 and TLS1 97611fa71b9SJerome Forissier */ 97711fa71b9SJerome Forissier memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv, 97811fa71b9SJerome Forissier transform->ivlen ); 97911fa71b9SJerome Forissier } 98011fa71b9SJerome Forissier else 98111fa71b9SJerome Forissier #endif 98211fa71b9SJerome Forissier { 98311fa71b9SJerome Forissier data -= transform->ivlen; 98411fa71b9SJerome Forissier rec->data_offset -= transform->ivlen; 98511fa71b9SJerome Forissier rec->data_len += transform->ivlen; 98611fa71b9SJerome Forissier } 98711fa71b9SJerome Forissier 98811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 98911fa71b9SJerome Forissier if( auth_done == 0 ) 99011fa71b9SJerome Forissier { 99111fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD]; 99211fa71b9SJerome Forissier 99311fa71b9SJerome Forissier /* 99411fa71b9SJerome Forissier * MAC(MAC_write_key, seq_num + 99511fa71b9SJerome Forissier * TLSCipherText.type + 99611fa71b9SJerome Forissier * TLSCipherText.version + 99711fa71b9SJerome Forissier * length_of( (IV +) ENC(...) ) + 99811fa71b9SJerome Forissier * IV + // except for TLS 1.0 99911fa71b9SJerome Forissier * ENC(content + padding + padding_length)); 100011fa71b9SJerome Forissier */ 100111fa71b9SJerome Forissier 100211fa71b9SJerome Forissier if( post_avail < transform->maclen) 100311fa71b9SJerome Forissier { 100411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) ); 100511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 100611fa71b9SJerome Forissier } 100711fa71b9SJerome Forissier 1008*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, 1009*7901324dSJerome Forissier rec, transform->minor_ver ); 101011fa71b9SJerome Forissier 101111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); 101211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, 101311fa71b9SJerome Forissier add_data_len ); 101411fa71b9SJerome Forissier 101511fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, 101611fa71b9SJerome Forissier add_data_len ); 101711fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_enc, 101811fa71b9SJerome Forissier data, rec->data_len ); 101911fa71b9SJerome Forissier mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); 102011fa71b9SJerome Forissier mbedtls_md_hmac_reset( &transform->md_ctx_enc ); 102111fa71b9SJerome Forissier 102211fa71b9SJerome Forissier memcpy( data + rec->data_len, mac, transform->maclen ); 102311fa71b9SJerome Forissier 102411fa71b9SJerome Forissier rec->data_len += transform->maclen; 102511fa71b9SJerome Forissier post_avail -= transform->maclen; 102611fa71b9SJerome Forissier auth_done++; 102711fa71b9SJerome Forissier } 102811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 102911fa71b9SJerome Forissier } 103011fa71b9SJerome Forissier else 1031*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */ 103211fa71b9SJerome Forissier { 103311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 103411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 103511fa71b9SJerome Forissier } 103611fa71b9SJerome Forissier 103711fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 103811fa71b9SJerome Forissier if( auth_done != 1 ) 103911fa71b9SJerome Forissier { 104011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 104111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 104211fa71b9SJerome Forissier } 104311fa71b9SJerome Forissier 104411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); 104511fa71b9SJerome Forissier 104611fa71b9SJerome Forissier return( 0 ); 104711fa71b9SJerome Forissier } 104811fa71b9SJerome Forissier 1049*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) 1050*7901324dSJerome Forissier /* 1051*7901324dSJerome Forissier * Turn a bit into a mask: 1052*7901324dSJerome Forissier * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1 1053*7901324dSJerome Forissier * - if bit == 0, return the all-bits 0 mask, aka 0 1054*7901324dSJerome Forissier * 1055*7901324dSJerome Forissier * This function can be used to write constant-time code by replacing branches 1056*7901324dSJerome Forissier * with bit operations using masks. 1057*7901324dSJerome Forissier * 1058*7901324dSJerome Forissier * This function is implemented without using comparison operators, as those 1059*7901324dSJerome Forissier * might be translated to branches by some compilers on some platforms. 1060*7901324dSJerome Forissier */ 1061*7901324dSJerome Forissier static size_t mbedtls_ssl_cf_mask_from_bit( size_t bit ) 1062*7901324dSJerome Forissier { 1063*7901324dSJerome Forissier /* MSVC has a warning about unary minus on unsigned integer types, 1064*7901324dSJerome Forissier * but this is well-defined and precisely what we want to do here. */ 1065*7901324dSJerome Forissier #if defined(_MSC_VER) 1066*7901324dSJerome Forissier #pragma warning( push ) 1067*7901324dSJerome Forissier #pragma warning( disable : 4146 ) 1068*7901324dSJerome Forissier #endif 1069*7901324dSJerome Forissier return -bit; 1070*7901324dSJerome Forissier #if defined(_MSC_VER) 1071*7901324dSJerome Forissier #pragma warning( pop ) 1072*7901324dSJerome Forissier #endif 1073*7901324dSJerome Forissier } 1074*7901324dSJerome Forissier 1075*7901324dSJerome Forissier /* 1076*7901324dSJerome Forissier * Constant-flow mask generation for "less than" comparison: 1077*7901324dSJerome Forissier * - if x < y, return all bits 1, that is (size_t) -1 1078*7901324dSJerome Forissier * - otherwise, return all bits 0, that is 0 1079*7901324dSJerome Forissier * 1080*7901324dSJerome Forissier * This function can be used to write constant-time code by replacing branches 1081*7901324dSJerome Forissier * with bit operations using masks. 1082*7901324dSJerome Forissier * 1083*7901324dSJerome Forissier * This function is implemented without using comparison operators, as those 1084*7901324dSJerome Forissier * might be translated to branches by some compilers on some platforms. 1085*7901324dSJerome Forissier */ 1086*7901324dSJerome Forissier static size_t mbedtls_ssl_cf_mask_lt( size_t x, size_t y ) 1087*7901324dSJerome Forissier { 1088*7901324dSJerome Forissier /* This has the most significant bit set if and only if x < y */ 1089*7901324dSJerome Forissier const size_t sub = x - y; 1090*7901324dSJerome Forissier 1091*7901324dSJerome Forissier /* sub1 = (x < y) ? 1 : 0 */ 1092*7901324dSJerome Forissier const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 ); 1093*7901324dSJerome Forissier 1094*7901324dSJerome Forissier /* mask = (x < y) ? 0xff... : 0x00... */ 1095*7901324dSJerome Forissier const size_t mask = mbedtls_ssl_cf_mask_from_bit( sub1 ); 1096*7901324dSJerome Forissier 1097*7901324dSJerome Forissier return( mask ); 1098*7901324dSJerome Forissier } 1099*7901324dSJerome Forissier 1100*7901324dSJerome Forissier /* 1101*7901324dSJerome Forissier * Constant-flow mask generation for "greater or equal" comparison: 1102*7901324dSJerome Forissier * - if x >= y, return all bits 1, that is (size_t) -1 1103*7901324dSJerome Forissier * - otherwise, return all bits 0, that is 0 1104*7901324dSJerome Forissier * 1105*7901324dSJerome Forissier * This function can be used to write constant-time code by replacing branches 1106*7901324dSJerome Forissier * with bit operations using masks. 1107*7901324dSJerome Forissier * 1108*7901324dSJerome Forissier * This function is implemented without using comparison operators, as those 1109*7901324dSJerome Forissier * might be translated to branches by some compilers on some platforms. 1110*7901324dSJerome Forissier */ 1111*7901324dSJerome Forissier static size_t mbedtls_ssl_cf_mask_ge( size_t x, size_t y ) 1112*7901324dSJerome Forissier { 1113*7901324dSJerome Forissier return( ~mbedtls_ssl_cf_mask_lt( x, y ) ); 1114*7901324dSJerome Forissier } 1115*7901324dSJerome Forissier 1116*7901324dSJerome Forissier /* 1117*7901324dSJerome Forissier * Constant-flow boolean "equal" comparison: 1118*7901324dSJerome Forissier * return x == y 1119*7901324dSJerome Forissier * 1120*7901324dSJerome Forissier * This function can be used to write constant-time code by replacing branches 1121*7901324dSJerome Forissier * with bit operations - it can be used in conjunction with 1122*7901324dSJerome Forissier * mbedtls_ssl_cf_mask_from_bit(). 1123*7901324dSJerome Forissier * 1124*7901324dSJerome Forissier * This function is implemented without using comparison operators, as those 1125*7901324dSJerome Forissier * might be translated to branches by some compilers on some platforms. 1126*7901324dSJerome Forissier */ 1127*7901324dSJerome Forissier static size_t mbedtls_ssl_cf_bool_eq( size_t x, size_t y ) 1128*7901324dSJerome Forissier { 1129*7901324dSJerome Forissier /* diff = 0 if x == y, non-zero otherwise */ 1130*7901324dSJerome Forissier const size_t diff = x ^ y; 1131*7901324dSJerome Forissier 1132*7901324dSJerome Forissier /* MSVC has a warning about unary minus on unsigned integer types, 1133*7901324dSJerome Forissier * but this is well-defined and precisely what we want to do here. */ 1134*7901324dSJerome Forissier #if defined(_MSC_VER) 1135*7901324dSJerome Forissier #pragma warning( push ) 1136*7901324dSJerome Forissier #pragma warning( disable : 4146 ) 1137*7901324dSJerome Forissier #endif 1138*7901324dSJerome Forissier 1139*7901324dSJerome Forissier /* diff_msb's most significant bit is equal to x != y */ 1140*7901324dSJerome Forissier const size_t diff_msb = ( diff | -diff ); 1141*7901324dSJerome Forissier 1142*7901324dSJerome Forissier #if defined(_MSC_VER) 1143*7901324dSJerome Forissier #pragma warning( pop ) 1144*7901324dSJerome Forissier #endif 1145*7901324dSJerome Forissier 1146*7901324dSJerome Forissier /* diff1 = (x != y) ? 1 : 0 */ 1147*7901324dSJerome Forissier const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 ); 1148*7901324dSJerome Forissier 1149*7901324dSJerome Forissier return( 1 ^ diff1 ); 1150*7901324dSJerome Forissier } 1151*7901324dSJerome Forissier 1152*7901324dSJerome Forissier /* 1153*7901324dSJerome Forissier * Constant-flow conditional memcpy: 1154*7901324dSJerome Forissier * - if c1 == c2, equivalent to memcpy(dst, src, len), 1155*7901324dSJerome Forissier * - otherwise, a no-op, 1156*7901324dSJerome Forissier * but with execution flow independent of the values of c1 and c2. 1157*7901324dSJerome Forissier * 1158*7901324dSJerome Forissier * This function is implemented without using comparison operators, as those 1159*7901324dSJerome Forissier * might be translated to branches by some compilers on some platforms. 1160*7901324dSJerome Forissier */ 1161*7901324dSJerome Forissier static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst, 1162*7901324dSJerome Forissier const unsigned char *src, 1163*7901324dSJerome Forissier size_t len, 1164*7901324dSJerome Forissier size_t c1, size_t c2 ) 1165*7901324dSJerome Forissier { 1166*7901324dSJerome Forissier /* mask = c1 == c2 ? 0xff : 0x00 */ 1167*7901324dSJerome Forissier const size_t equal = mbedtls_ssl_cf_bool_eq( c1, c2 ); 1168*7901324dSJerome Forissier const unsigned char mask = (unsigned char) mbedtls_ssl_cf_mask_from_bit( equal ); 1169*7901324dSJerome Forissier 1170*7901324dSJerome Forissier /* dst[i] = c1 == c2 ? src[i] : dst[i] */ 1171*7901324dSJerome Forissier for( size_t i = 0; i < len; i++ ) 1172*7901324dSJerome Forissier dst[i] = ( src[i] & mask ) | ( dst[i] & ~mask ); 1173*7901324dSJerome Forissier } 1174*7901324dSJerome Forissier 1175*7901324dSJerome Forissier /* 1176*7901324dSJerome Forissier * Compute HMAC of variable-length data with constant flow. 1177*7901324dSJerome Forissier * 1178*7901324dSJerome Forissier * Only works with MD-5, SHA-1, SHA-256 and SHA-384. 1179*7901324dSJerome Forissier * (Otherwise, computation of block_size needs to be adapted.) 1180*7901324dSJerome Forissier */ 1181*7901324dSJerome Forissier MBEDTLS_STATIC_TESTABLE int mbedtls_ssl_cf_hmac( 1182*7901324dSJerome Forissier mbedtls_md_context_t *ctx, 1183*7901324dSJerome Forissier const unsigned char *add_data, size_t add_data_len, 1184*7901324dSJerome Forissier const unsigned char *data, size_t data_len_secret, 1185*7901324dSJerome Forissier size_t min_data_len, size_t max_data_len, 1186*7901324dSJerome Forissier unsigned char *output ) 1187*7901324dSJerome Forissier { 1188*7901324dSJerome Forissier /* 1189*7901324dSJerome Forissier * This function breaks the HMAC abstraction and uses the md_clone() 1190*7901324dSJerome Forissier * extension to the MD API in order to get constant-flow behaviour. 1191*7901324dSJerome Forissier * 1192*7901324dSJerome Forissier * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means 1193*7901324dSJerome Forissier * concatenation, and okey/ikey are the XOR of the key with some fixed bit 1194*7901324dSJerome Forissier * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx. 1195*7901324dSJerome Forissier * 1196*7901324dSJerome Forissier * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to 1197*7901324dSJerome Forissier * minlen, then cloning the context, and for each byte up to maxlen 1198*7901324dSJerome Forissier * finishing up the hash computation, keeping only the correct result. 1199*7901324dSJerome Forissier * 1200*7901324dSJerome Forissier * Then we only need to compute HASH(okey + inner_hash) and we're done. 1201*7901324dSJerome Forissier */ 1202*7901324dSJerome Forissier const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info ); 1203*7901324dSJerome Forissier /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5, 1204*7901324dSJerome Forissier * all of which have the same block size except SHA-384. */ 1205*7901324dSJerome Forissier const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64; 1206*7901324dSJerome Forissier const unsigned char * const ikey = ctx->hmac_ctx; 1207*7901324dSJerome Forissier const unsigned char * const okey = ikey + block_size; 1208*7901324dSJerome Forissier const size_t hash_size = mbedtls_md_get_size( ctx->md_info ); 1209*7901324dSJerome Forissier 1210*7901324dSJerome Forissier unsigned char aux_out[MBEDTLS_MD_MAX_SIZE]; 1211*7901324dSJerome Forissier mbedtls_md_context_t aux; 1212*7901324dSJerome Forissier size_t offset; 1213*7901324dSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1214*7901324dSJerome Forissier 1215*7901324dSJerome Forissier mbedtls_md_init( &aux ); 1216*7901324dSJerome Forissier 1217*7901324dSJerome Forissier #define MD_CHK( func_call ) \ 1218*7901324dSJerome Forissier do { \ 1219*7901324dSJerome Forissier ret = (func_call); \ 1220*7901324dSJerome Forissier if( ret != 0 ) \ 1221*7901324dSJerome Forissier goto cleanup; \ 1222*7901324dSJerome Forissier } while( 0 ) 1223*7901324dSJerome Forissier 1224*7901324dSJerome Forissier MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) ); 1225*7901324dSJerome Forissier 1226*7901324dSJerome Forissier /* After hmac_start() of hmac_reset(), ikey has already been hashed, 1227*7901324dSJerome Forissier * so we can start directly with the message */ 1228*7901324dSJerome Forissier MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) ); 1229*7901324dSJerome Forissier MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) ); 1230*7901324dSJerome Forissier 1231*7901324dSJerome Forissier /* For each possible length, compute the hash up to that point */ 1232*7901324dSJerome Forissier for( offset = min_data_len; offset <= max_data_len; offset++ ) 1233*7901324dSJerome Forissier { 1234*7901324dSJerome Forissier MD_CHK( mbedtls_md_clone( &aux, ctx ) ); 1235*7901324dSJerome Forissier MD_CHK( mbedtls_md_finish( &aux, aux_out ) ); 1236*7901324dSJerome Forissier /* Keep only the correct inner_hash in the output buffer */ 1237*7901324dSJerome Forissier mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size, 1238*7901324dSJerome Forissier offset, data_len_secret ); 1239*7901324dSJerome Forissier 1240*7901324dSJerome Forissier if( offset < max_data_len ) 1241*7901324dSJerome Forissier MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) ); 1242*7901324dSJerome Forissier } 1243*7901324dSJerome Forissier 1244*7901324dSJerome Forissier /* The context needs to finish() before it starts() again */ 1245*7901324dSJerome Forissier MD_CHK( mbedtls_md_finish( ctx, aux_out ) ); 1246*7901324dSJerome Forissier 1247*7901324dSJerome Forissier /* Now compute HASH(okey + inner_hash) */ 1248*7901324dSJerome Forissier MD_CHK( mbedtls_md_starts( ctx ) ); 1249*7901324dSJerome Forissier MD_CHK( mbedtls_md_update( ctx, okey, block_size ) ); 1250*7901324dSJerome Forissier MD_CHK( mbedtls_md_update( ctx, output, hash_size ) ); 1251*7901324dSJerome Forissier MD_CHK( mbedtls_md_finish( ctx, output ) ); 1252*7901324dSJerome Forissier 1253*7901324dSJerome Forissier /* Done, get ready for next time */ 1254*7901324dSJerome Forissier MD_CHK( mbedtls_md_hmac_reset( ctx ) ); 1255*7901324dSJerome Forissier 1256*7901324dSJerome Forissier #undef MD_CHK 1257*7901324dSJerome Forissier 1258*7901324dSJerome Forissier cleanup: 1259*7901324dSJerome Forissier mbedtls_md_free( &aux ); 1260*7901324dSJerome Forissier return( ret ); 1261*7901324dSJerome Forissier } 1262*7901324dSJerome Forissier 1263*7901324dSJerome Forissier /* 1264*7901324dSJerome Forissier * Constant-flow memcpy from variable position in buffer. 1265*7901324dSJerome Forissier * - functionally equivalent to memcpy(dst, src + offset_secret, len) 1266*7901324dSJerome Forissier * - but with execution flow independent from the value of offset_secret. 1267*7901324dSJerome Forissier */ 1268*7901324dSJerome Forissier MBEDTLS_STATIC_TESTABLE void mbedtls_ssl_cf_memcpy_offset( 1269*7901324dSJerome Forissier unsigned char *dst, 1270*7901324dSJerome Forissier const unsigned char *src_base, 1271*7901324dSJerome Forissier size_t offset_secret, 1272*7901324dSJerome Forissier size_t offset_min, size_t offset_max, 1273*7901324dSJerome Forissier size_t len ) 1274*7901324dSJerome Forissier { 1275*7901324dSJerome Forissier size_t offset; 1276*7901324dSJerome Forissier 1277*7901324dSJerome Forissier for( offset = offset_min; offset <= offset_max; offset++ ) 1278*7901324dSJerome Forissier { 1279*7901324dSJerome Forissier mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len, 1280*7901324dSJerome Forissier offset, offset_secret ); 1281*7901324dSJerome Forissier } 1282*7901324dSJerome Forissier } 1283*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */ 1284*7901324dSJerome Forissier 128511fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl, 128611fa71b9SJerome Forissier mbedtls_ssl_transform *transform, 128711fa71b9SJerome Forissier mbedtls_record *rec ) 128811fa71b9SJerome Forissier { 128911fa71b9SJerome Forissier size_t olen; 129011fa71b9SJerome Forissier mbedtls_cipher_mode_t mode; 129111fa71b9SJerome Forissier int ret, auth_done = 0; 129211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 129311fa71b9SJerome Forissier size_t padlen = 0, correct = 1; 129411fa71b9SJerome Forissier #endif 129511fa71b9SJerome Forissier unsigned char* data; 129611fa71b9SJerome Forissier unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ]; 129711fa71b9SJerome Forissier size_t add_data_len; 129811fa71b9SJerome Forissier 129911fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C) 130011fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */ 130111fa71b9SJerome Forissier ((void) ssl); 130211fa71b9SJerome Forissier #endif 130311fa71b9SJerome Forissier 130411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); 130511fa71b9SJerome Forissier if( rec == NULL || 130611fa71b9SJerome Forissier rec->buf == NULL || 130711fa71b9SJerome Forissier rec->buf_len < rec->data_offset || 130811fa71b9SJerome Forissier rec->buf_len - rec->data_offset < rec->data_len ) 130911fa71b9SJerome Forissier { 131011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) ); 131111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 131211fa71b9SJerome Forissier } 131311fa71b9SJerome Forissier 131411fa71b9SJerome Forissier data = rec->buf + rec->data_offset; 131511fa71b9SJerome Forissier mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec ); 131611fa71b9SJerome Forissier 131711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 131811fa71b9SJerome Forissier /* 131911fa71b9SJerome Forissier * Match record's CID with incoming CID. 132011fa71b9SJerome Forissier */ 132111fa71b9SJerome Forissier if( rec->cid_len != transform->in_cid_len || 132211fa71b9SJerome Forissier memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 ) 132311fa71b9SJerome Forissier { 132411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_CID ); 132511fa71b9SJerome Forissier } 132611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 132711fa71b9SJerome Forissier 132811fa71b9SJerome Forissier #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) 132911fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_STREAM ) 133011fa71b9SJerome Forissier { 133111fa71b9SJerome Forissier padlen = 0; 133211fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, 133311fa71b9SJerome Forissier transform->iv_dec, 133411fa71b9SJerome Forissier transform->ivlen, 133511fa71b9SJerome Forissier data, rec->data_len, 133611fa71b9SJerome Forissier data, &olen ) ) != 0 ) 133711fa71b9SJerome Forissier { 133811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 133911fa71b9SJerome Forissier return( ret ); 134011fa71b9SJerome Forissier } 134111fa71b9SJerome Forissier 134211fa71b9SJerome Forissier if( rec->data_len != olen ) 134311fa71b9SJerome Forissier { 134411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 134511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 134611fa71b9SJerome Forissier } 134711fa71b9SJerome Forissier } 134811fa71b9SJerome Forissier else 134911fa71b9SJerome Forissier #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ 135011fa71b9SJerome Forissier #if defined(MBEDTLS_GCM_C) || \ 135111fa71b9SJerome Forissier defined(MBEDTLS_CCM_C) || \ 135211fa71b9SJerome Forissier defined(MBEDTLS_CHACHAPOLY_C) 135311fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_GCM || 135411fa71b9SJerome Forissier mode == MBEDTLS_MODE_CCM || 135511fa71b9SJerome Forissier mode == MBEDTLS_MODE_CHACHAPOLY ) 135611fa71b9SJerome Forissier { 135711fa71b9SJerome Forissier unsigned char iv[12]; 1358*7901324dSJerome Forissier unsigned char *dynamic_iv; 1359*7901324dSJerome Forissier size_t dynamic_iv_len; 136011fa71b9SJerome Forissier 136111fa71b9SJerome Forissier /* 1362*7901324dSJerome Forissier * Extract dynamic part of nonce for AEAD decryption. 1363*7901324dSJerome Forissier * 1364*7901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic 1365*7901324dSJerome Forissier * part of the IV is prepended to the ciphertext and 1366*7901324dSJerome Forissier * can be chosen freely - in particular, it need not 1367*7901324dSJerome Forissier * agree with the record sequence number. 136811fa71b9SJerome Forissier */ 1369*7901324dSJerome Forissier dynamic_iv_len = sizeof( rec->ctr ); 1370*7901324dSJerome Forissier if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 ) 137111fa71b9SJerome Forissier { 1372*7901324dSJerome Forissier if( rec->data_len < dynamic_iv_len ) 1373*7901324dSJerome Forissier { 1374*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 1375*7901324dSJerome Forissier " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ", 1376*7901324dSJerome Forissier rec->data_len, 1377*7901324dSJerome Forissier dynamic_iv_len ) ); 137811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 137911fa71b9SJerome Forissier } 1380*7901324dSJerome Forissier dynamic_iv = data; 138111fa71b9SJerome Forissier 1382*7901324dSJerome Forissier data += dynamic_iv_len; 1383*7901324dSJerome Forissier rec->data_offset += dynamic_iv_len; 1384*7901324dSJerome Forissier rec->data_len -= dynamic_iv_len; 138511fa71b9SJerome Forissier } 138611fa71b9SJerome Forissier else 138711fa71b9SJerome Forissier { 1388*7901324dSJerome Forissier dynamic_iv = rec->ctr; 138911fa71b9SJerome Forissier } 139011fa71b9SJerome Forissier 1391*7901324dSJerome Forissier /* Check that there's space for the authentication tag. */ 1392*7901324dSJerome Forissier if( rec->data_len < transform->taglen ) 1393*7901324dSJerome Forissier { 1394*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 1395*7901324dSJerome Forissier ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ", 1396*7901324dSJerome Forissier rec->data_len, 1397*7901324dSJerome Forissier transform->taglen ) ); 1398*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 1399*7901324dSJerome Forissier } 1400*7901324dSJerome Forissier rec->data_len -= transform->taglen; 140111fa71b9SJerome Forissier 1402*7901324dSJerome Forissier /* 1403*7901324dSJerome Forissier * Prepare nonce from dynamic and static parts. 1404*7901324dSJerome Forissier */ 1405*7901324dSJerome Forissier ssl_build_record_nonce( iv, sizeof( iv ), 1406*7901324dSJerome Forissier transform->iv_dec, 1407*7901324dSJerome Forissier transform->fixed_ivlen, 1408*7901324dSJerome Forissier dynamic_iv, 1409*7901324dSJerome Forissier dynamic_iv_len ); 1410*7901324dSJerome Forissier 1411*7901324dSJerome Forissier /* 1412*7901324dSJerome Forissier * Build additional data for AEAD encryption. 1413*7901324dSJerome Forissier * This depends on the TLS version. 1414*7901324dSJerome Forissier */ 1415*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 1416*7901324dSJerome Forissier transform->minor_ver ); 141711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", 141811fa71b9SJerome Forissier add_data, add_data_len ); 141911fa71b9SJerome Forissier 142011fa71b9SJerome Forissier /* Because of the check above, we know that there are 142111fa71b9SJerome Forissier * explicit_iv_len Bytes preceeding data, and taglen 142211fa71b9SJerome Forissier * bytes following data + data_len. This justifies 142311fa71b9SJerome Forissier * the debug message and the invocation of 142411fa71b9SJerome Forissier * mbedtls_cipher_auth_decrypt() below. */ 142511fa71b9SJerome Forissier 142611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); 142711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len, 142811fa71b9SJerome Forissier transform->taglen ); 142911fa71b9SJerome Forissier 143011fa71b9SJerome Forissier /* 143111fa71b9SJerome Forissier * Decrypt and authenticate 143211fa71b9SJerome Forissier */ 1433*7901324dSJerome Forissier if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec, 143411fa71b9SJerome Forissier iv, transform->ivlen, 143511fa71b9SJerome Forissier add_data, add_data_len, 1436*7901324dSJerome Forissier data, rec->data_len + transform->taglen, /* src */ 1437*7901324dSJerome Forissier data, rec->buf_len - (data - rec->buf), &olen, /* dst */ 143811fa71b9SJerome Forissier transform->taglen ) ) != 0 ) 143911fa71b9SJerome Forissier { 144011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); 144111fa71b9SJerome Forissier 144211fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) 144311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 144411fa71b9SJerome Forissier 144511fa71b9SJerome Forissier return( ret ); 144611fa71b9SJerome Forissier } 144711fa71b9SJerome Forissier auth_done++; 144811fa71b9SJerome Forissier 144911fa71b9SJerome Forissier /* Double-check that AEAD decryption doesn't change content length. */ 145011fa71b9SJerome Forissier if( olen != rec->data_len ) 145111fa71b9SJerome Forissier { 145211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 145311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 145411fa71b9SJerome Forissier } 145511fa71b9SJerome Forissier } 145611fa71b9SJerome Forissier else 145711fa71b9SJerome Forissier #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ 1458*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) 145911fa71b9SJerome Forissier if( mode == MBEDTLS_MODE_CBC ) 146011fa71b9SJerome Forissier { 146111fa71b9SJerome Forissier size_t minlen = 0; 146211fa71b9SJerome Forissier 146311fa71b9SJerome Forissier /* 146411fa71b9SJerome Forissier * Check immediate ciphertext sanity 146511fa71b9SJerome Forissier */ 146611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 146711fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 146811fa71b9SJerome Forissier { 146911fa71b9SJerome Forissier /* The ciphertext is prefixed with the CBC IV. */ 147011fa71b9SJerome Forissier minlen += transform->ivlen; 147111fa71b9SJerome Forissier } 147211fa71b9SJerome Forissier #endif 147311fa71b9SJerome Forissier 147411fa71b9SJerome Forissier /* Size considerations: 147511fa71b9SJerome Forissier * 147611fa71b9SJerome Forissier * - The CBC cipher text must not be empty and hence 147711fa71b9SJerome Forissier * at least of size transform->ivlen. 147811fa71b9SJerome Forissier * 147911fa71b9SJerome Forissier * Together with the potential IV-prefix, this explains 148011fa71b9SJerome Forissier * the first of the two checks below. 148111fa71b9SJerome Forissier * 148211fa71b9SJerome Forissier * - The record must contain a MAC, either in plain or 148311fa71b9SJerome Forissier * encrypted, depending on whether Encrypt-then-MAC 148411fa71b9SJerome Forissier * is used or not. 148511fa71b9SJerome Forissier * - If it is, the message contains the IV-prefix, 148611fa71b9SJerome Forissier * the CBC ciphertext, and the MAC. 148711fa71b9SJerome Forissier * - If it is not, the padded plaintext, and hence 148811fa71b9SJerome Forissier * the CBC ciphertext, has at least length maclen + 1 148911fa71b9SJerome Forissier * because there is at least the padding length byte. 149011fa71b9SJerome Forissier * 149111fa71b9SJerome Forissier * As the CBC ciphertext is not empty, both cases give the 149211fa71b9SJerome Forissier * lower bound minlen + maclen + 1 on the record size, which 149311fa71b9SJerome Forissier * we test for in the second check below. 149411fa71b9SJerome Forissier */ 149511fa71b9SJerome Forissier if( rec->data_len < minlen + transform->ivlen || 149611fa71b9SJerome Forissier rec->data_len < minlen + transform->maclen + 1 ) 149711fa71b9SJerome Forissier { 1498*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 1499*7901324dSJerome Forissier ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET 1500*7901324dSJerome Forissier "), maclen (%" MBEDTLS_PRINTF_SIZET ") " 150111fa71b9SJerome Forissier "+ 1 ) ( + expl IV )", rec->data_len, 150211fa71b9SJerome Forissier transform->ivlen, 150311fa71b9SJerome Forissier transform->maclen ) ); 150411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 150511fa71b9SJerome Forissier } 150611fa71b9SJerome Forissier 150711fa71b9SJerome Forissier /* 150811fa71b9SJerome Forissier * Authenticate before decrypt if enabled 150911fa71b9SJerome Forissier */ 151011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 151111fa71b9SJerome Forissier if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) 151211fa71b9SJerome Forissier { 151311fa71b9SJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; 151411fa71b9SJerome Forissier 151511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); 151611fa71b9SJerome Forissier 151711fa71b9SJerome Forissier /* Update data_len in tandem with add_data. 151811fa71b9SJerome Forissier * 151911fa71b9SJerome Forissier * The subtraction is safe because of the previous check 152011fa71b9SJerome Forissier * data_len >= minlen + maclen + 1. 152111fa71b9SJerome Forissier * 152211fa71b9SJerome Forissier * Afterwards, we know that data + data_len is followed by at 152311fa71b9SJerome Forissier * least maclen Bytes, which justifies the call to 152411fa71b9SJerome Forissier * mbedtls_ssl_safer_memcmp() below. 152511fa71b9SJerome Forissier * 152611fa71b9SJerome Forissier * Further, we still know that data_len > minlen */ 152711fa71b9SJerome Forissier rec->data_len -= transform->maclen; 1528*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 1529*7901324dSJerome Forissier transform->minor_ver ); 153011fa71b9SJerome Forissier 153111fa71b9SJerome Forissier /* Calculate expected MAC. */ 153211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, 153311fa71b9SJerome Forissier add_data_len ); 153411fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, 153511fa71b9SJerome Forissier add_data_len ); 153611fa71b9SJerome Forissier mbedtls_md_hmac_update( &transform->md_ctx_dec, 153711fa71b9SJerome Forissier data, rec->data_len ); 153811fa71b9SJerome Forissier mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); 153911fa71b9SJerome Forissier mbedtls_md_hmac_reset( &transform->md_ctx_dec ); 154011fa71b9SJerome Forissier 154111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, 154211fa71b9SJerome Forissier transform->maclen ); 154311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, 154411fa71b9SJerome Forissier transform->maclen ); 154511fa71b9SJerome Forissier 154611fa71b9SJerome Forissier /* Compare expected MAC with MAC at the end of the record. */ 154711fa71b9SJerome Forissier if( mbedtls_ssl_safer_memcmp( data + rec->data_len, mac_expect, 154811fa71b9SJerome Forissier transform->maclen ) != 0 ) 154911fa71b9SJerome Forissier { 155011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); 155111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 155211fa71b9SJerome Forissier } 155311fa71b9SJerome Forissier auth_done++; 155411fa71b9SJerome Forissier } 155511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 155611fa71b9SJerome Forissier 155711fa71b9SJerome Forissier /* 155811fa71b9SJerome Forissier * Check length sanity 155911fa71b9SJerome Forissier */ 156011fa71b9SJerome Forissier 156111fa71b9SJerome Forissier /* We know from above that data_len > minlen >= 0, 156211fa71b9SJerome Forissier * so the following check in particular implies that 156311fa71b9SJerome Forissier * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */ 156411fa71b9SJerome Forissier if( rec->data_len % transform->ivlen != 0 ) 156511fa71b9SJerome Forissier { 1566*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 1567*7901324dSJerome Forissier ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0", 156811fa71b9SJerome Forissier rec->data_len, transform->ivlen ) ); 156911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 157011fa71b9SJerome Forissier } 157111fa71b9SJerome Forissier 157211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 157311fa71b9SJerome Forissier /* 157411fa71b9SJerome Forissier * Initialize for prepended IV for block cipher in TLS v1.1 and up 157511fa71b9SJerome Forissier */ 157611fa71b9SJerome Forissier if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 157711fa71b9SJerome Forissier { 157811fa71b9SJerome Forissier /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */ 157911fa71b9SJerome Forissier memcpy( transform->iv_dec, data, transform->ivlen ); 158011fa71b9SJerome Forissier 158111fa71b9SJerome Forissier data += transform->ivlen; 158211fa71b9SJerome Forissier rec->data_offset += transform->ivlen; 158311fa71b9SJerome Forissier rec->data_len -= transform->ivlen; 158411fa71b9SJerome Forissier } 158511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 158611fa71b9SJerome Forissier 158711fa71b9SJerome Forissier /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */ 158811fa71b9SJerome Forissier 158911fa71b9SJerome Forissier if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec, 159011fa71b9SJerome Forissier transform->iv_dec, transform->ivlen, 159111fa71b9SJerome Forissier data, rec->data_len, data, &olen ) ) != 0 ) 159211fa71b9SJerome Forissier { 159311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); 159411fa71b9SJerome Forissier return( ret ); 159511fa71b9SJerome Forissier } 159611fa71b9SJerome Forissier 159711fa71b9SJerome Forissier /* Double-check that length hasn't changed during decryption. */ 159811fa71b9SJerome Forissier if( rec->data_len != olen ) 159911fa71b9SJerome Forissier { 160011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 160111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 160211fa71b9SJerome Forissier } 160311fa71b9SJerome Forissier 160411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) 160511fa71b9SJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 160611fa71b9SJerome Forissier { 160711fa71b9SJerome Forissier /* 160811fa71b9SJerome Forissier * Save IV in SSL3 and TLS1, where CBC decryption of consecutive 160911fa71b9SJerome Forissier * records is equivalent to CBC decryption of the concatenation 161011fa71b9SJerome Forissier * of the records; in other words, IVs are maintained across 161111fa71b9SJerome Forissier * record decryptions. 161211fa71b9SJerome Forissier */ 161311fa71b9SJerome Forissier memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv, 161411fa71b9SJerome Forissier transform->ivlen ); 161511fa71b9SJerome Forissier } 161611fa71b9SJerome Forissier #endif 161711fa71b9SJerome Forissier 161811fa71b9SJerome Forissier /* Safe since data_len >= minlen + maclen + 1, so after having 161911fa71b9SJerome Forissier * subtracted at most minlen and maclen up to this point, 162011fa71b9SJerome Forissier * data_len > 0 (because of data_len % ivlen == 0, it's actually 162111fa71b9SJerome Forissier * >= ivlen ). */ 162211fa71b9SJerome Forissier padlen = data[rec->data_len - 1]; 162311fa71b9SJerome Forissier 162411fa71b9SJerome Forissier if( auth_done == 1 ) 162511fa71b9SJerome Forissier { 1626*7901324dSJerome Forissier const size_t mask = mbedtls_ssl_cf_mask_ge( 1627*7901324dSJerome Forissier rec->data_len, 1628*7901324dSJerome Forissier padlen + 1 ); 1629*7901324dSJerome Forissier correct &= mask; 1630*7901324dSJerome Forissier padlen &= mask; 163111fa71b9SJerome Forissier } 163211fa71b9SJerome Forissier else 163311fa71b9SJerome Forissier { 163411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 163511fa71b9SJerome Forissier if( rec->data_len < transform->maclen + padlen + 1 ) 163611fa71b9SJerome Forissier { 1637*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET 1638*7901324dSJerome Forissier ") < maclen (%" MBEDTLS_PRINTF_SIZET 1639*7901324dSJerome Forissier ") + padlen (%" MBEDTLS_PRINTF_SIZET ")", 164011fa71b9SJerome Forissier rec->data_len, 164111fa71b9SJerome Forissier transform->maclen, 164211fa71b9SJerome Forissier padlen + 1 ) ); 164311fa71b9SJerome Forissier } 164411fa71b9SJerome Forissier #endif 164511fa71b9SJerome Forissier 1646*7901324dSJerome Forissier const size_t mask = mbedtls_ssl_cf_mask_ge( 1647*7901324dSJerome Forissier rec->data_len, 1648*7901324dSJerome Forissier transform->maclen + padlen + 1 ); 1649*7901324dSJerome Forissier correct &= mask; 1650*7901324dSJerome Forissier padlen &= mask; 165111fa71b9SJerome Forissier } 165211fa71b9SJerome Forissier 165311fa71b9SJerome Forissier padlen++; 165411fa71b9SJerome Forissier 165511fa71b9SJerome Forissier /* Regardless of the validity of the padding, 165611fa71b9SJerome Forissier * we have data_len >= padlen here. */ 165711fa71b9SJerome Forissier 165811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 165911fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 166011fa71b9SJerome Forissier { 1661*7901324dSJerome Forissier /* This is the SSL 3.0 path, we don't have to worry about Lucky 1662*7901324dSJerome Forissier * 13, because there's a strictly worse padding attack built in 1663*7901324dSJerome Forissier * the protocol (known as part of POODLE), so we don't care if the 1664*7901324dSJerome Forissier * code is not constant-time, in particular branches are OK. */ 166511fa71b9SJerome Forissier if( padlen > transform->ivlen ) 166611fa71b9SJerome Forissier { 166711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 1668*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %" MBEDTLS_PRINTF_SIZET ", " 1669*7901324dSJerome Forissier "should be no more than %" MBEDTLS_PRINTF_SIZET, 167011fa71b9SJerome Forissier padlen, transform->ivlen ) ); 167111fa71b9SJerome Forissier #endif 167211fa71b9SJerome Forissier correct = 0; 167311fa71b9SJerome Forissier } 167411fa71b9SJerome Forissier } 167511fa71b9SJerome Forissier else 167611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 167711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 167811fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 167911fa71b9SJerome Forissier if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) 168011fa71b9SJerome Forissier { 168111fa71b9SJerome Forissier /* The padding check involves a series of up to 256 168211fa71b9SJerome Forissier * consecutive memory reads at the end of the record 168311fa71b9SJerome Forissier * plaintext buffer. In order to hide the length and 168411fa71b9SJerome Forissier * validity of the padding, always perform exactly 168511fa71b9SJerome Forissier * `min(256,plaintext_len)` reads (but take into account 168611fa71b9SJerome Forissier * only the last `padlen` bytes for the padding check). */ 168711fa71b9SJerome Forissier size_t pad_count = 0; 168811fa71b9SJerome Forissier volatile unsigned char* const check = data; 168911fa71b9SJerome Forissier 169011fa71b9SJerome Forissier /* Index of first padding byte; it has been ensured above 169111fa71b9SJerome Forissier * that the subtraction is safe. */ 169211fa71b9SJerome Forissier size_t const padding_idx = rec->data_len - padlen; 169311fa71b9SJerome Forissier size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256; 169411fa71b9SJerome Forissier size_t const start_idx = rec->data_len - num_checks; 169511fa71b9SJerome Forissier size_t idx; 169611fa71b9SJerome Forissier 169711fa71b9SJerome Forissier for( idx = start_idx; idx < rec->data_len; idx++ ) 169811fa71b9SJerome Forissier { 1699*7901324dSJerome Forissier /* pad_count += (idx >= padding_idx) && 1700*7901324dSJerome Forissier * (check[idx] == padlen - 1); 1701*7901324dSJerome Forissier */ 1702*7901324dSJerome Forissier const size_t mask = mbedtls_ssl_cf_mask_ge( idx, padding_idx ); 1703*7901324dSJerome Forissier const size_t equal = mbedtls_ssl_cf_bool_eq( check[idx], 1704*7901324dSJerome Forissier padlen - 1 ); 1705*7901324dSJerome Forissier pad_count += mask & equal; 170611fa71b9SJerome Forissier } 1707*7901324dSJerome Forissier correct &= mbedtls_ssl_cf_bool_eq( pad_count, padlen ); 170811fa71b9SJerome Forissier 170911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 171011fa71b9SJerome Forissier if( padlen > 0 && correct == 0 ) 171111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); 171211fa71b9SJerome Forissier #endif 1713*7901324dSJerome Forissier padlen &= mbedtls_ssl_cf_mask_from_bit( correct ); 171411fa71b9SJerome Forissier } 171511fa71b9SJerome Forissier else 171611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ 171711fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 171811fa71b9SJerome Forissier { 171911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 172011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 172111fa71b9SJerome Forissier } 172211fa71b9SJerome Forissier 172311fa71b9SJerome Forissier /* If the padding was found to be invalid, padlen == 0 172411fa71b9SJerome Forissier * and the subtraction is safe. If the padding was found valid, 172511fa71b9SJerome Forissier * padlen hasn't been changed and the previous assertion 172611fa71b9SJerome Forissier * data_len >= padlen still holds. */ 172711fa71b9SJerome Forissier rec->data_len -= padlen; 172811fa71b9SJerome Forissier } 172911fa71b9SJerome Forissier else 1730*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */ 173111fa71b9SJerome Forissier { 173211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 173311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 173411fa71b9SJerome Forissier } 173511fa71b9SJerome Forissier 173611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 173711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", 173811fa71b9SJerome Forissier data, rec->data_len ); 173911fa71b9SJerome Forissier #endif 174011fa71b9SJerome Forissier 174111fa71b9SJerome Forissier /* 174211fa71b9SJerome Forissier * Authenticate if not done yet. 174311fa71b9SJerome Forissier * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). 174411fa71b9SJerome Forissier */ 174511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 174611fa71b9SJerome Forissier if( auth_done == 0 ) 174711fa71b9SJerome Forissier { 174811fa71b9SJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; 1749*7901324dSJerome Forissier unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD]; 175011fa71b9SJerome Forissier 175111fa71b9SJerome Forissier /* If the initial value of padlen was such that 175211fa71b9SJerome Forissier * data_len < maclen + padlen + 1, then padlen 175311fa71b9SJerome Forissier * got reset to 1, and the initial check 175411fa71b9SJerome Forissier * data_len >= minlen + maclen + 1 175511fa71b9SJerome Forissier * guarantees that at this point we still 175611fa71b9SJerome Forissier * have at least data_len >= maclen. 175711fa71b9SJerome Forissier * 175811fa71b9SJerome Forissier * If the initial value of padlen was such that 175911fa71b9SJerome Forissier * data_len >= maclen + padlen + 1, then we have 176011fa71b9SJerome Forissier * subtracted either padlen + 1 (if the padding was correct) 176111fa71b9SJerome Forissier * or 0 (if the padding was incorrect) since then, 176211fa71b9SJerome Forissier * hence data_len >= maclen in any case. 176311fa71b9SJerome Forissier */ 176411fa71b9SJerome Forissier rec->data_len -= transform->maclen; 1765*7901324dSJerome Forissier ssl_extract_add_data_from_record( add_data, &add_data_len, rec, 1766*7901324dSJerome Forissier transform->minor_ver ); 176711fa71b9SJerome Forissier 176811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 176911fa71b9SJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 177011fa71b9SJerome Forissier { 177111fa71b9SJerome Forissier ssl_mac( &transform->md_ctx_dec, 177211fa71b9SJerome Forissier transform->mac_dec, 177311fa71b9SJerome Forissier data, rec->data_len, 177411fa71b9SJerome Forissier rec->ctr, rec->type, 177511fa71b9SJerome Forissier mac_expect ); 1776*7901324dSJerome Forissier memcpy( mac_peer, data + rec->data_len, transform->maclen ); 177711fa71b9SJerome Forissier } 177811fa71b9SJerome Forissier else 177911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 178011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 178111fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 178211fa71b9SJerome Forissier if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) 178311fa71b9SJerome Forissier { 178411fa71b9SJerome Forissier /* 178511fa71b9SJerome Forissier * The next two sizes are the minimum and maximum values of 1786*7901324dSJerome Forissier * data_len over all padlen values. 178711fa71b9SJerome Forissier * 178811fa71b9SJerome Forissier * They're independent of padlen, since we previously did 178911fa71b9SJerome Forissier * data_len -= padlen. 179011fa71b9SJerome Forissier * 179111fa71b9SJerome Forissier * Note that max_len + maclen is never more than the buffer 179211fa71b9SJerome Forissier * length, as we previously did in_msglen -= maclen too. 179311fa71b9SJerome Forissier */ 179411fa71b9SJerome Forissier const size_t max_len = rec->data_len + padlen; 179511fa71b9SJerome Forissier const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; 179611fa71b9SJerome Forissier 1797*7901324dSJerome Forissier ret = mbedtls_ssl_cf_hmac( &transform->md_ctx_dec, 1798*7901324dSJerome Forissier add_data, add_data_len, 1799*7901324dSJerome Forissier data, rec->data_len, min_len, max_len, 1800*7901324dSJerome Forissier mac_expect ); 1801*7901324dSJerome Forissier if( ret != 0 ) 180211fa71b9SJerome Forissier { 1803*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret ); 1804*7901324dSJerome Forissier return( ret ); 180511fa71b9SJerome Forissier } 180611fa71b9SJerome Forissier 1807*7901324dSJerome Forissier mbedtls_ssl_cf_memcpy_offset( mac_peer, data, 1808*7901324dSJerome Forissier rec->data_len, 1809*7901324dSJerome Forissier min_len, max_len, 1810*7901324dSJerome Forissier transform->maclen ); 181111fa71b9SJerome Forissier } 181211fa71b9SJerome Forissier else 181311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ 181411fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 181511fa71b9SJerome Forissier { 181611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 181711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 181811fa71b9SJerome Forissier } 181911fa71b9SJerome Forissier 182011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 182111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen ); 1822*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, transform->maclen ); 182311fa71b9SJerome Forissier #endif 182411fa71b9SJerome Forissier 1825*7901324dSJerome Forissier if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect, 182611fa71b9SJerome Forissier transform->maclen ) != 0 ) 182711fa71b9SJerome Forissier { 182811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL) 182911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); 183011fa71b9SJerome Forissier #endif 183111fa71b9SJerome Forissier correct = 0; 183211fa71b9SJerome Forissier } 183311fa71b9SJerome Forissier auth_done++; 183411fa71b9SJerome Forissier } 183511fa71b9SJerome Forissier 183611fa71b9SJerome Forissier /* 183711fa71b9SJerome Forissier * Finally check the correct flag 183811fa71b9SJerome Forissier */ 183911fa71b9SJerome Forissier if( correct == 0 ) 184011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 184111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ 184211fa71b9SJerome Forissier 184311fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */ 184411fa71b9SJerome Forissier if( auth_done != 1 ) 184511fa71b9SJerome Forissier { 184611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 184711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 184811fa71b9SJerome Forissier } 184911fa71b9SJerome Forissier 1850*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 1851*7901324dSJerome Forissier if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) 1852*7901324dSJerome Forissier { 1853*7901324dSJerome Forissier /* Remove inner padding and infer true content type. */ 1854*7901324dSJerome Forissier ret = ssl_parse_inner_plaintext( data, &rec->data_len, 1855*7901324dSJerome Forissier &rec->type ); 1856*7901324dSJerome Forissier 1857*7901324dSJerome Forissier if( ret != 0 ) 1858*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 1859*7901324dSJerome Forissier } 1860*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 1861*7901324dSJerome Forissier 186211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 186311fa71b9SJerome Forissier if( rec->cid_len != 0 ) 186411fa71b9SJerome Forissier { 1865*7901324dSJerome Forissier ret = ssl_parse_inner_plaintext( data, &rec->data_len, 186611fa71b9SJerome Forissier &rec->type ); 186711fa71b9SJerome Forissier if( ret != 0 ) 186811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 186911fa71b9SJerome Forissier } 187011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 187111fa71b9SJerome Forissier 187211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); 187311fa71b9SJerome Forissier 187411fa71b9SJerome Forissier return( 0 ); 187511fa71b9SJerome Forissier } 187611fa71b9SJerome Forissier 187711fa71b9SJerome Forissier #undef MAC_NONE 187811fa71b9SJerome Forissier #undef MAC_PLAINTEXT 187911fa71b9SJerome Forissier #undef MAC_CIPHERTEXT 188011fa71b9SJerome Forissier 188111fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 188211fa71b9SJerome Forissier /* 188311fa71b9SJerome Forissier * Compression/decompression functions 188411fa71b9SJerome Forissier */ 188511fa71b9SJerome Forissier static int ssl_compress_buf( mbedtls_ssl_context *ssl ) 188611fa71b9SJerome Forissier { 188711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 188811fa71b9SJerome Forissier unsigned char *msg_post = ssl->out_msg; 188911fa71b9SJerome Forissier ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf; 189011fa71b9SJerome Forissier size_t len_pre = ssl->out_msglen; 189111fa71b9SJerome Forissier unsigned char *msg_pre = ssl->compress_buf; 189211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 189311fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 189411fa71b9SJerome Forissier #else 189511fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 189611fa71b9SJerome Forissier #endif 189711fa71b9SJerome Forissier 189811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); 189911fa71b9SJerome Forissier 190011fa71b9SJerome Forissier if( len_pre == 0 ) 190111fa71b9SJerome Forissier return( 0 ); 190211fa71b9SJerome Forissier 190311fa71b9SJerome Forissier memcpy( msg_pre, ssl->out_msg, len_pre ); 190411fa71b9SJerome Forissier 1905*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 190611fa71b9SJerome Forissier ssl->out_msglen ) ); 190711fa71b9SJerome Forissier 190811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", 190911fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 191011fa71b9SJerome Forissier 191111fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.next_in = msg_pre; 191211fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_in = len_pre; 191311fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.next_out = msg_post; 191411fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written; 191511fa71b9SJerome Forissier 191611fa71b9SJerome Forissier ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); 191711fa71b9SJerome Forissier if( ret != Z_OK ) 191811fa71b9SJerome Forissier { 191911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); 192011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); 192111fa71b9SJerome Forissier } 192211fa71b9SJerome Forissier 192311fa71b9SJerome Forissier ssl->out_msglen = out_buf_len - 192411fa71b9SJerome Forissier ssl->transform_out->ctx_deflate.avail_out - bytes_written; 192511fa71b9SJerome Forissier 1926*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 192711fa71b9SJerome Forissier ssl->out_msglen ) ); 192811fa71b9SJerome Forissier 192911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", 193011fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 193111fa71b9SJerome Forissier 193211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); 193311fa71b9SJerome Forissier 193411fa71b9SJerome Forissier return( 0 ); 193511fa71b9SJerome Forissier } 193611fa71b9SJerome Forissier 193711fa71b9SJerome Forissier static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) 193811fa71b9SJerome Forissier { 193911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 194011fa71b9SJerome Forissier unsigned char *msg_post = ssl->in_msg; 194111fa71b9SJerome Forissier ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf; 194211fa71b9SJerome Forissier size_t len_pre = ssl->in_msglen; 194311fa71b9SJerome Forissier unsigned char *msg_pre = ssl->compress_buf; 194411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 194511fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 194611fa71b9SJerome Forissier #else 194711fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 194811fa71b9SJerome Forissier #endif 194911fa71b9SJerome Forissier 195011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); 195111fa71b9SJerome Forissier 195211fa71b9SJerome Forissier if( len_pre == 0 ) 195311fa71b9SJerome Forissier return( 0 ); 195411fa71b9SJerome Forissier 195511fa71b9SJerome Forissier memcpy( msg_pre, ssl->in_msg, len_pre ); 195611fa71b9SJerome Forissier 1957*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 195811fa71b9SJerome Forissier ssl->in_msglen ) ); 195911fa71b9SJerome Forissier 196011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", 196111fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 196211fa71b9SJerome Forissier 196311fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.next_in = msg_pre; 196411fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_in = len_pre; 196511fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.next_out = msg_post; 196611fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes; 196711fa71b9SJerome Forissier 196811fa71b9SJerome Forissier ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); 196911fa71b9SJerome Forissier if( ret != Z_OK ) 197011fa71b9SJerome Forissier { 197111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); 197211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); 197311fa71b9SJerome Forissier } 197411fa71b9SJerome Forissier 197511fa71b9SJerome Forissier ssl->in_msglen = in_buf_len - 197611fa71b9SJerome Forissier ssl->transform_in->ctx_inflate.avail_out - header_bytes; 197711fa71b9SJerome Forissier 1978*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ", 197911fa71b9SJerome Forissier ssl->in_msglen ) ); 198011fa71b9SJerome Forissier 198111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", 198211fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 198311fa71b9SJerome Forissier 198411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); 198511fa71b9SJerome Forissier 198611fa71b9SJerome Forissier return( 0 ); 198711fa71b9SJerome Forissier } 198811fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */ 198911fa71b9SJerome Forissier 199011fa71b9SJerome Forissier /* 199111fa71b9SJerome Forissier * Fill the input message buffer by appending data to it. 199211fa71b9SJerome Forissier * The amount of data already fetched is in ssl->in_left. 199311fa71b9SJerome Forissier * 199411fa71b9SJerome Forissier * If we return 0, is it guaranteed that (at least) nb_want bytes are 199511fa71b9SJerome Forissier * available (from this read and/or a previous one). Otherwise, an error code 199611fa71b9SJerome Forissier * is returned (possibly EOF or WANT_READ). 199711fa71b9SJerome Forissier * 199811fa71b9SJerome Forissier * With stream transport (TLS) on success ssl->in_left == nb_want, but 199911fa71b9SJerome Forissier * with datagram transport (DTLS) on success ssl->in_left >= nb_want, 200011fa71b9SJerome Forissier * since we always read a whole datagram at once. 200111fa71b9SJerome Forissier * 200211fa71b9SJerome Forissier * For DTLS, it is up to the caller to set ssl->next_record_offset when 200311fa71b9SJerome Forissier * they're done reading a record. 200411fa71b9SJerome Forissier */ 200511fa71b9SJerome Forissier int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) 200611fa71b9SJerome Forissier { 200711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 200811fa71b9SJerome Forissier size_t len; 200911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 201011fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 201111fa71b9SJerome Forissier #else 201211fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 201311fa71b9SJerome Forissier #endif 201411fa71b9SJerome Forissier 201511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); 201611fa71b9SJerome Forissier 201711fa71b9SJerome Forissier if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) 201811fa71b9SJerome Forissier { 201911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " 202011fa71b9SJerome Forissier "or mbedtls_ssl_set_bio()" ) ); 202111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 202211fa71b9SJerome Forissier } 202311fa71b9SJerome Forissier 202411fa71b9SJerome Forissier if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) 202511fa71b9SJerome Forissier { 202611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); 202711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 202811fa71b9SJerome Forissier } 202911fa71b9SJerome Forissier 203011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 203111fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 203211fa71b9SJerome Forissier { 203311fa71b9SJerome Forissier uint32_t timeout; 203411fa71b9SJerome Forissier 203511fa71b9SJerome Forissier /* 203611fa71b9SJerome Forissier * The point is, we need to always read a full datagram at once, so we 203711fa71b9SJerome Forissier * sometimes read more then requested, and handle the additional data. 203811fa71b9SJerome Forissier * It could be the rest of the current record (while fetching the 203911fa71b9SJerome Forissier * header) and/or some other records in the same datagram. 204011fa71b9SJerome Forissier */ 204111fa71b9SJerome Forissier 204211fa71b9SJerome Forissier /* 204311fa71b9SJerome Forissier * Move to the next record in the already read datagram if applicable 204411fa71b9SJerome Forissier */ 204511fa71b9SJerome Forissier if( ssl->next_record_offset != 0 ) 204611fa71b9SJerome Forissier { 204711fa71b9SJerome Forissier if( ssl->in_left < ssl->next_record_offset ) 204811fa71b9SJerome Forissier { 204911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 205011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 205111fa71b9SJerome Forissier } 205211fa71b9SJerome Forissier 205311fa71b9SJerome Forissier ssl->in_left -= ssl->next_record_offset; 205411fa71b9SJerome Forissier 205511fa71b9SJerome Forissier if( ssl->in_left != 0 ) 205611fa71b9SJerome Forissier { 2057*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %" 2058*7901324dSJerome Forissier MBEDTLS_PRINTF_SIZET, 205911fa71b9SJerome Forissier ssl->next_record_offset ) ); 206011fa71b9SJerome Forissier memmove( ssl->in_hdr, 206111fa71b9SJerome Forissier ssl->in_hdr + ssl->next_record_offset, 206211fa71b9SJerome Forissier ssl->in_left ); 206311fa71b9SJerome Forissier } 206411fa71b9SJerome Forissier 206511fa71b9SJerome Forissier ssl->next_record_offset = 0; 206611fa71b9SJerome Forissier } 206711fa71b9SJerome Forissier 2068*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET 2069*7901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 207011fa71b9SJerome Forissier ssl->in_left, nb_want ) ); 207111fa71b9SJerome Forissier 207211fa71b9SJerome Forissier /* 207311fa71b9SJerome Forissier * Done if we already have enough data. 207411fa71b9SJerome Forissier */ 207511fa71b9SJerome Forissier if( nb_want <= ssl->in_left) 207611fa71b9SJerome Forissier { 207711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); 207811fa71b9SJerome Forissier return( 0 ); 207911fa71b9SJerome Forissier } 208011fa71b9SJerome Forissier 208111fa71b9SJerome Forissier /* 208211fa71b9SJerome Forissier * A record can't be split across datagrams. If we need to read but 208311fa71b9SJerome Forissier * are not at the beginning of a new record, the caller did something 208411fa71b9SJerome Forissier * wrong. 208511fa71b9SJerome Forissier */ 208611fa71b9SJerome Forissier if( ssl->in_left != 0 ) 208711fa71b9SJerome Forissier { 208811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 208911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 209011fa71b9SJerome Forissier } 209111fa71b9SJerome Forissier 209211fa71b9SJerome Forissier /* 209311fa71b9SJerome Forissier * Don't even try to read if time's out already. 209411fa71b9SJerome Forissier * This avoids by-passing the timer when repeatedly receiving messages 209511fa71b9SJerome Forissier * that will end up being dropped. 209611fa71b9SJerome Forissier */ 209711fa71b9SJerome Forissier if( mbedtls_ssl_check_timer( ssl ) != 0 ) 209811fa71b9SJerome Forissier { 209911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) ); 210011fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 210111fa71b9SJerome Forissier } 210211fa71b9SJerome Forissier else 210311fa71b9SJerome Forissier { 210411fa71b9SJerome Forissier len = in_buf_len - ( ssl->in_hdr - ssl->in_buf ); 210511fa71b9SJerome Forissier 210611fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 210711fa71b9SJerome Forissier timeout = ssl->handshake->retransmit_timeout; 210811fa71b9SJerome Forissier else 210911fa71b9SJerome Forissier timeout = ssl->conf->read_timeout; 211011fa71b9SJerome Forissier 2111*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %lu ms", (unsigned long) timeout ) ); 211211fa71b9SJerome Forissier 211311fa71b9SJerome Forissier if( ssl->f_recv_timeout != NULL ) 211411fa71b9SJerome Forissier ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, 211511fa71b9SJerome Forissier timeout ); 211611fa71b9SJerome Forissier else 211711fa71b9SJerome Forissier ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); 211811fa71b9SJerome Forissier 211911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); 212011fa71b9SJerome Forissier 212111fa71b9SJerome Forissier if( ret == 0 ) 212211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONN_EOF ); 212311fa71b9SJerome Forissier } 212411fa71b9SJerome Forissier 212511fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) 212611fa71b9SJerome Forissier { 212711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); 212811fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 212911fa71b9SJerome Forissier 213011fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 213111fa71b9SJerome Forissier { 213211fa71b9SJerome Forissier if( ssl_double_retransmit_timeout( ssl ) != 0 ) 213311fa71b9SJerome Forissier { 213411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); 213511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_TIMEOUT ); 213611fa71b9SJerome Forissier } 213711fa71b9SJerome Forissier 213811fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) 213911fa71b9SJerome Forissier { 214011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); 214111fa71b9SJerome Forissier return( ret ); 214211fa71b9SJerome Forissier } 214311fa71b9SJerome Forissier 214411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 214511fa71b9SJerome Forissier } 214611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 214711fa71b9SJerome Forissier else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 214811fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 214911fa71b9SJerome Forissier { 215011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 ) 215111fa71b9SJerome Forissier { 215211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request", 215311fa71b9SJerome Forissier ret ); 215411fa71b9SJerome Forissier return( ret ); 215511fa71b9SJerome Forissier } 215611fa71b9SJerome Forissier 215711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 215811fa71b9SJerome Forissier } 215911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 216011fa71b9SJerome Forissier } 216111fa71b9SJerome Forissier 216211fa71b9SJerome Forissier if( ret < 0 ) 216311fa71b9SJerome Forissier return( ret ); 216411fa71b9SJerome Forissier 216511fa71b9SJerome Forissier ssl->in_left = ret; 216611fa71b9SJerome Forissier } 216711fa71b9SJerome Forissier else 216811fa71b9SJerome Forissier #endif 216911fa71b9SJerome Forissier { 2170*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET 2171*7901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 217211fa71b9SJerome Forissier ssl->in_left, nb_want ) ); 217311fa71b9SJerome Forissier 217411fa71b9SJerome Forissier while( ssl->in_left < nb_want ) 217511fa71b9SJerome Forissier { 217611fa71b9SJerome Forissier len = nb_want - ssl->in_left; 217711fa71b9SJerome Forissier 217811fa71b9SJerome Forissier if( mbedtls_ssl_check_timer( ssl ) != 0 ) 217911fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT; 218011fa71b9SJerome Forissier else 218111fa71b9SJerome Forissier { 218211fa71b9SJerome Forissier if( ssl->f_recv_timeout != NULL ) 218311fa71b9SJerome Forissier { 218411fa71b9SJerome Forissier ret = ssl->f_recv_timeout( ssl->p_bio, 218511fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len, 218611fa71b9SJerome Forissier ssl->conf->read_timeout ); 218711fa71b9SJerome Forissier } 218811fa71b9SJerome Forissier else 218911fa71b9SJerome Forissier { 219011fa71b9SJerome Forissier ret = ssl->f_recv( ssl->p_bio, 219111fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len ); 219211fa71b9SJerome Forissier } 219311fa71b9SJerome Forissier } 219411fa71b9SJerome Forissier 2195*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET 2196*7901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET, 219711fa71b9SJerome Forissier ssl->in_left, nb_want ) ); 219811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); 219911fa71b9SJerome Forissier 220011fa71b9SJerome Forissier if( ret == 0 ) 220111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONN_EOF ); 220211fa71b9SJerome Forissier 220311fa71b9SJerome Forissier if( ret < 0 ) 220411fa71b9SJerome Forissier return( ret ); 220511fa71b9SJerome Forissier 2206*7901324dSJerome Forissier if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) 220711fa71b9SJerome Forissier { 220811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, 2209*7901324dSJerome Forissier ( "f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " were requested", 2210*7901324dSJerome Forissier ret, len ) ); 221111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 221211fa71b9SJerome Forissier } 221311fa71b9SJerome Forissier 221411fa71b9SJerome Forissier ssl->in_left += ret; 221511fa71b9SJerome Forissier } 221611fa71b9SJerome Forissier } 221711fa71b9SJerome Forissier 221811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); 221911fa71b9SJerome Forissier 222011fa71b9SJerome Forissier return( 0 ); 222111fa71b9SJerome Forissier } 222211fa71b9SJerome Forissier 222311fa71b9SJerome Forissier /* 222411fa71b9SJerome Forissier * Flush any data not yet written 222511fa71b9SJerome Forissier */ 222611fa71b9SJerome Forissier int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) 222711fa71b9SJerome Forissier { 222811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 222911fa71b9SJerome Forissier unsigned char *buf; 223011fa71b9SJerome Forissier 223111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); 223211fa71b9SJerome Forissier 223311fa71b9SJerome Forissier if( ssl->f_send == NULL ) 223411fa71b9SJerome Forissier { 223511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " 223611fa71b9SJerome Forissier "or mbedtls_ssl_set_bio()" ) ); 223711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 223811fa71b9SJerome Forissier } 223911fa71b9SJerome Forissier 224011fa71b9SJerome Forissier /* Avoid incrementing counter if data is flushed */ 224111fa71b9SJerome Forissier if( ssl->out_left == 0 ) 224211fa71b9SJerome Forissier { 224311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); 224411fa71b9SJerome Forissier return( 0 ); 224511fa71b9SJerome Forissier } 224611fa71b9SJerome Forissier 224711fa71b9SJerome Forissier while( ssl->out_left > 0 ) 224811fa71b9SJerome Forissier { 2249*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %" MBEDTLS_PRINTF_SIZET 2250*7901324dSJerome Forissier ", out_left: %" MBEDTLS_PRINTF_SIZET, 225111fa71b9SJerome Forissier mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); 225211fa71b9SJerome Forissier 225311fa71b9SJerome Forissier buf = ssl->out_hdr - ssl->out_left; 225411fa71b9SJerome Forissier ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); 225511fa71b9SJerome Forissier 225611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); 225711fa71b9SJerome Forissier 225811fa71b9SJerome Forissier if( ret <= 0 ) 225911fa71b9SJerome Forissier return( ret ); 226011fa71b9SJerome Forissier 2261*7901324dSJerome Forissier if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) ) 226211fa71b9SJerome Forissier { 226311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, 2264*7901324dSJerome Forissier ( "f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " bytes were sent", 2265*7901324dSJerome Forissier ret, ssl->out_left ) ); 226611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 226711fa71b9SJerome Forissier } 226811fa71b9SJerome Forissier 226911fa71b9SJerome Forissier ssl->out_left -= ret; 227011fa71b9SJerome Forissier } 227111fa71b9SJerome Forissier 227211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 227311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 227411fa71b9SJerome Forissier { 227511fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 227611fa71b9SJerome Forissier } 227711fa71b9SJerome Forissier else 227811fa71b9SJerome Forissier #endif 227911fa71b9SJerome Forissier { 228011fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 228111fa71b9SJerome Forissier } 228211fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 228311fa71b9SJerome Forissier 228411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); 228511fa71b9SJerome Forissier 228611fa71b9SJerome Forissier return( 0 ); 228711fa71b9SJerome Forissier } 228811fa71b9SJerome Forissier 228911fa71b9SJerome Forissier /* 229011fa71b9SJerome Forissier * Functions to handle the DTLS retransmission state machine 229111fa71b9SJerome Forissier */ 229211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 229311fa71b9SJerome Forissier /* 229411fa71b9SJerome Forissier * Append current handshake message to current outgoing flight 229511fa71b9SJerome Forissier */ 229611fa71b9SJerome Forissier static int ssl_flight_append( mbedtls_ssl_context *ssl ) 229711fa71b9SJerome Forissier { 229811fa71b9SJerome Forissier mbedtls_ssl_flight_item *msg; 229911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) ); 230011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight", 230111fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen ); 230211fa71b9SJerome Forissier 230311fa71b9SJerome Forissier /* Allocate space for current message */ 230411fa71b9SJerome Forissier if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) 230511fa71b9SJerome Forissier { 2306*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 230711fa71b9SJerome Forissier sizeof( mbedtls_ssl_flight_item ) ) ); 230811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); 230911fa71b9SJerome Forissier } 231011fa71b9SJerome Forissier 231111fa71b9SJerome Forissier if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) 231211fa71b9SJerome Forissier { 2313*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed", 2314*7901324dSJerome Forissier ssl->out_msglen ) ); 231511fa71b9SJerome Forissier mbedtls_free( msg ); 231611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); 231711fa71b9SJerome Forissier } 231811fa71b9SJerome Forissier 231911fa71b9SJerome Forissier /* Copy current handshake message with headers */ 232011fa71b9SJerome Forissier memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); 232111fa71b9SJerome Forissier msg->len = ssl->out_msglen; 232211fa71b9SJerome Forissier msg->type = ssl->out_msgtype; 232311fa71b9SJerome Forissier msg->next = NULL; 232411fa71b9SJerome Forissier 232511fa71b9SJerome Forissier /* Append to the current flight */ 232611fa71b9SJerome Forissier if( ssl->handshake->flight == NULL ) 232711fa71b9SJerome Forissier ssl->handshake->flight = msg; 232811fa71b9SJerome Forissier else 232911fa71b9SJerome Forissier { 233011fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = ssl->handshake->flight; 233111fa71b9SJerome Forissier while( cur->next != NULL ) 233211fa71b9SJerome Forissier cur = cur->next; 233311fa71b9SJerome Forissier cur->next = msg; 233411fa71b9SJerome Forissier } 233511fa71b9SJerome Forissier 233611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) ); 233711fa71b9SJerome Forissier return( 0 ); 233811fa71b9SJerome Forissier } 233911fa71b9SJerome Forissier 234011fa71b9SJerome Forissier /* 234111fa71b9SJerome Forissier * Free the current flight of handshake messages 234211fa71b9SJerome Forissier */ 234311fa71b9SJerome Forissier void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight ) 234411fa71b9SJerome Forissier { 234511fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = flight; 234611fa71b9SJerome Forissier mbedtls_ssl_flight_item *next; 234711fa71b9SJerome Forissier 234811fa71b9SJerome Forissier while( cur != NULL ) 234911fa71b9SJerome Forissier { 235011fa71b9SJerome Forissier next = cur->next; 235111fa71b9SJerome Forissier 235211fa71b9SJerome Forissier mbedtls_free( cur->p ); 235311fa71b9SJerome Forissier mbedtls_free( cur ); 235411fa71b9SJerome Forissier 235511fa71b9SJerome Forissier cur = next; 235611fa71b9SJerome Forissier } 235711fa71b9SJerome Forissier } 235811fa71b9SJerome Forissier 235911fa71b9SJerome Forissier /* 236011fa71b9SJerome Forissier * Swap transform_out and out_ctr with the alternative ones 236111fa71b9SJerome Forissier */ 236211fa71b9SJerome Forissier static int ssl_swap_epochs( mbedtls_ssl_context *ssl ) 236311fa71b9SJerome Forissier { 236411fa71b9SJerome Forissier mbedtls_ssl_transform *tmp_transform; 236511fa71b9SJerome Forissier unsigned char tmp_out_ctr[8]; 236611fa71b9SJerome Forissier 236711fa71b9SJerome Forissier if( ssl->transform_out == ssl->handshake->alt_transform_out ) 236811fa71b9SJerome Forissier { 236911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); 237011fa71b9SJerome Forissier return( 0 ); 237111fa71b9SJerome Forissier } 237211fa71b9SJerome Forissier 237311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); 237411fa71b9SJerome Forissier 237511fa71b9SJerome Forissier /* Swap transforms */ 237611fa71b9SJerome Forissier tmp_transform = ssl->transform_out; 237711fa71b9SJerome Forissier ssl->transform_out = ssl->handshake->alt_transform_out; 237811fa71b9SJerome Forissier ssl->handshake->alt_transform_out = tmp_transform; 237911fa71b9SJerome Forissier 238011fa71b9SJerome Forissier /* Swap epoch + sequence_number */ 238111fa71b9SJerome Forissier memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 ); 238211fa71b9SJerome Forissier memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 ); 238311fa71b9SJerome Forissier memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); 238411fa71b9SJerome Forissier 238511fa71b9SJerome Forissier /* Adjust to the newly activated transform */ 238611fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 238711fa71b9SJerome Forissier 238811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 238911fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_activate != NULL ) 239011fa71b9SJerome Forissier { 239111fa71b9SJerome Forissier int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ); 239211fa71b9SJerome Forissier if( ret != 0 ) 239311fa71b9SJerome Forissier { 239411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); 239511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 239611fa71b9SJerome Forissier } 239711fa71b9SJerome Forissier } 239811fa71b9SJerome Forissier #endif 239911fa71b9SJerome Forissier 240011fa71b9SJerome Forissier return( 0 ); 240111fa71b9SJerome Forissier } 240211fa71b9SJerome Forissier 240311fa71b9SJerome Forissier /* 240411fa71b9SJerome Forissier * Retransmit the current flight of messages. 240511fa71b9SJerome Forissier */ 240611fa71b9SJerome Forissier int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) 240711fa71b9SJerome Forissier { 240811fa71b9SJerome Forissier int ret = 0; 240911fa71b9SJerome Forissier 241011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); 241111fa71b9SJerome Forissier 241211fa71b9SJerome Forissier ret = mbedtls_ssl_flight_transmit( ssl ); 241311fa71b9SJerome Forissier 241411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); 241511fa71b9SJerome Forissier 241611fa71b9SJerome Forissier return( ret ); 241711fa71b9SJerome Forissier } 241811fa71b9SJerome Forissier 241911fa71b9SJerome Forissier /* 242011fa71b9SJerome Forissier * Transmit or retransmit the current flight of messages. 242111fa71b9SJerome Forissier * 242211fa71b9SJerome Forissier * Need to remember the current message in case flush_output returns 242311fa71b9SJerome Forissier * WANT_WRITE, causing us to exit this function and come back later. 242411fa71b9SJerome Forissier * This function must be called until state is no longer SENDING. 242511fa71b9SJerome Forissier */ 242611fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl ) 242711fa71b9SJerome Forissier { 242811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 242911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) ); 243011fa71b9SJerome Forissier 243111fa71b9SJerome Forissier if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) 243211fa71b9SJerome Forissier { 243311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) ); 243411fa71b9SJerome Forissier 243511fa71b9SJerome Forissier ssl->handshake->cur_msg = ssl->handshake->flight; 243611fa71b9SJerome Forissier ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12; 243711fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 243811fa71b9SJerome Forissier if( ret != 0 ) 243911fa71b9SJerome Forissier return( ret ); 244011fa71b9SJerome Forissier 244111fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; 244211fa71b9SJerome Forissier } 244311fa71b9SJerome Forissier 244411fa71b9SJerome Forissier while( ssl->handshake->cur_msg != NULL ) 244511fa71b9SJerome Forissier { 244611fa71b9SJerome Forissier size_t max_frag_len; 244711fa71b9SJerome Forissier const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg; 244811fa71b9SJerome Forissier 244911fa71b9SJerome Forissier int const is_finished = 245011fa71b9SJerome Forissier ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && 245111fa71b9SJerome Forissier cur->p[0] == MBEDTLS_SSL_HS_FINISHED ); 245211fa71b9SJerome Forissier 245311fa71b9SJerome Forissier uint8_t const force_flush = ssl->disable_datagram_packing == 1 ? 245411fa71b9SJerome Forissier SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH; 245511fa71b9SJerome Forissier 245611fa71b9SJerome Forissier /* Swap epochs before sending Finished: we can't do it after 245711fa71b9SJerome Forissier * sending ChangeCipherSpec, in case write returns WANT_READ. 245811fa71b9SJerome Forissier * Must be done before copying, may change out_msg pointer */ 245911fa71b9SJerome Forissier if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) ) 246011fa71b9SJerome Forissier { 246111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) ); 246211fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 246311fa71b9SJerome Forissier if( ret != 0 ) 246411fa71b9SJerome Forissier return( ret ); 246511fa71b9SJerome Forissier } 246611fa71b9SJerome Forissier 246711fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram( ssl ); 246811fa71b9SJerome Forissier if( ret < 0 ) 246911fa71b9SJerome Forissier return( ret ); 247011fa71b9SJerome Forissier max_frag_len = (size_t) ret; 247111fa71b9SJerome Forissier 247211fa71b9SJerome Forissier /* CCS is copied as is, while HS messages may need fragmentation */ 247311fa71b9SJerome Forissier if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 247411fa71b9SJerome Forissier { 247511fa71b9SJerome Forissier if( max_frag_len == 0 ) 247611fa71b9SJerome Forissier { 247711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 247811fa71b9SJerome Forissier return( ret ); 247911fa71b9SJerome Forissier 248011fa71b9SJerome Forissier continue; 248111fa71b9SJerome Forissier } 248211fa71b9SJerome Forissier 248311fa71b9SJerome Forissier memcpy( ssl->out_msg, cur->p, cur->len ); 248411fa71b9SJerome Forissier ssl->out_msglen = cur->len; 248511fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 248611fa71b9SJerome Forissier 248711fa71b9SJerome Forissier /* Update position inside current message */ 248811fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur->len; 248911fa71b9SJerome Forissier } 249011fa71b9SJerome Forissier else 249111fa71b9SJerome Forissier { 249211fa71b9SJerome Forissier const unsigned char * const p = ssl->handshake->cur_msg_p; 249311fa71b9SJerome Forissier const size_t hs_len = cur->len - 12; 249411fa71b9SJerome Forissier const size_t frag_off = p - ( cur->p + 12 ); 249511fa71b9SJerome Forissier const size_t rem_len = hs_len - frag_off; 249611fa71b9SJerome Forissier size_t cur_hs_frag_len, max_hs_frag_len; 249711fa71b9SJerome Forissier 249811fa71b9SJerome Forissier if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) ) 249911fa71b9SJerome Forissier { 250011fa71b9SJerome Forissier if( is_finished ) 250111fa71b9SJerome Forissier { 250211fa71b9SJerome Forissier ret = ssl_swap_epochs( ssl ); 250311fa71b9SJerome Forissier if( ret != 0 ) 250411fa71b9SJerome Forissier return( ret ); 250511fa71b9SJerome Forissier } 250611fa71b9SJerome Forissier 250711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 250811fa71b9SJerome Forissier return( ret ); 250911fa71b9SJerome Forissier 251011fa71b9SJerome Forissier continue; 251111fa71b9SJerome Forissier } 251211fa71b9SJerome Forissier max_hs_frag_len = max_frag_len - 12; 251311fa71b9SJerome Forissier 251411fa71b9SJerome Forissier cur_hs_frag_len = rem_len > max_hs_frag_len ? 251511fa71b9SJerome Forissier max_hs_frag_len : rem_len; 251611fa71b9SJerome Forissier 251711fa71b9SJerome Forissier if( frag_off == 0 && cur_hs_frag_len != hs_len ) 251811fa71b9SJerome Forissier { 251911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)", 252011fa71b9SJerome Forissier (unsigned) cur_hs_frag_len, 252111fa71b9SJerome Forissier (unsigned) max_hs_frag_len ) ); 252211fa71b9SJerome Forissier } 252311fa71b9SJerome Forissier 252411fa71b9SJerome Forissier /* Messages are stored with handshake headers as if not fragmented, 252511fa71b9SJerome Forissier * copy beginning of headers then fill fragmentation fields. 252611fa71b9SJerome Forissier * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */ 252711fa71b9SJerome Forissier memcpy( ssl->out_msg, cur->p, 6 ); 252811fa71b9SJerome Forissier 252911fa71b9SJerome Forissier ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff ); 253011fa71b9SJerome Forissier ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff ); 253111fa71b9SJerome Forissier ssl->out_msg[8] = ( ( frag_off ) & 0xff ); 253211fa71b9SJerome Forissier 253311fa71b9SJerome Forissier ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff ); 253411fa71b9SJerome Forissier ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff ); 253511fa71b9SJerome Forissier ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff ); 253611fa71b9SJerome Forissier 253711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 ); 253811fa71b9SJerome Forissier 253911fa71b9SJerome Forissier /* Copy the handshake message content and set records fields */ 254011fa71b9SJerome Forissier memcpy( ssl->out_msg + 12, p, cur_hs_frag_len ); 254111fa71b9SJerome Forissier ssl->out_msglen = cur_hs_frag_len + 12; 254211fa71b9SJerome Forissier ssl->out_msgtype = cur->type; 254311fa71b9SJerome Forissier 254411fa71b9SJerome Forissier /* Update position inside current message */ 254511fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur_hs_frag_len; 254611fa71b9SJerome Forissier } 254711fa71b9SJerome Forissier 254811fa71b9SJerome Forissier /* If done with the current message move to the next one if any */ 254911fa71b9SJerome Forissier if( ssl->handshake->cur_msg_p >= cur->p + cur->len ) 255011fa71b9SJerome Forissier { 255111fa71b9SJerome Forissier if( cur->next != NULL ) 255211fa71b9SJerome Forissier { 255311fa71b9SJerome Forissier ssl->handshake->cur_msg = cur->next; 255411fa71b9SJerome Forissier ssl->handshake->cur_msg_p = cur->next->p + 12; 255511fa71b9SJerome Forissier } 255611fa71b9SJerome Forissier else 255711fa71b9SJerome Forissier { 255811fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 255911fa71b9SJerome Forissier ssl->handshake->cur_msg_p = NULL; 256011fa71b9SJerome Forissier } 256111fa71b9SJerome Forissier } 256211fa71b9SJerome Forissier 256311fa71b9SJerome Forissier /* Actually send the message out */ 256411fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 ) 256511fa71b9SJerome Forissier { 256611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 256711fa71b9SJerome Forissier return( ret ); 256811fa71b9SJerome Forissier } 256911fa71b9SJerome Forissier } 257011fa71b9SJerome Forissier 257111fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 257211fa71b9SJerome Forissier return( ret ); 257311fa71b9SJerome Forissier 257411fa71b9SJerome Forissier /* Update state and set timer */ 257511fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 257611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 257711fa71b9SJerome Forissier else 257811fa71b9SJerome Forissier { 257911fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 258011fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); 258111fa71b9SJerome Forissier } 258211fa71b9SJerome Forissier 258311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) ); 258411fa71b9SJerome Forissier 258511fa71b9SJerome Forissier return( 0 ); 258611fa71b9SJerome Forissier } 258711fa71b9SJerome Forissier 258811fa71b9SJerome Forissier /* 258911fa71b9SJerome Forissier * To be called when the last message of an incoming flight is received. 259011fa71b9SJerome Forissier */ 259111fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) 259211fa71b9SJerome Forissier { 259311fa71b9SJerome Forissier /* We won't need to resend that one any more */ 259411fa71b9SJerome Forissier mbedtls_ssl_flight_free( ssl->handshake->flight ); 259511fa71b9SJerome Forissier ssl->handshake->flight = NULL; 259611fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL; 259711fa71b9SJerome Forissier 259811fa71b9SJerome Forissier /* The next incoming flight will start with this msg_seq */ 259911fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; 260011fa71b9SJerome Forissier 260111fa71b9SJerome Forissier /* We don't want to remember CCS's across flight boundaries. */ 260211fa71b9SJerome Forissier ssl->handshake->buffering.seen_ccs = 0; 260311fa71b9SJerome Forissier 260411fa71b9SJerome Forissier /* Clear future message buffering structure. */ 260511fa71b9SJerome Forissier mbedtls_ssl_buffering_free( ssl ); 260611fa71b9SJerome Forissier 260711fa71b9SJerome Forissier /* Cancel timer */ 260811fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 260911fa71b9SJerome Forissier 261011fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 261111fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) 261211fa71b9SJerome Forissier { 261311fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 261411fa71b9SJerome Forissier } 261511fa71b9SJerome Forissier else 261611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; 261711fa71b9SJerome Forissier } 261811fa71b9SJerome Forissier 261911fa71b9SJerome Forissier /* 262011fa71b9SJerome Forissier * To be called when the last message of an outgoing flight is send. 262111fa71b9SJerome Forissier */ 262211fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) 262311fa71b9SJerome Forissier { 262411fa71b9SJerome Forissier ssl_reset_retransmit_timeout( ssl ); 262511fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); 262611fa71b9SJerome Forissier 262711fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 262811fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) 262911fa71b9SJerome Forissier { 263011fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; 263111fa71b9SJerome Forissier } 263211fa71b9SJerome Forissier else 263311fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; 263411fa71b9SJerome Forissier } 263511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 263611fa71b9SJerome Forissier 263711fa71b9SJerome Forissier /* 263811fa71b9SJerome Forissier * Handshake layer functions 263911fa71b9SJerome Forissier */ 264011fa71b9SJerome Forissier 264111fa71b9SJerome Forissier /* 264211fa71b9SJerome Forissier * Write (DTLS: or queue) current handshake (including CCS) message. 264311fa71b9SJerome Forissier * 264411fa71b9SJerome Forissier * - fill in handshake headers 264511fa71b9SJerome Forissier * - update handshake checksum 264611fa71b9SJerome Forissier * - DTLS: save message for resending 264711fa71b9SJerome Forissier * - then pass to the record layer 264811fa71b9SJerome Forissier * 264911fa71b9SJerome Forissier * DTLS: except for HelloRequest, messages are only queued, and will only be 265011fa71b9SJerome Forissier * actually sent when calling flight_transmit() or resend(). 265111fa71b9SJerome Forissier * 265211fa71b9SJerome Forissier * Inputs: 265311fa71b9SJerome Forissier * - ssl->out_msglen: 4 + actual handshake message len 265411fa71b9SJerome Forissier * (4 is the size of handshake headers for TLS) 265511fa71b9SJerome Forissier * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc) 265611fa71b9SJerome Forissier * - ssl->out_msg + 4: the handshake message body 265711fa71b9SJerome Forissier * 265811fa71b9SJerome Forissier * Outputs, ie state before passing to flight_append() or write_record(): 265911fa71b9SJerome Forissier * - ssl->out_msglen: the length of the record contents 266011fa71b9SJerome Forissier * (including handshake headers but excluding record headers) 266111fa71b9SJerome Forissier * - ssl->out_msg: the record contents (handshake headers + content) 266211fa71b9SJerome Forissier */ 266311fa71b9SJerome Forissier int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) 266411fa71b9SJerome Forissier { 266511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 266611fa71b9SJerome Forissier const size_t hs_len = ssl->out_msglen - 4; 266711fa71b9SJerome Forissier const unsigned char hs_type = ssl->out_msg[0]; 266811fa71b9SJerome Forissier 266911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) ); 267011fa71b9SJerome Forissier 267111fa71b9SJerome Forissier /* 267211fa71b9SJerome Forissier * Sanity checks 267311fa71b9SJerome Forissier */ 267411fa71b9SJerome Forissier if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && 267511fa71b9SJerome Forissier ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 267611fa71b9SJerome Forissier { 267711fa71b9SJerome Forissier /* In SSLv3, the client might send a NoCertificate alert. */ 267811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) 267911fa71b9SJerome Forissier if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && 268011fa71b9SJerome Forissier ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && 268111fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) 268211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ 268311fa71b9SJerome Forissier { 268411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 268511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 268611fa71b9SJerome Forissier } 268711fa71b9SJerome Forissier } 268811fa71b9SJerome Forissier 268911fa71b9SJerome Forissier /* Whenever we send anything different from a 269011fa71b9SJerome Forissier * HelloRequest we should be in a handshake - double check. */ 269111fa71b9SJerome Forissier if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 269211fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) && 269311fa71b9SJerome Forissier ssl->handshake == NULL ) 269411fa71b9SJerome Forissier { 269511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 269611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 269711fa71b9SJerome Forissier } 269811fa71b9SJerome Forissier 269911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 270011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 270111fa71b9SJerome Forissier ssl->handshake != NULL && 270211fa71b9SJerome Forissier ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) 270311fa71b9SJerome Forissier { 270411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 270511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 270611fa71b9SJerome Forissier } 270711fa71b9SJerome Forissier #endif 270811fa71b9SJerome Forissier 270911fa71b9SJerome Forissier /* Double-check that we did not exceed the bounds 271011fa71b9SJerome Forissier * of the outgoing record buffer. 271111fa71b9SJerome Forissier * This should never fail as the various message 271211fa71b9SJerome Forissier * writing functions must obey the bounds of the 271311fa71b9SJerome Forissier * outgoing record buffer, but better be safe. 271411fa71b9SJerome Forissier * 271511fa71b9SJerome Forissier * Note: We deliberately do not check for the MTU or MFL here. 271611fa71b9SJerome Forissier */ 271711fa71b9SJerome Forissier if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) 271811fa71b9SJerome Forissier { 271911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: " 2720*7901324dSJerome Forissier "size %" MBEDTLS_PRINTF_SIZET 2721*7901324dSJerome Forissier ", maximum %" MBEDTLS_PRINTF_SIZET, 2722*7901324dSJerome Forissier ssl->out_msglen, 2723*7901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) ); 272411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 272511fa71b9SJerome Forissier } 272611fa71b9SJerome Forissier 272711fa71b9SJerome Forissier /* 272811fa71b9SJerome Forissier * Fill handshake headers 272911fa71b9SJerome Forissier */ 273011fa71b9SJerome Forissier if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 273111fa71b9SJerome Forissier { 273211fa71b9SJerome Forissier ssl->out_msg[1] = (unsigned char)( hs_len >> 16 ); 273311fa71b9SJerome Forissier ssl->out_msg[2] = (unsigned char)( hs_len >> 8 ); 273411fa71b9SJerome Forissier ssl->out_msg[3] = (unsigned char)( hs_len ); 273511fa71b9SJerome Forissier 273611fa71b9SJerome Forissier /* 273711fa71b9SJerome Forissier * DTLS has additional fields in the Handshake layer, 273811fa71b9SJerome Forissier * between the length field and the actual payload: 273911fa71b9SJerome Forissier * uint16 message_seq; 274011fa71b9SJerome Forissier * uint24 fragment_offset; 274111fa71b9SJerome Forissier * uint24 fragment_length; 274211fa71b9SJerome Forissier */ 274311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 274411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 274511fa71b9SJerome Forissier { 274611fa71b9SJerome Forissier /* Make room for the additional DTLS fields */ 274711fa71b9SJerome Forissier if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) 274811fa71b9SJerome Forissier { 274911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " 2750*7901324dSJerome Forissier "size %" MBEDTLS_PRINTF_SIZET ", maximum %" MBEDTLS_PRINTF_SIZET, 2751*7901324dSJerome Forissier hs_len, 2752*7901324dSJerome Forissier (size_t) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); 275311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 275411fa71b9SJerome Forissier } 275511fa71b9SJerome Forissier 275611fa71b9SJerome Forissier memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len ); 275711fa71b9SJerome Forissier ssl->out_msglen += 8; 275811fa71b9SJerome Forissier 275911fa71b9SJerome Forissier /* Write message_seq and update it, except for HelloRequest */ 276011fa71b9SJerome Forissier if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) 276111fa71b9SJerome Forissier { 276211fa71b9SJerome Forissier ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; 276311fa71b9SJerome Forissier ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; 276411fa71b9SJerome Forissier ++( ssl->handshake->out_msg_seq ); 276511fa71b9SJerome Forissier } 276611fa71b9SJerome Forissier else 276711fa71b9SJerome Forissier { 276811fa71b9SJerome Forissier ssl->out_msg[4] = 0; 276911fa71b9SJerome Forissier ssl->out_msg[5] = 0; 277011fa71b9SJerome Forissier } 277111fa71b9SJerome Forissier 277211fa71b9SJerome Forissier /* Handshake hashes are computed without fragmentation, 277311fa71b9SJerome Forissier * so set frag_offset = 0 and frag_len = hs_len for now */ 277411fa71b9SJerome Forissier memset( ssl->out_msg + 6, 0x00, 3 ); 277511fa71b9SJerome Forissier memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); 277611fa71b9SJerome Forissier } 277711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 277811fa71b9SJerome Forissier 277911fa71b9SJerome Forissier /* Update running hashes of handshake messages seen */ 278011fa71b9SJerome Forissier if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) 278111fa71b9SJerome Forissier ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen ); 278211fa71b9SJerome Forissier } 278311fa71b9SJerome Forissier 278411fa71b9SJerome Forissier /* Either send now, or just save to be sent (and resent) later */ 278511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 278611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 278711fa71b9SJerome Forissier ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 278811fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) ) 278911fa71b9SJerome Forissier { 279011fa71b9SJerome Forissier if( ( ret = ssl_flight_append( ssl ) ) != 0 ) 279111fa71b9SJerome Forissier { 279211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); 279311fa71b9SJerome Forissier return( ret ); 279411fa71b9SJerome Forissier } 279511fa71b9SJerome Forissier } 279611fa71b9SJerome Forissier else 279711fa71b9SJerome Forissier #endif 279811fa71b9SJerome Forissier { 279911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 280011fa71b9SJerome Forissier { 280111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret ); 280211fa71b9SJerome Forissier return( ret ); 280311fa71b9SJerome Forissier } 280411fa71b9SJerome Forissier } 280511fa71b9SJerome Forissier 280611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) ); 280711fa71b9SJerome Forissier 280811fa71b9SJerome Forissier return( 0 ); 280911fa71b9SJerome Forissier } 281011fa71b9SJerome Forissier 281111fa71b9SJerome Forissier /* 281211fa71b9SJerome Forissier * Record layer functions 281311fa71b9SJerome Forissier */ 281411fa71b9SJerome Forissier 281511fa71b9SJerome Forissier /* 281611fa71b9SJerome Forissier * Write current record. 281711fa71b9SJerome Forissier * 281811fa71b9SJerome Forissier * Uses: 281911fa71b9SJerome Forissier * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS) 282011fa71b9SJerome Forissier * - ssl->out_msglen: length of the record content (excl headers) 282111fa71b9SJerome Forissier * - ssl->out_msg: record content 282211fa71b9SJerome Forissier */ 282311fa71b9SJerome Forissier int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) 282411fa71b9SJerome Forissier { 282511fa71b9SJerome Forissier int ret, done = 0; 282611fa71b9SJerome Forissier size_t len = ssl->out_msglen; 282711fa71b9SJerome Forissier uint8_t flush = force_flush; 282811fa71b9SJerome Forissier 282911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); 283011fa71b9SJerome Forissier 283111fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 283211fa71b9SJerome Forissier if( ssl->transform_out != NULL && 283311fa71b9SJerome Forissier ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) 283411fa71b9SJerome Forissier { 283511fa71b9SJerome Forissier if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) 283611fa71b9SJerome Forissier { 283711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); 283811fa71b9SJerome Forissier return( ret ); 283911fa71b9SJerome Forissier } 284011fa71b9SJerome Forissier 284111fa71b9SJerome Forissier len = ssl->out_msglen; 284211fa71b9SJerome Forissier } 284311fa71b9SJerome Forissier #endif /*MBEDTLS_ZLIB_SUPPORT */ 284411fa71b9SJerome Forissier 284511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 284611fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_write != NULL ) 284711fa71b9SJerome Forissier { 284811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); 284911fa71b9SJerome Forissier 285011fa71b9SJerome Forissier ret = mbedtls_ssl_hw_record_write( ssl ); 285111fa71b9SJerome Forissier if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) 285211fa71b9SJerome Forissier { 285311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); 285411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 285511fa71b9SJerome Forissier } 285611fa71b9SJerome Forissier 285711fa71b9SJerome Forissier if( ret == 0 ) 285811fa71b9SJerome Forissier done = 1; 285911fa71b9SJerome Forissier } 286011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 286111fa71b9SJerome Forissier if( !done ) 286211fa71b9SJerome Forissier { 286311fa71b9SJerome Forissier unsigned i; 286411fa71b9SJerome Forissier size_t protected_record_size; 286511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 286611fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len; 286711fa71b9SJerome Forissier #else 286811fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN; 286911fa71b9SJerome Forissier #endif 287011fa71b9SJerome Forissier /* Skip writing the record content type to after the encryption, 287111fa71b9SJerome Forissier * as it may change when using the CID extension. */ 287211fa71b9SJerome Forissier 287311fa71b9SJerome Forissier mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, 287411fa71b9SJerome Forissier ssl->conf->transport, ssl->out_hdr + 1 ); 287511fa71b9SJerome Forissier 287611fa71b9SJerome Forissier memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 ); 287711fa71b9SJerome Forissier ssl->out_len[0] = (unsigned char)( len >> 8 ); 287811fa71b9SJerome Forissier ssl->out_len[1] = (unsigned char)( len ); 287911fa71b9SJerome Forissier 288011fa71b9SJerome Forissier if( ssl->transform_out != NULL ) 288111fa71b9SJerome Forissier { 288211fa71b9SJerome Forissier mbedtls_record rec; 288311fa71b9SJerome Forissier 288411fa71b9SJerome Forissier rec.buf = ssl->out_iv; 288511fa71b9SJerome Forissier rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf ); 288611fa71b9SJerome Forissier rec.data_len = ssl->out_msglen; 288711fa71b9SJerome Forissier rec.data_offset = ssl->out_msg - rec.buf; 288811fa71b9SJerome Forissier 288911fa71b9SJerome Forissier memcpy( &rec.ctr[0], ssl->out_ctr, 8 ); 289011fa71b9SJerome Forissier mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, 289111fa71b9SJerome Forissier ssl->conf->transport, rec.ver ); 289211fa71b9SJerome Forissier rec.type = ssl->out_msgtype; 289311fa71b9SJerome Forissier 289411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 289511fa71b9SJerome Forissier /* The CID is set by mbedtls_ssl_encrypt_buf(). */ 289611fa71b9SJerome Forissier rec.cid_len = 0; 289711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 289811fa71b9SJerome Forissier 289911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec, 290011fa71b9SJerome Forissier ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) 290111fa71b9SJerome Forissier { 290211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); 290311fa71b9SJerome Forissier return( ret ); 290411fa71b9SJerome Forissier } 290511fa71b9SJerome Forissier 290611fa71b9SJerome Forissier if( rec.data_offset != 0 ) 290711fa71b9SJerome Forissier { 290811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 290911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 291011fa71b9SJerome Forissier } 291111fa71b9SJerome Forissier 291211fa71b9SJerome Forissier /* Update the record content type and CID. */ 291311fa71b9SJerome Forissier ssl->out_msgtype = rec.type; 291411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID ) 291511fa71b9SJerome Forissier memcpy( ssl->out_cid, rec.cid, rec.cid_len ); 291611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 291711fa71b9SJerome Forissier ssl->out_msglen = len = rec.data_len; 291811fa71b9SJerome Forissier ssl->out_len[0] = (unsigned char)( rec.data_len >> 8 ); 291911fa71b9SJerome Forissier ssl->out_len[1] = (unsigned char)( rec.data_len ); 292011fa71b9SJerome Forissier } 292111fa71b9SJerome Forissier 292211fa71b9SJerome Forissier protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl ); 292311fa71b9SJerome Forissier 292411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 292511fa71b9SJerome Forissier /* In case of DTLS, double-check that we don't exceed 292611fa71b9SJerome Forissier * the remaining space in the datagram. */ 292711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 292811fa71b9SJerome Forissier { 292911fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram( ssl ); 293011fa71b9SJerome Forissier if( ret < 0 ) 293111fa71b9SJerome Forissier return( ret ); 293211fa71b9SJerome Forissier 293311fa71b9SJerome Forissier if( protected_record_size > (size_t) ret ) 293411fa71b9SJerome Forissier { 293511fa71b9SJerome Forissier /* Should never happen */ 293611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 293711fa71b9SJerome Forissier } 293811fa71b9SJerome Forissier } 293911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 294011fa71b9SJerome Forissier 294111fa71b9SJerome Forissier /* Now write the potentially updated record content type. */ 294211fa71b9SJerome Forissier ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; 294311fa71b9SJerome Forissier 2944*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %u, " 2945*7901324dSJerome Forissier "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET, 294611fa71b9SJerome Forissier ssl->out_hdr[0], ssl->out_hdr[1], 294711fa71b9SJerome Forissier ssl->out_hdr[2], len ) ); 294811fa71b9SJerome Forissier 294911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", 295011fa71b9SJerome Forissier ssl->out_hdr, protected_record_size ); 295111fa71b9SJerome Forissier 295211fa71b9SJerome Forissier ssl->out_left += protected_record_size; 295311fa71b9SJerome Forissier ssl->out_hdr += protected_record_size; 295411fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out ); 295511fa71b9SJerome Forissier 295611fa71b9SJerome Forissier for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- ) 295711fa71b9SJerome Forissier if( ++ssl->cur_out_ctr[i - 1] != 0 ) 295811fa71b9SJerome Forissier break; 295911fa71b9SJerome Forissier 296011fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */ 296111fa71b9SJerome Forissier if( i == mbedtls_ssl_ep_len( ssl ) ) 296211fa71b9SJerome Forissier { 296311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); 296411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 296511fa71b9SJerome Forissier } 296611fa71b9SJerome Forissier } 296711fa71b9SJerome Forissier 296811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 296911fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 297011fa71b9SJerome Forissier flush == SSL_DONT_FORCE_FLUSH ) 297111fa71b9SJerome Forissier { 297211fa71b9SJerome Forissier size_t remaining; 297311fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram( ssl ); 297411fa71b9SJerome Forissier if( ret < 0 ) 297511fa71b9SJerome Forissier { 297611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram", 297711fa71b9SJerome Forissier ret ); 297811fa71b9SJerome Forissier return( ret ); 297911fa71b9SJerome Forissier } 298011fa71b9SJerome Forissier 298111fa71b9SJerome Forissier remaining = (size_t) ret; 298211fa71b9SJerome Forissier if( remaining == 0 ) 298311fa71b9SJerome Forissier { 298411fa71b9SJerome Forissier flush = SSL_FORCE_FLUSH; 298511fa71b9SJerome Forissier } 298611fa71b9SJerome Forissier else 298711fa71b9SJerome Forissier { 298811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) ); 298911fa71b9SJerome Forissier } 299011fa71b9SJerome Forissier } 299111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 299211fa71b9SJerome Forissier 299311fa71b9SJerome Forissier if( ( flush == SSL_FORCE_FLUSH ) && 299411fa71b9SJerome Forissier ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 299511fa71b9SJerome Forissier { 299611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); 299711fa71b9SJerome Forissier return( ret ); 299811fa71b9SJerome Forissier } 299911fa71b9SJerome Forissier 300011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); 300111fa71b9SJerome Forissier 300211fa71b9SJerome Forissier return( 0 ); 300311fa71b9SJerome Forissier } 300411fa71b9SJerome Forissier 300511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 300611fa71b9SJerome Forissier 300711fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl ) 300811fa71b9SJerome Forissier { 300911fa71b9SJerome Forissier if( ssl->in_msglen < ssl->in_hslen || 301011fa71b9SJerome Forissier memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || 301111fa71b9SJerome Forissier memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 ) 301211fa71b9SJerome Forissier { 301311fa71b9SJerome Forissier return( 1 ); 301411fa71b9SJerome Forissier } 301511fa71b9SJerome Forissier return( 0 ); 301611fa71b9SJerome Forissier } 301711fa71b9SJerome Forissier 301811fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl ) 301911fa71b9SJerome Forissier { 302011fa71b9SJerome Forissier return( ( ssl->in_msg[9] << 16 ) | 302111fa71b9SJerome Forissier ( ssl->in_msg[10] << 8 ) | 302211fa71b9SJerome Forissier ssl->in_msg[11] ); 302311fa71b9SJerome Forissier } 302411fa71b9SJerome Forissier 302511fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl ) 302611fa71b9SJerome Forissier { 302711fa71b9SJerome Forissier return( ( ssl->in_msg[6] << 16 ) | 302811fa71b9SJerome Forissier ( ssl->in_msg[7] << 8 ) | 302911fa71b9SJerome Forissier ssl->in_msg[8] ); 303011fa71b9SJerome Forissier } 303111fa71b9SJerome Forissier 303211fa71b9SJerome Forissier static int ssl_check_hs_header( mbedtls_ssl_context const *ssl ) 303311fa71b9SJerome Forissier { 303411fa71b9SJerome Forissier uint32_t msg_len, frag_off, frag_len; 303511fa71b9SJerome Forissier 303611fa71b9SJerome Forissier msg_len = ssl_get_hs_total_len( ssl ); 303711fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off( ssl ); 303811fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len( ssl ); 303911fa71b9SJerome Forissier 304011fa71b9SJerome Forissier if( frag_off > msg_len ) 304111fa71b9SJerome Forissier return( -1 ); 304211fa71b9SJerome Forissier 304311fa71b9SJerome Forissier if( frag_len > msg_len - frag_off ) 304411fa71b9SJerome Forissier return( -1 ); 304511fa71b9SJerome Forissier 304611fa71b9SJerome Forissier if( frag_len + 12 > ssl->in_msglen ) 304711fa71b9SJerome Forissier return( -1 ); 304811fa71b9SJerome Forissier 304911fa71b9SJerome Forissier return( 0 ); 305011fa71b9SJerome Forissier } 305111fa71b9SJerome Forissier 305211fa71b9SJerome Forissier /* 305311fa71b9SJerome Forissier * Mark bits in bitmask (used for DTLS HS reassembly) 305411fa71b9SJerome Forissier */ 305511fa71b9SJerome Forissier static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) 305611fa71b9SJerome Forissier { 305711fa71b9SJerome Forissier unsigned int start_bits, end_bits; 305811fa71b9SJerome Forissier 305911fa71b9SJerome Forissier start_bits = 8 - ( offset % 8 ); 306011fa71b9SJerome Forissier if( start_bits != 8 ) 306111fa71b9SJerome Forissier { 306211fa71b9SJerome Forissier size_t first_byte_idx = offset / 8; 306311fa71b9SJerome Forissier 306411fa71b9SJerome Forissier /* Special case */ 306511fa71b9SJerome Forissier if( len <= start_bits ) 306611fa71b9SJerome Forissier { 306711fa71b9SJerome Forissier for( ; len != 0; len-- ) 306811fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << ( start_bits - len ); 306911fa71b9SJerome Forissier 307011fa71b9SJerome Forissier /* Avoid potential issues with offset or len becoming invalid */ 307111fa71b9SJerome Forissier return; 307211fa71b9SJerome Forissier } 307311fa71b9SJerome Forissier 307411fa71b9SJerome Forissier offset += start_bits; /* Now offset % 8 == 0 */ 307511fa71b9SJerome Forissier len -= start_bits; 307611fa71b9SJerome Forissier 307711fa71b9SJerome Forissier for( ; start_bits != 0; start_bits-- ) 307811fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << ( start_bits - 1 ); 307911fa71b9SJerome Forissier } 308011fa71b9SJerome Forissier 308111fa71b9SJerome Forissier end_bits = len % 8; 308211fa71b9SJerome Forissier if( end_bits != 0 ) 308311fa71b9SJerome Forissier { 308411fa71b9SJerome Forissier size_t last_byte_idx = ( offset + len ) / 8; 308511fa71b9SJerome Forissier 308611fa71b9SJerome Forissier len -= end_bits; /* Now len % 8 == 0 */ 308711fa71b9SJerome Forissier 308811fa71b9SJerome Forissier for( ; end_bits != 0; end_bits-- ) 308911fa71b9SJerome Forissier mask[last_byte_idx] |= 1 << ( 8 - end_bits ); 309011fa71b9SJerome Forissier } 309111fa71b9SJerome Forissier 309211fa71b9SJerome Forissier memset( mask + offset / 8, 0xFF, len / 8 ); 309311fa71b9SJerome Forissier } 309411fa71b9SJerome Forissier 309511fa71b9SJerome Forissier /* 309611fa71b9SJerome Forissier * Check that bitmask is full 309711fa71b9SJerome Forissier */ 309811fa71b9SJerome Forissier static int ssl_bitmask_check( unsigned char *mask, size_t len ) 309911fa71b9SJerome Forissier { 310011fa71b9SJerome Forissier size_t i; 310111fa71b9SJerome Forissier 310211fa71b9SJerome Forissier for( i = 0; i < len / 8; i++ ) 310311fa71b9SJerome Forissier if( mask[i] != 0xFF ) 310411fa71b9SJerome Forissier return( -1 ); 310511fa71b9SJerome Forissier 310611fa71b9SJerome Forissier for( i = 0; i < len % 8; i++ ) 310711fa71b9SJerome Forissier if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) 310811fa71b9SJerome Forissier return( -1 ); 310911fa71b9SJerome Forissier 311011fa71b9SJerome Forissier return( 0 ); 311111fa71b9SJerome Forissier } 311211fa71b9SJerome Forissier 311311fa71b9SJerome Forissier /* msg_len does not include the handshake header */ 311411fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size( size_t msg_len, 311511fa71b9SJerome Forissier unsigned add_bitmap ) 311611fa71b9SJerome Forissier { 311711fa71b9SJerome Forissier size_t alloc_len; 311811fa71b9SJerome Forissier 311911fa71b9SJerome Forissier alloc_len = 12; /* Handshake header */ 312011fa71b9SJerome Forissier alloc_len += msg_len; /* Content buffer */ 312111fa71b9SJerome Forissier 312211fa71b9SJerome Forissier if( add_bitmap ) 312311fa71b9SJerome Forissier alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */ 312411fa71b9SJerome Forissier 312511fa71b9SJerome Forissier return( alloc_len ); 312611fa71b9SJerome Forissier } 312711fa71b9SJerome Forissier 312811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 312911fa71b9SJerome Forissier 313011fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl ) 313111fa71b9SJerome Forissier { 313211fa71b9SJerome Forissier return( ( ssl->in_msg[1] << 16 ) | 313311fa71b9SJerome Forissier ( ssl->in_msg[2] << 8 ) | 313411fa71b9SJerome Forissier ssl->in_msg[3] ); 313511fa71b9SJerome Forissier } 313611fa71b9SJerome Forissier 313711fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) 313811fa71b9SJerome Forissier { 313911fa71b9SJerome Forissier if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) 314011fa71b9SJerome Forissier { 3141*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %" MBEDTLS_PRINTF_SIZET, 314211fa71b9SJerome Forissier ssl->in_msglen ) ); 314311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 314411fa71b9SJerome Forissier } 314511fa71b9SJerome Forissier 314611fa71b9SJerome Forissier ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl ); 314711fa71b9SJerome Forissier 314811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" 3149*7901324dSJerome Forissier " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET, 315011fa71b9SJerome Forissier ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); 315111fa71b9SJerome Forissier 315211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 315311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 315411fa71b9SJerome Forissier { 315511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 315611fa71b9SJerome Forissier unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; 315711fa71b9SJerome Forissier 315811fa71b9SJerome Forissier if( ssl_check_hs_header( ssl ) != 0 ) 315911fa71b9SJerome Forissier { 316011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) ); 316111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 316211fa71b9SJerome Forissier } 316311fa71b9SJerome Forissier 316411fa71b9SJerome Forissier if( ssl->handshake != NULL && 316511fa71b9SJerome Forissier ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && 316611fa71b9SJerome Forissier recv_msg_seq != ssl->handshake->in_msg_seq ) || 316711fa71b9SJerome Forissier ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && 316811fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) ) 316911fa71b9SJerome Forissier { 317011fa71b9SJerome Forissier if( recv_msg_seq > ssl->handshake->in_msg_seq ) 317111fa71b9SJerome Forissier { 317211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)", 317311fa71b9SJerome Forissier recv_msg_seq, 317411fa71b9SJerome Forissier ssl->handshake->in_msg_seq ) ); 317511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 317611fa71b9SJerome Forissier } 317711fa71b9SJerome Forissier 317811fa71b9SJerome Forissier /* Retransmit only on last message from previous flight, to avoid 317911fa71b9SJerome Forissier * too many retransmissions. 318011fa71b9SJerome Forissier * Besides, No sane server ever retransmits HelloVerifyRequest */ 318111fa71b9SJerome Forissier if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && 318211fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) 318311fa71b9SJerome Forissier { 318411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " 3185*7901324dSJerome Forissier "message_seq = %u, start_of_flight = %u", 318611fa71b9SJerome Forissier recv_msg_seq, 318711fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq ) ); 318811fa71b9SJerome Forissier 318911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) 319011fa71b9SJerome Forissier { 319111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); 319211fa71b9SJerome Forissier return( ret ); 319311fa71b9SJerome Forissier } 319411fa71b9SJerome Forissier } 319511fa71b9SJerome Forissier else 319611fa71b9SJerome Forissier { 319711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " 3198*7901324dSJerome Forissier "message_seq = %u, expected = %u", 319911fa71b9SJerome Forissier recv_msg_seq, 320011fa71b9SJerome Forissier ssl->handshake->in_msg_seq ) ); 320111fa71b9SJerome Forissier } 320211fa71b9SJerome Forissier 320311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 320411fa71b9SJerome Forissier } 320511fa71b9SJerome Forissier /* Wait until message completion to increment in_msg_seq */ 320611fa71b9SJerome Forissier 320711fa71b9SJerome Forissier /* Message reassembly is handled alongside buffering of future 320811fa71b9SJerome Forissier * messages; the commonality is that both handshake fragments and 320911fa71b9SJerome Forissier * future messages cannot be forwarded immediately to the 321011fa71b9SJerome Forissier * handshake logic layer. */ 321111fa71b9SJerome Forissier if( ssl_hs_is_proper_fragment( ssl ) == 1 ) 321211fa71b9SJerome Forissier { 321311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); 321411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 321511fa71b9SJerome Forissier } 321611fa71b9SJerome Forissier } 321711fa71b9SJerome Forissier else 321811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 321911fa71b9SJerome Forissier /* With TLS we don't handle fragmentation (for now) */ 322011fa71b9SJerome Forissier if( ssl->in_msglen < ssl->in_hslen ) 322111fa71b9SJerome Forissier { 322211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); 322311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 322411fa71b9SJerome Forissier } 322511fa71b9SJerome Forissier 322611fa71b9SJerome Forissier return( 0 ); 322711fa71b9SJerome Forissier } 322811fa71b9SJerome Forissier 322911fa71b9SJerome Forissier void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) 323011fa71b9SJerome Forissier { 323111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 323211fa71b9SJerome Forissier 323311fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL ) 323411fa71b9SJerome Forissier { 323511fa71b9SJerome Forissier ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); 323611fa71b9SJerome Forissier } 323711fa71b9SJerome Forissier 323811fa71b9SJerome Forissier /* Handshake message is complete, increment counter */ 323911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 324011fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 324111fa71b9SJerome Forissier ssl->handshake != NULL ) 324211fa71b9SJerome Forissier { 324311fa71b9SJerome Forissier unsigned offset; 324411fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 324511fa71b9SJerome Forissier 324611fa71b9SJerome Forissier /* Increment handshake sequence number */ 324711fa71b9SJerome Forissier hs->in_msg_seq++; 324811fa71b9SJerome Forissier 324911fa71b9SJerome Forissier /* 325011fa71b9SJerome Forissier * Clear up handshake buffering and reassembly structure. 325111fa71b9SJerome Forissier */ 325211fa71b9SJerome Forissier 325311fa71b9SJerome Forissier /* Free first entry */ 325411fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, 0 ); 325511fa71b9SJerome Forissier 325611fa71b9SJerome Forissier /* Shift all other entries */ 325711fa71b9SJerome Forissier for( offset = 0, hs_buf = &hs->buffering.hs[0]; 325811fa71b9SJerome Forissier offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; 325911fa71b9SJerome Forissier offset++, hs_buf++ ) 326011fa71b9SJerome Forissier { 326111fa71b9SJerome Forissier *hs_buf = *(hs_buf + 1); 326211fa71b9SJerome Forissier } 326311fa71b9SJerome Forissier 326411fa71b9SJerome Forissier /* Create a fresh last entry */ 326511fa71b9SJerome Forissier memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); 326611fa71b9SJerome Forissier } 326711fa71b9SJerome Forissier #endif 326811fa71b9SJerome Forissier } 326911fa71b9SJerome Forissier 327011fa71b9SJerome Forissier /* 327111fa71b9SJerome Forissier * DTLS anti-replay: RFC 6347 4.1.2.6 327211fa71b9SJerome Forissier * 327311fa71b9SJerome Forissier * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). 327411fa71b9SJerome Forissier * Bit n is set iff record number in_window_top - n has been seen. 327511fa71b9SJerome Forissier * 327611fa71b9SJerome Forissier * Usually, in_window_top is the last record number seen and the lsb of 327711fa71b9SJerome Forissier * in_window is set. The only exception is the initial state (record number 0 327811fa71b9SJerome Forissier * not seen yet). 327911fa71b9SJerome Forissier */ 328011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 328111fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) 328211fa71b9SJerome Forissier { 328311fa71b9SJerome Forissier ssl->in_window_top = 0; 328411fa71b9SJerome Forissier ssl->in_window = 0; 328511fa71b9SJerome Forissier } 328611fa71b9SJerome Forissier 328711fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) 328811fa71b9SJerome Forissier { 328911fa71b9SJerome Forissier return( ( (uint64_t) buf[0] << 40 ) | 329011fa71b9SJerome Forissier ( (uint64_t) buf[1] << 32 ) | 329111fa71b9SJerome Forissier ( (uint64_t) buf[2] << 24 ) | 329211fa71b9SJerome Forissier ( (uint64_t) buf[3] << 16 ) | 329311fa71b9SJerome Forissier ( (uint64_t) buf[4] << 8 ) | 329411fa71b9SJerome Forissier ( (uint64_t) buf[5] ) ); 329511fa71b9SJerome Forissier } 329611fa71b9SJerome Forissier 329711fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr ) 329811fa71b9SJerome Forissier { 329911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 330011fa71b9SJerome Forissier unsigned char *original_in_ctr; 330111fa71b9SJerome Forissier 330211fa71b9SJerome Forissier // save original in_ctr 330311fa71b9SJerome Forissier original_in_ctr = ssl->in_ctr; 330411fa71b9SJerome Forissier 330511fa71b9SJerome Forissier // use counter from record 330611fa71b9SJerome Forissier ssl->in_ctr = record_in_ctr; 330711fa71b9SJerome Forissier 330811fa71b9SJerome Forissier ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl ); 330911fa71b9SJerome Forissier 331011fa71b9SJerome Forissier // restore the counter 331111fa71b9SJerome Forissier ssl->in_ctr = original_in_ctr; 331211fa71b9SJerome Forissier 331311fa71b9SJerome Forissier return ret; 331411fa71b9SJerome Forissier } 331511fa71b9SJerome Forissier 331611fa71b9SJerome Forissier /* 331711fa71b9SJerome Forissier * Return 0 if sequence number is acceptable, -1 otherwise 331811fa71b9SJerome Forissier */ 331911fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl ) 332011fa71b9SJerome Forissier { 332111fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); 332211fa71b9SJerome Forissier uint64_t bit; 332311fa71b9SJerome Forissier 332411fa71b9SJerome Forissier if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) 332511fa71b9SJerome Forissier return( 0 ); 332611fa71b9SJerome Forissier 332711fa71b9SJerome Forissier if( rec_seqnum > ssl->in_window_top ) 332811fa71b9SJerome Forissier return( 0 ); 332911fa71b9SJerome Forissier 333011fa71b9SJerome Forissier bit = ssl->in_window_top - rec_seqnum; 333111fa71b9SJerome Forissier 333211fa71b9SJerome Forissier if( bit >= 64 ) 333311fa71b9SJerome Forissier return( -1 ); 333411fa71b9SJerome Forissier 333511fa71b9SJerome Forissier if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) 333611fa71b9SJerome Forissier return( -1 ); 333711fa71b9SJerome Forissier 333811fa71b9SJerome Forissier return( 0 ); 333911fa71b9SJerome Forissier } 334011fa71b9SJerome Forissier 334111fa71b9SJerome Forissier /* 334211fa71b9SJerome Forissier * Update replay window on new validated record 334311fa71b9SJerome Forissier */ 334411fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) 334511fa71b9SJerome Forissier { 334611fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); 334711fa71b9SJerome Forissier 334811fa71b9SJerome Forissier if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) 334911fa71b9SJerome Forissier return; 335011fa71b9SJerome Forissier 335111fa71b9SJerome Forissier if( rec_seqnum > ssl->in_window_top ) 335211fa71b9SJerome Forissier { 335311fa71b9SJerome Forissier /* Update window_top and the contents of the window */ 335411fa71b9SJerome Forissier uint64_t shift = rec_seqnum - ssl->in_window_top; 335511fa71b9SJerome Forissier 335611fa71b9SJerome Forissier if( shift >= 64 ) 335711fa71b9SJerome Forissier ssl->in_window = 1; 335811fa71b9SJerome Forissier else 335911fa71b9SJerome Forissier { 336011fa71b9SJerome Forissier ssl->in_window <<= shift; 336111fa71b9SJerome Forissier ssl->in_window |= 1; 336211fa71b9SJerome Forissier } 336311fa71b9SJerome Forissier 336411fa71b9SJerome Forissier ssl->in_window_top = rec_seqnum; 336511fa71b9SJerome Forissier } 336611fa71b9SJerome Forissier else 336711fa71b9SJerome Forissier { 336811fa71b9SJerome Forissier /* Mark that number as seen in the current window */ 336911fa71b9SJerome Forissier uint64_t bit = ssl->in_window_top - rec_seqnum; 337011fa71b9SJerome Forissier 337111fa71b9SJerome Forissier if( bit < 64 ) /* Always true, but be extra sure */ 337211fa71b9SJerome Forissier ssl->in_window |= (uint64_t) 1 << bit; 337311fa71b9SJerome Forissier } 337411fa71b9SJerome Forissier } 337511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ 337611fa71b9SJerome Forissier 337711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 337811fa71b9SJerome Forissier /* 337911fa71b9SJerome Forissier * Without any SSL context, check if a datagram looks like a ClientHello with 338011fa71b9SJerome Forissier * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. 338111fa71b9SJerome Forissier * Both input and output include full DTLS headers. 338211fa71b9SJerome Forissier * 338311fa71b9SJerome Forissier * - if cookie is valid, return 0 338411fa71b9SJerome Forissier * - if ClientHello looks superficially valid but cookie is not, 338511fa71b9SJerome Forissier * fill obuf and set olen, then 338611fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED 338711fa71b9SJerome Forissier * - otherwise return a specific error code 338811fa71b9SJerome Forissier */ 338911fa71b9SJerome Forissier static int ssl_check_dtls_clihlo_cookie( 339011fa71b9SJerome Forissier mbedtls_ssl_cookie_write_t *f_cookie_write, 339111fa71b9SJerome Forissier mbedtls_ssl_cookie_check_t *f_cookie_check, 339211fa71b9SJerome Forissier void *p_cookie, 339311fa71b9SJerome Forissier const unsigned char *cli_id, size_t cli_id_len, 339411fa71b9SJerome Forissier const unsigned char *in, size_t in_len, 339511fa71b9SJerome Forissier unsigned char *obuf, size_t buf_len, size_t *olen ) 339611fa71b9SJerome Forissier { 339711fa71b9SJerome Forissier size_t sid_len, cookie_len; 339811fa71b9SJerome Forissier unsigned char *p; 339911fa71b9SJerome Forissier 340011fa71b9SJerome Forissier /* 340111fa71b9SJerome Forissier * Structure of ClientHello with record and handshake headers, 340211fa71b9SJerome Forissier * and expected values. We don't need to check a lot, more checks will be 340311fa71b9SJerome Forissier * done when actually parsing the ClientHello - skipping those checks 340411fa71b9SJerome Forissier * avoids code duplication and does not make cookie forging any easier. 340511fa71b9SJerome Forissier * 340611fa71b9SJerome Forissier * 0-0 ContentType type; copied, must be handshake 340711fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 340811fa71b9SJerome Forissier * 3-4 uint16 epoch; copied, must be 0 340911fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 341011fa71b9SJerome Forissier * 11-12 uint16 length; (ignored) 341111fa71b9SJerome Forissier * 341211fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; (ignored) 341311fa71b9SJerome Forissier * 14-16 uint24 length; (ignored) 341411fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 341511fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied, must be 0 341611fa71b9SJerome Forissier * 22-24 uint24 fragment_length; (ignored) 341711fa71b9SJerome Forissier * 341811fa71b9SJerome Forissier * 25-26 ProtocolVersion client_version; (ignored) 341911fa71b9SJerome Forissier * 27-58 Random random; (ignored) 342011fa71b9SJerome Forissier * 59-xx SessionID session_id; 1 byte len + sid_len content 342111fa71b9SJerome Forissier * 60+ opaque cookie<0..2^8-1>; 1 byte len + content 342211fa71b9SJerome Forissier * ... 342311fa71b9SJerome Forissier * 342411fa71b9SJerome Forissier * Minimum length is 61 bytes. 342511fa71b9SJerome Forissier */ 342611fa71b9SJerome Forissier if( in_len < 61 || 342711fa71b9SJerome Forissier in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || 342811fa71b9SJerome Forissier in[3] != 0 || in[4] != 0 || 342911fa71b9SJerome Forissier in[19] != 0 || in[20] != 0 || in[21] != 0 ) 343011fa71b9SJerome Forissier { 343111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 343211fa71b9SJerome Forissier } 343311fa71b9SJerome Forissier 343411fa71b9SJerome Forissier sid_len = in[59]; 343511fa71b9SJerome Forissier if( sid_len > in_len - 61 ) 343611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 343711fa71b9SJerome Forissier 343811fa71b9SJerome Forissier cookie_len = in[60 + sid_len]; 343911fa71b9SJerome Forissier if( cookie_len > in_len - 60 ) 344011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); 344111fa71b9SJerome Forissier 344211fa71b9SJerome Forissier if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, 344311fa71b9SJerome Forissier cli_id, cli_id_len ) == 0 ) 344411fa71b9SJerome Forissier { 344511fa71b9SJerome Forissier /* Valid cookie */ 344611fa71b9SJerome Forissier return( 0 ); 344711fa71b9SJerome Forissier } 344811fa71b9SJerome Forissier 344911fa71b9SJerome Forissier /* 345011fa71b9SJerome Forissier * If we get here, we've got an invalid cookie, let's prepare HVR. 345111fa71b9SJerome Forissier * 345211fa71b9SJerome Forissier * 0-0 ContentType type; copied 345311fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied 345411fa71b9SJerome Forissier * 3-4 uint16 epoch; copied 345511fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied 345611fa71b9SJerome Forissier * 11-12 uint16 length; olen - 13 345711fa71b9SJerome Forissier * 345811fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; hello_verify_request 345911fa71b9SJerome Forissier * 14-16 uint24 length; olen - 25 346011fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied 346111fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied 346211fa71b9SJerome Forissier * 22-24 uint24 fragment_length; olen - 25 346311fa71b9SJerome Forissier * 346411fa71b9SJerome Forissier * 25-26 ProtocolVersion server_version; 0xfe 0xff 346511fa71b9SJerome Forissier * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie 346611fa71b9SJerome Forissier * 346711fa71b9SJerome Forissier * Minimum length is 28. 346811fa71b9SJerome Forissier */ 346911fa71b9SJerome Forissier if( buf_len < 28 ) 347011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); 347111fa71b9SJerome Forissier 347211fa71b9SJerome Forissier /* Copy most fields and adapt others */ 347311fa71b9SJerome Forissier memcpy( obuf, in, 25 ); 347411fa71b9SJerome Forissier obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; 347511fa71b9SJerome Forissier obuf[25] = 0xfe; 347611fa71b9SJerome Forissier obuf[26] = 0xff; 347711fa71b9SJerome Forissier 347811fa71b9SJerome Forissier /* Generate and write actual cookie */ 347911fa71b9SJerome Forissier p = obuf + 28; 348011fa71b9SJerome Forissier if( f_cookie_write( p_cookie, 348111fa71b9SJerome Forissier &p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) 348211fa71b9SJerome Forissier { 348311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 348411fa71b9SJerome Forissier } 348511fa71b9SJerome Forissier 348611fa71b9SJerome Forissier *olen = p - obuf; 348711fa71b9SJerome Forissier 348811fa71b9SJerome Forissier /* Go back and fill length fields */ 348911fa71b9SJerome Forissier obuf[27] = (unsigned char)( *olen - 28 ); 349011fa71b9SJerome Forissier 349111fa71b9SJerome Forissier obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); 349211fa71b9SJerome Forissier obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); 349311fa71b9SJerome Forissier obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); 349411fa71b9SJerome Forissier 349511fa71b9SJerome Forissier obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); 349611fa71b9SJerome Forissier obuf[12] = (unsigned char)( ( *olen - 13 ) ); 349711fa71b9SJerome Forissier 349811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); 349911fa71b9SJerome Forissier } 350011fa71b9SJerome Forissier 350111fa71b9SJerome Forissier /* 350211fa71b9SJerome Forissier * Handle possible client reconnect with the same UDP quadruplet 350311fa71b9SJerome Forissier * (RFC 6347 Section 4.2.8). 350411fa71b9SJerome Forissier * 350511fa71b9SJerome Forissier * Called by ssl_parse_record_header() in case we receive an epoch 0 record 350611fa71b9SJerome Forissier * that looks like a ClientHello. 350711fa71b9SJerome Forissier * 350811fa71b9SJerome Forissier * - if the input looks like a ClientHello without cookies, 350911fa71b9SJerome Forissier * send back HelloVerifyRequest, then return 0 351011fa71b9SJerome Forissier * - if the input looks like a ClientHello with a valid cookie, 351111fa71b9SJerome Forissier * reset the session of the current context, and 351211fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT 351311fa71b9SJerome Forissier * - if anything goes wrong, return a specific error code 351411fa71b9SJerome Forissier * 351511fa71b9SJerome Forissier * This function is called (through ssl_check_client_reconnect()) when an 351611fa71b9SJerome Forissier * unexpected record is found in ssl_get_next_record(), which will discard the 351711fa71b9SJerome Forissier * record if we return 0, and bubble up the return value otherwise (this 351811fa71b9SJerome Forissier * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected 351911fa71b9SJerome Forissier * errors, and is the right thing to do in both cases). 352011fa71b9SJerome Forissier */ 352111fa71b9SJerome Forissier static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) 352211fa71b9SJerome Forissier { 352311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 352411fa71b9SJerome Forissier size_t len; 352511fa71b9SJerome Forissier 352611fa71b9SJerome Forissier if( ssl->conf->f_cookie_write == NULL || 352711fa71b9SJerome Forissier ssl->conf->f_cookie_check == NULL ) 352811fa71b9SJerome Forissier { 352911fa71b9SJerome Forissier /* If we can't use cookies to verify reachability of the peer, 353011fa71b9SJerome Forissier * drop the record. */ 353111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, " 353211fa71b9SJerome Forissier "can't check reconnect validity" ) ); 353311fa71b9SJerome Forissier return( 0 ); 353411fa71b9SJerome Forissier } 353511fa71b9SJerome Forissier 353611fa71b9SJerome Forissier ret = ssl_check_dtls_clihlo_cookie( 353711fa71b9SJerome Forissier ssl->conf->f_cookie_write, 353811fa71b9SJerome Forissier ssl->conf->f_cookie_check, 353911fa71b9SJerome Forissier ssl->conf->p_cookie, 354011fa71b9SJerome Forissier ssl->cli_id, ssl->cli_id_len, 354111fa71b9SJerome Forissier ssl->in_buf, ssl->in_left, 354211fa71b9SJerome Forissier ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); 354311fa71b9SJerome Forissier 354411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); 354511fa71b9SJerome Forissier 354611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) 354711fa71b9SJerome Forissier { 354811fa71b9SJerome Forissier int send_ret; 354911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) ); 355011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", 355111fa71b9SJerome Forissier ssl->out_buf, len ); 355211fa71b9SJerome Forissier /* Don't check write errors as we can't do anything here. 355311fa71b9SJerome Forissier * If the error is permanent we'll catch it later, 355411fa71b9SJerome Forissier * if it's not, then hopefully it'll work next time. */ 355511fa71b9SJerome Forissier send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len ); 355611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret ); 355711fa71b9SJerome Forissier (void) send_ret; 355811fa71b9SJerome Forissier 355911fa71b9SJerome Forissier return( 0 ); 356011fa71b9SJerome Forissier } 356111fa71b9SJerome Forissier 356211fa71b9SJerome Forissier if( ret == 0 ) 356311fa71b9SJerome Forissier { 356411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) ); 356511fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 ) 356611fa71b9SJerome Forissier { 356711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); 356811fa71b9SJerome Forissier return( ret ); 356911fa71b9SJerome Forissier } 357011fa71b9SJerome Forissier 357111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); 357211fa71b9SJerome Forissier } 357311fa71b9SJerome Forissier 357411fa71b9SJerome Forissier return( ret ); 357511fa71b9SJerome Forissier } 357611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 357711fa71b9SJerome Forissier 357811fa71b9SJerome Forissier static int ssl_check_record_type( uint8_t record_type ) 357911fa71b9SJerome Forissier { 358011fa71b9SJerome Forissier if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE && 358111fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_ALERT && 358211fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && 358311fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 358411fa71b9SJerome Forissier { 358511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 358611fa71b9SJerome Forissier } 358711fa71b9SJerome Forissier 358811fa71b9SJerome Forissier return( 0 ); 358911fa71b9SJerome Forissier } 359011fa71b9SJerome Forissier 359111fa71b9SJerome Forissier /* 359211fa71b9SJerome Forissier * ContentType type; 359311fa71b9SJerome Forissier * ProtocolVersion version; 359411fa71b9SJerome Forissier * uint16 epoch; // DTLS only 359511fa71b9SJerome Forissier * uint48 sequence_number; // DTLS only 359611fa71b9SJerome Forissier * uint16 length; 359711fa71b9SJerome Forissier * 359811fa71b9SJerome Forissier * Return 0 if header looks sane (and, for DTLS, the record is expected) 359911fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, 360011fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. 360111fa71b9SJerome Forissier * 360211fa71b9SJerome Forissier * With DTLS, mbedtls_ssl_read_record() will: 360311fa71b9SJerome Forissier * 1. proceed with the record if this function returns 0 360411fa71b9SJerome Forissier * 2. drop only the current record if this function returns UNEXPECTED_RECORD 360511fa71b9SJerome Forissier * 3. return CLIENT_RECONNECT if this function return that value 360611fa71b9SJerome Forissier * 4. drop the whole datagram if this function returns anything else. 360711fa71b9SJerome Forissier * Point 2 is needed when the peer is resending, and we have already received 360811fa71b9SJerome Forissier * the first record from a datagram but are still waiting for the others. 360911fa71b9SJerome Forissier */ 361011fa71b9SJerome Forissier static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, 361111fa71b9SJerome Forissier unsigned char *buf, 361211fa71b9SJerome Forissier size_t len, 361311fa71b9SJerome Forissier mbedtls_record *rec ) 361411fa71b9SJerome Forissier { 361511fa71b9SJerome Forissier int major_ver, minor_ver; 361611fa71b9SJerome Forissier 361711fa71b9SJerome Forissier size_t const rec_hdr_type_offset = 0; 361811fa71b9SJerome Forissier size_t const rec_hdr_type_len = 1; 361911fa71b9SJerome Forissier 362011fa71b9SJerome Forissier size_t const rec_hdr_version_offset = rec_hdr_type_offset + 362111fa71b9SJerome Forissier rec_hdr_type_len; 362211fa71b9SJerome Forissier size_t const rec_hdr_version_len = 2; 362311fa71b9SJerome Forissier 362411fa71b9SJerome Forissier size_t const rec_hdr_ctr_len = 8; 362511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 362611fa71b9SJerome Forissier uint32_t rec_epoch; 362711fa71b9SJerome Forissier size_t const rec_hdr_ctr_offset = rec_hdr_version_offset + 362811fa71b9SJerome Forissier rec_hdr_version_len; 362911fa71b9SJerome Forissier 363011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 363111fa71b9SJerome Forissier size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + 363211fa71b9SJerome Forissier rec_hdr_ctr_len; 363311fa71b9SJerome Forissier size_t rec_hdr_cid_len = 0; 363411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 363511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 363611fa71b9SJerome Forissier 363711fa71b9SJerome Forissier size_t rec_hdr_len_offset; /* To be determined */ 363811fa71b9SJerome Forissier size_t const rec_hdr_len_len = 2; 363911fa71b9SJerome Forissier 364011fa71b9SJerome Forissier /* 364111fa71b9SJerome Forissier * Check minimum lengths for record header. 364211fa71b9SJerome Forissier */ 364311fa71b9SJerome Forissier 364411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 364511fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 364611fa71b9SJerome Forissier { 364711fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len; 364811fa71b9SJerome Forissier } 364911fa71b9SJerome Forissier else 365011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 365111fa71b9SJerome Forissier { 365211fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len; 365311fa71b9SJerome Forissier } 365411fa71b9SJerome Forissier 365511fa71b9SJerome Forissier if( len < rec_hdr_len_offset + rec_hdr_len_len ) 365611fa71b9SJerome Forissier { 365711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u", 365811fa71b9SJerome Forissier (unsigned) len, 365911fa71b9SJerome Forissier (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) ); 366011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 366111fa71b9SJerome Forissier } 366211fa71b9SJerome Forissier 366311fa71b9SJerome Forissier /* 366411fa71b9SJerome Forissier * Parse and validate record content type 366511fa71b9SJerome Forissier */ 366611fa71b9SJerome Forissier 366711fa71b9SJerome Forissier rec->type = buf[ rec_hdr_type_offset ]; 366811fa71b9SJerome Forissier 366911fa71b9SJerome Forissier /* Check record content type */ 367011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 367111fa71b9SJerome Forissier rec->cid_len = 0; 367211fa71b9SJerome Forissier 367311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 367411fa71b9SJerome Forissier ssl->conf->cid_len != 0 && 367511fa71b9SJerome Forissier rec->type == MBEDTLS_SSL_MSG_CID ) 367611fa71b9SJerome Forissier { 367711fa71b9SJerome Forissier /* Shift pointers to account for record header including CID 367811fa71b9SJerome Forissier * struct { 367911fa71b9SJerome Forissier * ContentType special_type = tls12_cid; 368011fa71b9SJerome Forissier * ProtocolVersion version; 368111fa71b9SJerome Forissier * uint16 epoch; 368211fa71b9SJerome Forissier * uint48 sequence_number; 368311fa71b9SJerome Forissier * opaque cid[cid_length]; // Additional field compared to 368411fa71b9SJerome Forissier * // default DTLS record format 368511fa71b9SJerome Forissier * uint16 length; 368611fa71b9SJerome Forissier * opaque enc_content[DTLSCiphertext.length]; 368711fa71b9SJerome Forissier * } DTLSCiphertext; 368811fa71b9SJerome Forissier */ 368911fa71b9SJerome Forissier 369011fa71b9SJerome Forissier /* So far, we only support static CID lengths 369111fa71b9SJerome Forissier * fixed in the configuration. */ 369211fa71b9SJerome Forissier rec_hdr_cid_len = ssl->conf->cid_len; 369311fa71b9SJerome Forissier rec_hdr_len_offset += rec_hdr_cid_len; 369411fa71b9SJerome Forissier 369511fa71b9SJerome Forissier if( len < rec_hdr_len_offset + rec_hdr_len_len ) 369611fa71b9SJerome Forissier { 369711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u", 369811fa71b9SJerome Forissier (unsigned) len, 369911fa71b9SJerome Forissier (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) ); 370011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 370111fa71b9SJerome Forissier } 370211fa71b9SJerome Forissier 370311fa71b9SJerome Forissier /* configured CID len is guaranteed at most 255, see 370411fa71b9SJerome Forissier * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */ 370511fa71b9SJerome Forissier rec->cid_len = (uint8_t) rec_hdr_cid_len; 370611fa71b9SJerome Forissier memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len ); 370711fa71b9SJerome Forissier } 370811fa71b9SJerome Forissier else 370911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 371011fa71b9SJerome Forissier { 371111fa71b9SJerome Forissier if( ssl_check_record_type( rec->type ) ) 371211fa71b9SJerome Forissier { 371311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u", 371411fa71b9SJerome Forissier (unsigned) rec->type ) ); 371511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 371611fa71b9SJerome Forissier } 371711fa71b9SJerome Forissier } 371811fa71b9SJerome Forissier 371911fa71b9SJerome Forissier /* 372011fa71b9SJerome Forissier * Parse and validate record version 372111fa71b9SJerome Forissier */ 372211fa71b9SJerome Forissier 372311fa71b9SJerome Forissier rec->ver[0] = buf[ rec_hdr_version_offset + 0 ]; 372411fa71b9SJerome Forissier rec->ver[1] = buf[ rec_hdr_version_offset + 1 ]; 372511fa71b9SJerome Forissier mbedtls_ssl_read_version( &major_ver, &minor_ver, 372611fa71b9SJerome Forissier ssl->conf->transport, 372711fa71b9SJerome Forissier &rec->ver[0] ); 372811fa71b9SJerome Forissier 372911fa71b9SJerome Forissier if( major_ver != ssl->major_ver ) 373011fa71b9SJerome Forissier { 373111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); 373211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 373311fa71b9SJerome Forissier } 373411fa71b9SJerome Forissier 373511fa71b9SJerome Forissier if( minor_ver > ssl->conf->max_minor_ver ) 373611fa71b9SJerome Forissier { 373711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); 373811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 373911fa71b9SJerome Forissier } 374011fa71b9SJerome Forissier 374111fa71b9SJerome Forissier /* 374211fa71b9SJerome Forissier * Parse/Copy record sequence number. 374311fa71b9SJerome Forissier */ 374411fa71b9SJerome Forissier 374511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 374611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 374711fa71b9SJerome Forissier { 374811fa71b9SJerome Forissier /* Copy explicit record sequence number from input buffer. */ 374911fa71b9SJerome Forissier memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset, 375011fa71b9SJerome Forissier rec_hdr_ctr_len ); 375111fa71b9SJerome Forissier } 375211fa71b9SJerome Forissier else 375311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 375411fa71b9SJerome Forissier { 375511fa71b9SJerome Forissier /* Copy implicit record sequence number from SSL context structure. */ 375611fa71b9SJerome Forissier memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len ); 375711fa71b9SJerome Forissier } 375811fa71b9SJerome Forissier 375911fa71b9SJerome Forissier /* 376011fa71b9SJerome Forissier * Parse record length. 376111fa71b9SJerome Forissier */ 376211fa71b9SJerome Forissier 376311fa71b9SJerome Forissier rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len; 376411fa71b9SJerome Forissier rec->data_len = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) | 376511fa71b9SJerome Forissier ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 ); 376611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset ); 376711fa71b9SJerome Forissier 3768*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %u, " 3769*7901324dSJerome Forissier "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET, 377011fa71b9SJerome Forissier rec->type, 377111fa71b9SJerome Forissier major_ver, minor_ver, rec->data_len ) ); 377211fa71b9SJerome Forissier 377311fa71b9SJerome Forissier rec->buf = buf; 377411fa71b9SJerome Forissier rec->buf_len = rec->data_offset + rec->data_len; 377511fa71b9SJerome Forissier 377611fa71b9SJerome Forissier if( rec->data_len == 0 ) 377711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 377811fa71b9SJerome Forissier 377911fa71b9SJerome Forissier /* 378011fa71b9SJerome Forissier * DTLS-related tests. 378111fa71b9SJerome Forissier * Check epoch before checking length constraint because 378211fa71b9SJerome Forissier * the latter varies with the epoch. E.g., if a ChangeCipherSpec 378311fa71b9SJerome Forissier * message gets duplicated before the corresponding Finished message, 378411fa71b9SJerome Forissier * the second ChangeCipherSpec should be discarded because it belongs 378511fa71b9SJerome Forissier * to an old epoch, but not because its length is shorter than 378611fa71b9SJerome Forissier * the minimum record length for packets using the new record transform. 378711fa71b9SJerome Forissier * Note that these two kinds of failures are handled differently, 378811fa71b9SJerome Forissier * as an unexpected record is silently skipped but an invalid 378911fa71b9SJerome Forissier * record leads to the entire datagram being dropped. 379011fa71b9SJerome Forissier */ 379111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 379211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 379311fa71b9SJerome Forissier { 379411fa71b9SJerome Forissier rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1]; 379511fa71b9SJerome Forissier 379611fa71b9SJerome Forissier /* Check that the datagram is large enough to contain a record 379711fa71b9SJerome Forissier * of the advertised length. */ 379811fa71b9SJerome Forissier if( len < rec->data_offset + rec->data_len ) 379911fa71b9SJerome Forissier { 380011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.", 380111fa71b9SJerome Forissier (unsigned) len, 380211fa71b9SJerome Forissier (unsigned)( rec->data_offset + rec->data_len ) ) ); 380311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 380411fa71b9SJerome Forissier } 380511fa71b9SJerome Forissier 380611fa71b9SJerome Forissier /* Records from other, non-matching epochs are silently discarded. 380711fa71b9SJerome Forissier * (The case of same-port Client reconnects must be considered in 380811fa71b9SJerome Forissier * the caller). */ 380911fa71b9SJerome Forissier if( rec_epoch != ssl->in_epoch ) 381011fa71b9SJerome Forissier { 381111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " 3812*7901324dSJerome Forissier "expected %u, received %lu", 3813*7901324dSJerome Forissier ssl->in_epoch, (unsigned long) rec_epoch ) ); 381411fa71b9SJerome Forissier 381511fa71b9SJerome Forissier /* Records from the next epoch are considered for buffering 381611fa71b9SJerome Forissier * (concretely: early Finished messages). */ 381711fa71b9SJerome Forissier if( rec_epoch == (unsigned) ssl->in_epoch + 1 ) 381811fa71b9SJerome Forissier { 381911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) ); 382011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 382111fa71b9SJerome Forissier } 382211fa71b9SJerome Forissier 382311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 382411fa71b9SJerome Forissier } 382511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 382611fa71b9SJerome Forissier /* For records from the correct epoch, check whether their 382711fa71b9SJerome Forissier * sequence number has been seen before. */ 382811fa71b9SJerome Forissier else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl, 382911fa71b9SJerome Forissier &rec->ctr[0] ) != 0 ) 383011fa71b9SJerome Forissier { 383111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); 383211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 383311fa71b9SJerome Forissier } 383411fa71b9SJerome Forissier #endif 383511fa71b9SJerome Forissier } 383611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 383711fa71b9SJerome Forissier 383811fa71b9SJerome Forissier return( 0 ); 383911fa71b9SJerome Forissier } 384011fa71b9SJerome Forissier 384111fa71b9SJerome Forissier 384211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 384311fa71b9SJerome Forissier static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl ) 384411fa71b9SJerome Forissier { 384511fa71b9SJerome Forissier unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; 384611fa71b9SJerome Forissier 384711fa71b9SJerome Forissier /* 384811fa71b9SJerome Forissier * Check for an epoch 0 ClientHello. We can't use in_msg here to 384911fa71b9SJerome Forissier * access the first byte of record content (handshake type), as we 385011fa71b9SJerome Forissier * have an active transform (possibly iv_len != 0), so use the 385111fa71b9SJerome Forissier * fact that the record header len is 13 instead. 385211fa71b9SJerome Forissier */ 385311fa71b9SJerome Forissier if( rec_epoch == 0 && 385411fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 385511fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && 385611fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 385711fa71b9SJerome Forissier ssl->in_left > 13 && 385811fa71b9SJerome Forissier ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) 385911fa71b9SJerome Forissier { 386011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " 386111fa71b9SJerome Forissier "from the same port" ) ); 386211fa71b9SJerome Forissier return( ssl_handle_possible_reconnect( ssl ) ); 386311fa71b9SJerome Forissier } 386411fa71b9SJerome Forissier 386511fa71b9SJerome Forissier return( 0 ); 386611fa71b9SJerome Forissier } 386711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ 386811fa71b9SJerome Forissier 386911fa71b9SJerome Forissier /* 387011fa71b9SJerome Forissier * If applicable, decrypt record content 387111fa71b9SJerome Forissier */ 387211fa71b9SJerome Forissier static int ssl_prepare_record_content( mbedtls_ssl_context *ssl, 387311fa71b9SJerome Forissier mbedtls_record *rec ) 387411fa71b9SJerome Forissier { 387511fa71b9SJerome Forissier int ret, done = 0; 387611fa71b9SJerome Forissier 387711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", 387811fa71b9SJerome Forissier rec->buf, rec->buf_len ); 387911fa71b9SJerome Forissier 388011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 388111fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_read != NULL ) 388211fa71b9SJerome Forissier { 388311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); 388411fa71b9SJerome Forissier 388511fa71b9SJerome Forissier ret = mbedtls_ssl_hw_record_read( ssl ); 388611fa71b9SJerome Forissier if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) 388711fa71b9SJerome Forissier { 388811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); 388911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 389011fa71b9SJerome Forissier } 389111fa71b9SJerome Forissier 389211fa71b9SJerome Forissier if( ret == 0 ) 389311fa71b9SJerome Forissier done = 1; 389411fa71b9SJerome Forissier } 389511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ 389611fa71b9SJerome Forissier if( !done && ssl->transform_in != NULL ) 389711fa71b9SJerome Forissier { 389811fa71b9SJerome Forissier unsigned char const old_msg_type = rec->type; 389911fa71b9SJerome Forissier 390011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, 390111fa71b9SJerome Forissier rec ) ) != 0 ) 390211fa71b9SJerome Forissier { 390311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); 390411fa71b9SJerome Forissier 390511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 390611fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && 390711fa71b9SJerome Forissier ssl->conf->ignore_unexpected_cid 390811fa71b9SJerome Forissier == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) 390911fa71b9SJerome Forissier { 391011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) ); 391111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 391211fa71b9SJerome Forissier } 391311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 391411fa71b9SJerome Forissier 391511fa71b9SJerome Forissier return( ret ); 391611fa71b9SJerome Forissier } 391711fa71b9SJerome Forissier 391811fa71b9SJerome Forissier if( old_msg_type != rec->type ) 391911fa71b9SJerome Forissier { 392011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d", 392111fa71b9SJerome Forissier old_msg_type, rec->type ) ); 392211fa71b9SJerome Forissier } 392311fa71b9SJerome Forissier 392411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", 392511fa71b9SJerome Forissier rec->buf + rec->data_offset, rec->data_len ); 392611fa71b9SJerome Forissier 392711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 392811fa71b9SJerome Forissier /* We have already checked the record content type 392911fa71b9SJerome Forissier * in ssl_parse_record_header(), failing or silently 393011fa71b9SJerome Forissier * dropping the record in the case of an unknown type. 393111fa71b9SJerome Forissier * 393211fa71b9SJerome Forissier * Since with the use of CIDs, the record content type 393311fa71b9SJerome Forissier * might change during decryption, re-check the record 393411fa71b9SJerome Forissier * content type, but treat a failure as fatal this time. */ 393511fa71b9SJerome Forissier if( ssl_check_record_type( rec->type ) ) 393611fa71b9SJerome Forissier { 393711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); 393811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 393911fa71b9SJerome Forissier } 394011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 394111fa71b9SJerome Forissier 394211fa71b9SJerome Forissier if( rec->data_len == 0 ) 394311fa71b9SJerome Forissier { 394411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2) 394511fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 394611fa71b9SJerome Forissier && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 394711fa71b9SJerome Forissier { 394811fa71b9SJerome Forissier /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ 394911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); 395011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 395111fa71b9SJerome Forissier } 395211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ 395311fa71b9SJerome Forissier 395411fa71b9SJerome Forissier ssl->nb_zero++; 395511fa71b9SJerome Forissier 395611fa71b9SJerome Forissier /* 395711fa71b9SJerome Forissier * Three or more empty messages may be a DoS attack 395811fa71b9SJerome Forissier * (excessive CPU consumption). 395911fa71b9SJerome Forissier */ 396011fa71b9SJerome Forissier if( ssl->nb_zero > 3 ) 396111fa71b9SJerome Forissier { 396211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " 396311fa71b9SJerome Forissier "messages, possible DoS attack" ) ); 396411fa71b9SJerome Forissier /* Treat the records as if they were not properly authenticated, 396511fa71b9SJerome Forissier * thereby failing the connection if we see more than allowed 396611fa71b9SJerome Forissier * by the configured bad MAC threshold. */ 396711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 396811fa71b9SJerome Forissier } 396911fa71b9SJerome Forissier } 397011fa71b9SJerome Forissier else 397111fa71b9SJerome Forissier ssl->nb_zero = 0; 397211fa71b9SJerome Forissier 397311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 397411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 397511fa71b9SJerome Forissier { 397611fa71b9SJerome Forissier ; /* in_ctr read from peer, not maintained internally */ 397711fa71b9SJerome Forissier } 397811fa71b9SJerome Forissier else 397911fa71b9SJerome Forissier #endif 398011fa71b9SJerome Forissier { 398111fa71b9SJerome Forissier unsigned i; 398211fa71b9SJerome Forissier for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- ) 398311fa71b9SJerome Forissier if( ++ssl->in_ctr[i - 1] != 0 ) 398411fa71b9SJerome Forissier break; 398511fa71b9SJerome Forissier 398611fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */ 398711fa71b9SJerome Forissier if( i == mbedtls_ssl_ep_len( ssl ) ) 398811fa71b9SJerome Forissier { 398911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); 399011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 399111fa71b9SJerome Forissier } 399211fa71b9SJerome Forissier } 399311fa71b9SJerome Forissier 399411fa71b9SJerome Forissier } 399511fa71b9SJerome Forissier 399611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 399711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 399811fa71b9SJerome Forissier { 399911fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_update( ssl ); 400011fa71b9SJerome Forissier } 400111fa71b9SJerome Forissier #endif 400211fa71b9SJerome Forissier 400311fa71b9SJerome Forissier /* Check actual (decrypted) record content length against 400411fa71b9SJerome Forissier * configured maximum. */ 400511fa71b9SJerome Forissier if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) 400611fa71b9SJerome Forissier { 400711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); 400811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 400911fa71b9SJerome Forissier } 401011fa71b9SJerome Forissier 401111fa71b9SJerome Forissier return( 0 ); 401211fa71b9SJerome Forissier } 401311fa71b9SJerome Forissier 401411fa71b9SJerome Forissier /* 401511fa71b9SJerome Forissier * Read a record. 401611fa71b9SJerome Forissier * 401711fa71b9SJerome Forissier * Silently ignore non-fatal alert (and for DTLS, invalid records as well, 401811fa71b9SJerome Forissier * RFC 6347 4.1.2.7) and continue reading until a valid record is found. 401911fa71b9SJerome Forissier * 402011fa71b9SJerome Forissier */ 402111fa71b9SJerome Forissier 402211fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */ 402311fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl ); 402411fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl ); 402511fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ); 402611fa71b9SJerome Forissier 402711fa71b9SJerome Forissier int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl, 402811fa71b9SJerome Forissier unsigned update_hs_digest ) 402911fa71b9SJerome Forissier { 403011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 403111fa71b9SJerome Forissier 403211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); 403311fa71b9SJerome Forissier 403411fa71b9SJerome Forissier if( ssl->keep_current_message == 0 ) 403511fa71b9SJerome Forissier { 403611fa71b9SJerome Forissier do { 403711fa71b9SJerome Forissier 403811fa71b9SJerome Forissier ret = ssl_consume_current_message( ssl ); 403911fa71b9SJerome Forissier if( ret != 0 ) 404011fa71b9SJerome Forissier return( ret ); 404111fa71b9SJerome Forissier 404211fa71b9SJerome Forissier if( ssl_record_is_in_progress( ssl ) == 0 ) 404311fa71b9SJerome Forissier { 404411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 404511fa71b9SJerome Forissier int have_buffered = 0; 404611fa71b9SJerome Forissier 404711fa71b9SJerome Forissier /* We only check for buffered messages if the 404811fa71b9SJerome Forissier * current datagram is fully consumed. */ 404911fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 405011fa71b9SJerome Forissier ssl_next_record_is_in_datagram( ssl ) == 0 ) 405111fa71b9SJerome Forissier { 405211fa71b9SJerome Forissier if( ssl_load_buffered_message( ssl ) == 0 ) 405311fa71b9SJerome Forissier have_buffered = 1; 405411fa71b9SJerome Forissier } 405511fa71b9SJerome Forissier 405611fa71b9SJerome Forissier if( have_buffered == 0 ) 405711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 405811fa71b9SJerome Forissier { 405911fa71b9SJerome Forissier ret = ssl_get_next_record( ssl ); 406011fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ) 406111fa71b9SJerome Forissier continue; 406211fa71b9SJerome Forissier 406311fa71b9SJerome Forissier if( ret != 0 ) 406411fa71b9SJerome Forissier { 406511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret ); 406611fa71b9SJerome Forissier return( ret ); 406711fa71b9SJerome Forissier } 406811fa71b9SJerome Forissier } 406911fa71b9SJerome Forissier } 407011fa71b9SJerome Forissier 407111fa71b9SJerome Forissier ret = mbedtls_ssl_handle_message_type( ssl ); 407211fa71b9SJerome Forissier 407311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 407411fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 407511fa71b9SJerome Forissier { 407611fa71b9SJerome Forissier /* Buffer future message */ 407711fa71b9SJerome Forissier ret = ssl_buffer_message( ssl ); 407811fa71b9SJerome Forissier if( ret != 0 ) 407911fa71b9SJerome Forissier return( ret ); 408011fa71b9SJerome Forissier 408111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; 408211fa71b9SJerome Forissier } 408311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 408411fa71b9SJerome Forissier 408511fa71b9SJerome Forissier } while( MBEDTLS_ERR_SSL_NON_FATAL == ret || 408611fa71b9SJerome Forissier MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret ); 408711fa71b9SJerome Forissier 408811fa71b9SJerome Forissier if( 0 != ret ) 408911fa71b9SJerome Forissier { 409011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); 409111fa71b9SJerome Forissier return( ret ); 409211fa71b9SJerome Forissier } 409311fa71b9SJerome Forissier 409411fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && 409511fa71b9SJerome Forissier update_hs_digest == 1 ) 409611fa71b9SJerome Forissier { 409711fa71b9SJerome Forissier mbedtls_ssl_update_handshake_status( ssl ); 409811fa71b9SJerome Forissier } 409911fa71b9SJerome Forissier } 410011fa71b9SJerome Forissier else 410111fa71b9SJerome Forissier { 410211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) ); 410311fa71b9SJerome Forissier ssl->keep_current_message = 0; 410411fa71b9SJerome Forissier } 410511fa71b9SJerome Forissier 410611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); 410711fa71b9SJerome Forissier 410811fa71b9SJerome Forissier return( 0 ); 410911fa71b9SJerome Forissier } 411011fa71b9SJerome Forissier 411111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 411211fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl ) 411311fa71b9SJerome Forissier { 411411fa71b9SJerome Forissier if( ssl->in_left > ssl->next_record_offset ) 411511fa71b9SJerome Forissier return( 1 ); 411611fa71b9SJerome Forissier 411711fa71b9SJerome Forissier return( 0 ); 411811fa71b9SJerome Forissier } 411911fa71b9SJerome Forissier 412011fa71b9SJerome Forissier static int ssl_load_buffered_message( mbedtls_ssl_context *ssl ) 412111fa71b9SJerome Forissier { 412211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 412311fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * hs_buf; 412411fa71b9SJerome Forissier int ret = 0; 412511fa71b9SJerome Forissier 412611fa71b9SJerome Forissier if( hs == NULL ) 412711fa71b9SJerome Forissier return( -1 ); 412811fa71b9SJerome Forissier 412911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) ); 413011fa71b9SJerome Forissier 413111fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC || 413211fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) 413311fa71b9SJerome Forissier { 413411fa71b9SJerome Forissier /* Check if we have seen a ChangeCipherSpec before. 413511fa71b9SJerome Forissier * If yes, synthesize a CCS record. */ 413611fa71b9SJerome Forissier if( !hs->buffering.seen_ccs ) 413711fa71b9SJerome Forissier { 413811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) ); 413911fa71b9SJerome Forissier ret = -1; 414011fa71b9SJerome Forissier goto exit; 414111fa71b9SJerome Forissier } 414211fa71b9SJerome Forissier 414311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) ); 414411fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 414511fa71b9SJerome Forissier ssl->in_msglen = 1; 414611fa71b9SJerome Forissier ssl->in_msg[0] = 1; 414711fa71b9SJerome Forissier 414811fa71b9SJerome Forissier /* As long as they are equal, the exact value doesn't matter. */ 414911fa71b9SJerome Forissier ssl->in_left = 0; 415011fa71b9SJerome Forissier ssl->next_record_offset = 0; 415111fa71b9SJerome Forissier 415211fa71b9SJerome Forissier hs->buffering.seen_ccs = 0; 415311fa71b9SJerome Forissier goto exit; 415411fa71b9SJerome Forissier } 415511fa71b9SJerome Forissier 415611fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C) 415711fa71b9SJerome Forissier /* Debug only */ 415811fa71b9SJerome Forissier { 415911fa71b9SJerome Forissier unsigned offset; 416011fa71b9SJerome Forissier for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) 416111fa71b9SJerome Forissier { 416211fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[offset]; 416311fa71b9SJerome Forissier if( hs_buf->is_valid == 1 ) 416411fa71b9SJerome Forissier { 416511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.", 416611fa71b9SJerome Forissier hs->in_msg_seq + offset, 416711fa71b9SJerome Forissier hs_buf->is_complete ? "fully" : "partially" ) ); 416811fa71b9SJerome Forissier } 416911fa71b9SJerome Forissier } 417011fa71b9SJerome Forissier } 417111fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */ 417211fa71b9SJerome Forissier 417311fa71b9SJerome Forissier /* Check if we have buffered and/or fully reassembled the 417411fa71b9SJerome Forissier * next handshake message. */ 417511fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[0]; 417611fa71b9SJerome Forissier if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) ) 417711fa71b9SJerome Forissier { 417811fa71b9SJerome Forissier /* Synthesize a record containing the buffered HS message. */ 417911fa71b9SJerome Forissier size_t msg_len = ( hs_buf->data[1] << 16 ) | 418011fa71b9SJerome Forissier ( hs_buf->data[2] << 8 ) | 418111fa71b9SJerome Forissier hs_buf->data[3]; 418211fa71b9SJerome Forissier 418311fa71b9SJerome Forissier /* Double-check that we haven't accidentally buffered 418411fa71b9SJerome Forissier * a message that doesn't fit into the input buffer. */ 418511fa71b9SJerome Forissier if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) 418611fa71b9SJerome Forissier { 418711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 418811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 418911fa71b9SJerome Forissier } 419011fa71b9SJerome Forissier 419111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) ); 419211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)", 419311fa71b9SJerome Forissier hs_buf->data, msg_len + 12 ); 419411fa71b9SJerome Forissier 419511fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 419611fa71b9SJerome Forissier ssl->in_hslen = msg_len + 12; 419711fa71b9SJerome Forissier ssl->in_msglen = msg_len + 12; 419811fa71b9SJerome Forissier memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen ); 419911fa71b9SJerome Forissier 420011fa71b9SJerome Forissier ret = 0; 420111fa71b9SJerome Forissier goto exit; 420211fa71b9SJerome Forissier } 420311fa71b9SJerome Forissier else 420411fa71b9SJerome Forissier { 420511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered", 420611fa71b9SJerome Forissier hs->in_msg_seq ) ); 420711fa71b9SJerome Forissier } 420811fa71b9SJerome Forissier 420911fa71b9SJerome Forissier ret = -1; 421011fa71b9SJerome Forissier 421111fa71b9SJerome Forissier exit: 421211fa71b9SJerome Forissier 421311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) ); 421411fa71b9SJerome Forissier return( ret ); 421511fa71b9SJerome Forissier } 421611fa71b9SJerome Forissier 421711fa71b9SJerome Forissier static int ssl_buffer_make_space( mbedtls_ssl_context *ssl, 421811fa71b9SJerome Forissier size_t desired ) 421911fa71b9SJerome Forissier { 422011fa71b9SJerome Forissier int offset; 422111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 422211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available", 422311fa71b9SJerome Forissier (unsigned) desired ) ); 422411fa71b9SJerome Forissier 422511fa71b9SJerome Forissier /* Get rid of future records epoch first, if such exist. */ 422611fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 422711fa71b9SJerome Forissier 422811fa71b9SJerome Forissier /* Check if we have enough space available now. */ 422911fa71b9SJerome Forissier if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 423011fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 423111fa71b9SJerome Forissier { 423211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) ); 423311fa71b9SJerome Forissier return( 0 ); 423411fa71b9SJerome Forissier } 423511fa71b9SJerome Forissier 423611fa71b9SJerome Forissier /* We don't have enough space to buffer the next expected handshake 423711fa71b9SJerome Forissier * message. Remove buffers used for future messages to gain space, 423811fa71b9SJerome Forissier * starting with the most distant one. */ 423911fa71b9SJerome Forissier for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; 424011fa71b9SJerome Forissier offset >= 0; offset-- ) 424111fa71b9SJerome Forissier { 424211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message", 424311fa71b9SJerome Forissier offset ) ); 424411fa71b9SJerome Forissier 424511fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, (uint8_t) offset ); 424611fa71b9SJerome Forissier 424711fa71b9SJerome Forissier /* Check if we have enough space available now. */ 424811fa71b9SJerome Forissier if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 424911fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 425011fa71b9SJerome Forissier { 425111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) ); 425211fa71b9SJerome Forissier return( 0 ); 425311fa71b9SJerome Forissier } 425411fa71b9SJerome Forissier } 425511fa71b9SJerome Forissier 425611fa71b9SJerome Forissier return( -1 ); 425711fa71b9SJerome Forissier } 425811fa71b9SJerome Forissier 425911fa71b9SJerome Forissier static int ssl_buffer_message( mbedtls_ssl_context *ssl ) 426011fa71b9SJerome Forissier { 426111fa71b9SJerome Forissier int ret = 0; 426211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 426311fa71b9SJerome Forissier 426411fa71b9SJerome Forissier if( hs == NULL ) 426511fa71b9SJerome Forissier return( 0 ); 426611fa71b9SJerome Forissier 426711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) ); 426811fa71b9SJerome Forissier 426911fa71b9SJerome Forissier switch( ssl->in_msgtype ) 427011fa71b9SJerome Forissier { 427111fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC: 427211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) ); 427311fa71b9SJerome Forissier 427411fa71b9SJerome Forissier hs->buffering.seen_ccs = 1; 427511fa71b9SJerome Forissier break; 427611fa71b9SJerome Forissier 427711fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_HANDSHAKE: 427811fa71b9SJerome Forissier { 427911fa71b9SJerome Forissier unsigned recv_msg_seq_offset; 428011fa71b9SJerome Forissier unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; 428111fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf; 428211fa71b9SJerome Forissier size_t msg_len = ssl->in_hslen - 12; 428311fa71b9SJerome Forissier 428411fa71b9SJerome Forissier /* We should never receive an old handshake 428511fa71b9SJerome Forissier * message - double-check nonetheless. */ 428611fa71b9SJerome Forissier if( recv_msg_seq < ssl->handshake->in_msg_seq ) 428711fa71b9SJerome Forissier { 428811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 428911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 429011fa71b9SJerome Forissier } 429111fa71b9SJerome Forissier 429211fa71b9SJerome Forissier recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq; 429311fa71b9SJerome Forissier if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS ) 429411fa71b9SJerome Forissier { 429511fa71b9SJerome Forissier /* Silently ignore -- message too far in the future */ 429611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, 429711fa71b9SJerome Forissier ( "Ignore future HS message with sequence number %u, " 429811fa71b9SJerome Forissier "buffering window %u - %u", 429911fa71b9SJerome Forissier recv_msg_seq, ssl->handshake->in_msg_seq, 430011fa71b9SJerome Forissier ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) ); 430111fa71b9SJerome Forissier 430211fa71b9SJerome Forissier goto exit; 430311fa71b9SJerome Forissier } 430411fa71b9SJerome Forissier 430511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ", 430611fa71b9SJerome Forissier recv_msg_seq, recv_msg_seq_offset ) ); 430711fa71b9SJerome Forissier 430811fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ]; 430911fa71b9SJerome Forissier 431011fa71b9SJerome Forissier /* Check if the buffering for this seq nr has already commenced. */ 431111fa71b9SJerome Forissier if( !hs_buf->is_valid ) 431211fa71b9SJerome Forissier { 431311fa71b9SJerome Forissier size_t reassembly_buf_sz; 431411fa71b9SJerome Forissier 431511fa71b9SJerome Forissier hs_buf->is_fragmented = 431611fa71b9SJerome Forissier ( ssl_hs_is_proper_fragment( ssl ) == 1 ); 431711fa71b9SJerome Forissier 431811fa71b9SJerome Forissier /* We copy the message back into the input buffer 431911fa71b9SJerome Forissier * after reassembly, so check that it's not too large. 432011fa71b9SJerome Forissier * This is an implementation-specific limitation 432111fa71b9SJerome Forissier * and not one from the standard, hence it is not 432211fa71b9SJerome Forissier * checked in ssl_check_hs_header(). */ 432311fa71b9SJerome Forissier if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN ) 432411fa71b9SJerome Forissier { 432511fa71b9SJerome Forissier /* Ignore message */ 432611fa71b9SJerome Forissier goto exit; 432711fa71b9SJerome Forissier } 432811fa71b9SJerome Forissier 432911fa71b9SJerome Forissier /* Check if we have enough space to buffer the message. */ 433011fa71b9SJerome Forissier if( hs->buffering.total_bytes_buffered > 433111fa71b9SJerome Forissier MBEDTLS_SSL_DTLS_MAX_BUFFERING ) 433211fa71b9SJerome Forissier { 433311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 433411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 433511fa71b9SJerome Forissier } 433611fa71b9SJerome Forissier 433711fa71b9SJerome Forissier reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len, 433811fa71b9SJerome Forissier hs_buf->is_fragmented ); 433911fa71b9SJerome Forissier 434011fa71b9SJerome Forissier if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 434111fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 434211fa71b9SJerome Forissier { 434311fa71b9SJerome Forissier if( recv_msg_seq_offset > 0 ) 434411fa71b9SJerome Forissier { 434511fa71b9SJerome Forissier /* If we can't buffer a future message because 434611fa71b9SJerome Forissier * of space limitations -- ignore. */ 4347*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET 4348*7901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 4349*7901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 4350*7901324dSJerome Forissier " bytes buffered) -- ignore\n", 4351*7901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 4352*7901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 435311fa71b9SJerome Forissier goto exit; 435411fa71b9SJerome Forissier } 435511fa71b9SJerome Forissier else 435611fa71b9SJerome Forissier { 4357*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET 4358*7901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 4359*7901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 4360*7901324dSJerome Forissier " bytes buffered) -- attempt to make space by freeing buffered future messages\n", 4361*7901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 4362*7901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 436311fa71b9SJerome Forissier } 436411fa71b9SJerome Forissier 436511fa71b9SJerome Forissier if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 ) 436611fa71b9SJerome Forissier { 4367*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET 4368*7901324dSJerome Forissier " (%" MBEDTLS_PRINTF_SIZET " with bitmap) would exceed" 4369*7901324dSJerome Forissier " the compile-time limit %" MBEDTLS_PRINTF_SIZET 4370*7901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 4371*7901324dSJerome Forissier " bytes buffered) -- fail\n", 4372*7901324dSJerome Forissier msg_len, 4373*7901324dSJerome Forissier reassembly_buf_sz, 4374*7901324dSJerome Forissier (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 4375*7901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 437611fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 437711fa71b9SJerome Forissier goto exit; 437811fa71b9SJerome Forissier } 437911fa71b9SJerome Forissier } 438011fa71b9SJerome Forissier 4381*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET, 438211fa71b9SJerome Forissier msg_len ) ); 438311fa71b9SJerome Forissier 438411fa71b9SJerome Forissier hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz ); 438511fa71b9SJerome Forissier if( hs_buf->data == NULL ) 438611fa71b9SJerome Forissier { 438711fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 438811fa71b9SJerome Forissier goto exit; 438911fa71b9SJerome Forissier } 439011fa71b9SJerome Forissier hs_buf->data_len = reassembly_buf_sz; 439111fa71b9SJerome Forissier 439211fa71b9SJerome Forissier /* Prepare final header: copy msg_type, length and message_seq, 439311fa71b9SJerome Forissier * then add standardised fragment_offset and fragment_length */ 439411fa71b9SJerome Forissier memcpy( hs_buf->data, ssl->in_msg, 6 ); 439511fa71b9SJerome Forissier memset( hs_buf->data + 6, 0, 3 ); 439611fa71b9SJerome Forissier memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ); 439711fa71b9SJerome Forissier 439811fa71b9SJerome Forissier hs_buf->is_valid = 1; 439911fa71b9SJerome Forissier 440011fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += reassembly_buf_sz; 440111fa71b9SJerome Forissier } 440211fa71b9SJerome Forissier else 440311fa71b9SJerome Forissier { 440411fa71b9SJerome Forissier /* Make sure msg_type and length are consistent */ 440511fa71b9SJerome Forissier if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 ) 440611fa71b9SJerome Forissier { 440711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) ); 440811fa71b9SJerome Forissier /* Ignore */ 440911fa71b9SJerome Forissier goto exit; 441011fa71b9SJerome Forissier } 441111fa71b9SJerome Forissier } 441211fa71b9SJerome Forissier 441311fa71b9SJerome Forissier if( !hs_buf->is_complete ) 441411fa71b9SJerome Forissier { 441511fa71b9SJerome Forissier size_t frag_len, frag_off; 441611fa71b9SJerome Forissier unsigned char * const msg = hs_buf->data + 12; 441711fa71b9SJerome Forissier 441811fa71b9SJerome Forissier /* 441911fa71b9SJerome Forissier * Check and copy current fragment 442011fa71b9SJerome Forissier */ 442111fa71b9SJerome Forissier 442211fa71b9SJerome Forissier /* Validation of header fields already done in 442311fa71b9SJerome Forissier * mbedtls_ssl_prepare_handshake_record(). */ 442411fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off( ssl ); 442511fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len( ssl ); 442611fa71b9SJerome Forissier 4427*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %" MBEDTLS_PRINTF_SIZET 4428*7901324dSJerome Forissier ", length = %" MBEDTLS_PRINTF_SIZET, 442911fa71b9SJerome Forissier frag_off, frag_len ) ); 443011fa71b9SJerome Forissier memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); 443111fa71b9SJerome Forissier 443211fa71b9SJerome Forissier if( hs_buf->is_fragmented ) 443311fa71b9SJerome Forissier { 443411fa71b9SJerome Forissier unsigned char * const bitmask = msg + msg_len; 443511fa71b9SJerome Forissier ssl_bitmask_set( bitmask, frag_off, frag_len ); 443611fa71b9SJerome Forissier hs_buf->is_complete = ( ssl_bitmask_check( bitmask, 443711fa71b9SJerome Forissier msg_len ) == 0 ); 443811fa71b9SJerome Forissier } 443911fa71b9SJerome Forissier else 444011fa71b9SJerome Forissier { 444111fa71b9SJerome Forissier hs_buf->is_complete = 1; 444211fa71b9SJerome Forissier } 444311fa71b9SJerome Forissier 444411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete", 444511fa71b9SJerome Forissier hs_buf->is_complete ? "" : "not yet " ) ); 444611fa71b9SJerome Forissier } 444711fa71b9SJerome Forissier 444811fa71b9SJerome Forissier break; 444911fa71b9SJerome Forissier } 445011fa71b9SJerome Forissier 445111fa71b9SJerome Forissier default: 445211fa71b9SJerome Forissier /* We don't buffer other types of messages. */ 445311fa71b9SJerome Forissier break; 445411fa71b9SJerome Forissier } 445511fa71b9SJerome Forissier 445611fa71b9SJerome Forissier exit: 445711fa71b9SJerome Forissier 445811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) ); 445911fa71b9SJerome Forissier return( ret ); 446011fa71b9SJerome Forissier } 446111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 446211fa71b9SJerome Forissier 446311fa71b9SJerome Forissier static int ssl_consume_current_message( mbedtls_ssl_context *ssl ) 446411fa71b9SJerome Forissier { 446511fa71b9SJerome Forissier /* 446611fa71b9SJerome Forissier * Consume last content-layer message and potentially 446711fa71b9SJerome Forissier * update in_msglen which keeps track of the contents' 446811fa71b9SJerome Forissier * consumption state. 446911fa71b9SJerome Forissier * 447011fa71b9SJerome Forissier * (1) Handshake messages: 447111fa71b9SJerome Forissier * Remove last handshake message, move content 447211fa71b9SJerome Forissier * and adapt in_msglen. 447311fa71b9SJerome Forissier * 447411fa71b9SJerome Forissier * (2) Alert messages: 447511fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 447611fa71b9SJerome Forissier * 447711fa71b9SJerome Forissier * (3) Change cipher spec: 447811fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0. 447911fa71b9SJerome Forissier * 448011fa71b9SJerome Forissier * (4) Application data: 448111fa71b9SJerome Forissier * Don't do anything - the record layer provides 448211fa71b9SJerome Forissier * the application data as a stream transport 448311fa71b9SJerome Forissier * and consumes through mbedtls_ssl_read only. 448411fa71b9SJerome Forissier * 448511fa71b9SJerome Forissier */ 448611fa71b9SJerome Forissier 448711fa71b9SJerome Forissier /* Case (1): Handshake messages */ 448811fa71b9SJerome Forissier if( ssl->in_hslen != 0 ) 448911fa71b9SJerome Forissier { 449011fa71b9SJerome Forissier /* Hard assertion to be sure that no application data 449111fa71b9SJerome Forissier * is in flight, as corrupting ssl->in_msglen during 449211fa71b9SJerome Forissier * ssl->in_offt != NULL is fatal. */ 449311fa71b9SJerome Forissier if( ssl->in_offt != NULL ) 449411fa71b9SJerome Forissier { 449511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 449611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 449711fa71b9SJerome Forissier } 449811fa71b9SJerome Forissier 449911fa71b9SJerome Forissier /* 450011fa71b9SJerome Forissier * Get next Handshake message in the current record 450111fa71b9SJerome Forissier */ 450211fa71b9SJerome Forissier 450311fa71b9SJerome Forissier /* Notes: 450411fa71b9SJerome Forissier * (1) in_hslen is not necessarily the size of the 450511fa71b9SJerome Forissier * current handshake content: If DTLS handshake 450611fa71b9SJerome Forissier * fragmentation is used, that's the fragment 450711fa71b9SJerome Forissier * size instead. Using the total handshake message 450811fa71b9SJerome Forissier * size here is faulty and should be changed at 450911fa71b9SJerome Forissier * some point. 451011fa71b9SJerome Forissier * (2) While it doesn't seem to cause problems, one 451111fa71b9SJerome Forissier * has to be very careful not to assume that in_hslen 451211fa71b9SJerome Forissier * is always <= in_msglen in a sensible communication. 451311fa71b9SJerome Forissier * Again, it's wrong for DTLS handshake fragmentation. 451411fa71b9SJerome Forissier * The following check is therefore mandatory, and 451511fa71b9SJerome Forissier * should not be treated as a silently corrected assertion. 451611fa71b9SJerome Forissier * Additionally, ssl->in_hslen might be arbitrarily out of 451711fa71b9SJerome Forissier * bounds after handling a DTLS message with an unexpected 451811fa71b9SJerome Forissier * sequence number, see mbedtls_ssl_prepare_handshake_record. 451911fa71b9SJerome Forissier */ 452011fa71b9SJerome Forissier if( ssl->in_hslen < ssl->in_msglen ) 452111fa71b9SJerome Forissier { 452211fa71b9SJerome Forissier ssl->in_msglen -= ssl->in_hslen; 452311fa71b9SJerome Forissier memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, 452411fa71b9SJerome Forissier ssl->in_msglen ); 452511fa71b9SJerome Forissier 452611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", 452711fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen ); 452811fa71b9SJerome Forissier } 452911fa71b9SJerome Forissier else 453011fa71b9SJerome Forissier { 453111fa71b9SJerome Forissier ssl->in_msglen = 0; 453211fa71b9SJerome Forissier } 453311fa71b9SJerome Forissier 453411fa71b9SJerome Forissier ssl->in_hslen = 0; 453511fa71b9SJerome Forissier } 453611fa71b9SJerome Forissier /* Case (4): Application data */ 453711fa71b9SJerome Forissier else if( ssl->in_offt != NULL ) 453811fa71b9SJerome Forissier { 453911fa71b9SJerome Forissier return( 0 ); 454011fa71b9SJerome Forissier } 454111fa71b9SJerome Forissier /* Everything else (CCS & Alerts) */ 454211fa71b9SJerome Forissier else 454311fa71b9SJerome Forissier { 454411fa71b9SJerome Forissier ssl->in_msglen = 0; 454511fa71b9SJerome Forissier } 454611fa71b9SJerome Forissier 454711fa71b9SJerome Forissier return( 0 ); 454811fa71b9SJerome Forissier } 454911fa71b9SJerome Forissier 455011fa71b9SJerome Forissier static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl ) 455111fa71b9SJerome Forissier { 455211fa71b9SJerome Forissier if( ssl->in_msglen > 0 ) 455311fa71b9SJerome Forissier return( 1 ); 455411fa71b9SJerome Forissier 455511fa71b9SJerome Forissier return( 0 ); 455611fa71b9SJerome Forissier } 455711fa71b9SJerome Forissier 455811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 455911fa71b9SJerome Forissier 456011fa71b9SJerome Forissier static void ssl_free_buffered_record( mbedtls_ssl_context *ssl ) 456111fa71b9SJerome Forissier { 456211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 456311fa71b9SJerome Forissier if( hs == NULL ) 456411fa71b9SJerome Forissier return; 456511fa71b9SJerome Forissier 456611fa71b9SJerome Forissier if( hs->buffering.future_record.data != NULL ) 456711fa71b9SJerome Forissier { 456811fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= 456911fa71b9SJerome Forissier hs->buffering.future_record.len; 457011fa71b9SJerome Forissier 457111fa71b9SJerome Forissier mbedtls_free( hs->buffering.future_record.data ); 457211fa71b9SJerome Forissier hs->buffering.future_record.data = NULL; 457311fa71b9SJerome Forissier } 457411fa71b9SJerome Forissier } 457511fa71b9SJerome Forissier 457611fa71b9SJerome Forissier static int ssl_load_buffered_record( mbedtls_ssl_context *ssl ) 457711fa71b9SJerome Forissier { 457811fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 457911fa71b9SJerome Forissier unsigned char * rec; 458011fa71b9SJerome Forissier size_t rec_len; 458111fa71b9SJerome Forissier unsigned rec_epoch; 458211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 458311fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len; 458411fa71b9SJerome Forissier #else 458511fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN; 458611fa71b9SJerome Forissier #endif 458711fa71b9SJerome Forissier if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 458811fa71b9SJerome Forissier return( 0 ); 458911fa71b9SJerome Forissier 459011fa71b9SJerome Forissier if( hs == NULL ) 459111fa71b9SJerome Forissier return( 0 ); 459211fa71b9SJerome Forissier 459311fa71b9SJerome Forissier rec = hs->buffering.future_record.data; 459411fa71b9SJerome Forissier rec_len = hs->buffering.future_record.len; 459511fa71b9SJerome Forissier rec_epoch = hs->buffering.future_record.epoch; 459611fa71b9SJerome Forissier 459711fa71b9SJerome Forissier if( rec == NULL ) 459811fa71b9SJerome Forissier return( 0 ); 459911fa71b9SJerome Forissier 460011fa71b9SJerome Forissier /* Only consider loading future records if the 460111fa71b9SJerome Forissier * input buffer is empty. */ 460211fa71b9SJerome Forissier if( ssl_next_record_is_in_datagram( ssl ) == 1 ) 460311fa71b9SJerome Forissier return( 0 ); 460411fa71b9SJerome Forissier 460511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) ); 460611fa71b9SJerome Forissier 460711fa71b9SJerome Forissier if( rec_epoch != ssl->in_epoch ) 460811fa71b9SJerome Forissier { 460911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) ); 461011fa71b9SJerome Forissier goto exit; 461111fa71b9SJerome Forissier } 461211fa71b9SJerome Forissier 461311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) ); 461411fa71b9SJerome Forissier 461511fa71b9SJerome Forissier /* Double-check that the record is not too large */ 461611fa71b9SJerome Forissier if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) ) 461711fa71b9SJerome Forissier { 461811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 461911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 462011fa71b9SJerome Forissier } 462111fa71b9SJerome Forissier 462211fa71b9SJerome Forissier memcpy( ssl->in_hdr, rec, rec_len ); 462311fa71b9SJerome Forissier ssl->in_left = rec_len; 462411fa71b9SJerome Forissier ssl->next_record_offset = 0; 462511fa71b9SJerome Forissier 462611fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 462711fa71b9SJerome Forissier 462811fa71b9SJerome Forissier exit: 462911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) ); 463011fa71b9SJerome Forissier return( 0 ); 463111fa71b9SJerome Forissier } 463211fa71b9SJerome Forissier 463311fa71b9SJerome Forissier static int ssl_buffer_future_record( mbedtls_ssl_context *ssl, 463411fa71b9SJerome Forissier mbedtls_record const *rec ) 463511fa71b9SJerome Forissier { 463611fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 463711fa71b9SJerome Forissier 463811fa71b9SJerome Forissier /* Don't buffer future records outside handshakes. */ 463911fa71b9SJerome Forissier if( hs == NULL ) 464011fa71b9SJerome Forissier return( 0 ); 464111fa71b9SJerome Forissier 464211fa71b9SJerome Forissier /* Only buffer handshake records (we are only interested 464311fa71b9SJerome Forissier * in Finished messages). */ 464411fa71b9SJerome Forissier if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE ) 464511fa71b9SJerome Forissier return( 0 ); 464611fa71b9SJerome Forissier 464711fa71b9SJerome Forissier /* Don't buffer more than one future epoch record. */ 464811fa71b9SJerome Forissier if( hs->buffering.future_record.data != NULL ) 464911fa71b9SJerome Forissier return( 0 ); 465011fa71b9SJerome Forissier 465111fa71b9SJerome Forissier /* Don't buffer record if there's not enough buffering space remaining. */ 465211fa71b9SJerome Forissier if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING - 465311fa71b9SJerome Forissier hs->buffering.total_bytes_buffered ) ) 465411fa71b9SJerome Forissier { 4655*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET 4656*7901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET 4657*7901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET 4658*7901324dSJerome Forissier " bytes buffered) -- ignore\n", 4659*7901324dSJerome Forissier rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING, 4660*7901324dSJerome Forissier hs->buffering.total_bytes_buffered ) ); 466111fa71b9SJerome Forissier return( 0 ); 466211fa71b9SJerome Forissier } 466311fa71b9SJerome Forissier 466411fa71b9SJerome Forissier /* Buffer record */ 466511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u", 4666*7901324dSJerome Forissier ssl->in_epoch + 1U ) ); 466711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len ); 466811fa71b9SJerome Forissier 466911fa71b9SJerome Forissier /* ssl_parse_record_header() only considers records 467011fa71b9SJerome Forissier * of the next epoch as candidates for buffering. */ 467111fa71b9SJerome Forissier hs->buffering.future_record.epoch = ssl->in_epoch + 1; 467211fa71b9SJerome Forissier hs->buffering.future_record.len = rec->buf_len; 467311fa71b9SJerome Forissier 467411fa71b9SJerome Forissier hs->buffering.future_record.data = 467511fa71b9SJerome Forissier mbedtls_calloc( 1, hs->buffering.future_record.len ); 467611fa71b9SJerome Forissier if( hs->buffering.future_record.data == NULL ) 467711fa71b9SJerome Forissier { 467811fa71b9SJerome Forissier /* If we run out of RAM trying to buffer a 467911fa71b9SJerome Forissier * record from the next epoch, just ignore. */ 468011fa71b9SJerome Forissier return( 0 ); 468111fa71b9SJerome Forissier } 468211fa71b9SJerome Forissier 468311fa71b9SJerome Forissier memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len ); 468411fa71b9SJerome Forissier 468511fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += rec->buf_len; 468611fa71b9SJerome Forissier return( 0 ); 468711fa71b9SJerome Forissier } 468811fa71b9SJerome Forissier 468911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 469011fa71b9SJerome Forissier 469111fa71b9SJerome Forissier static int ssl_get_next_record( mbedtls_ssl_context *ssl ) 469211fa71b9SJerome Forissier { 469311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 469411fa71b9SJerome Forissier mbedtls_record rec; 469511fa71b9SJerome Forissier 469611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 469711fa71b9SJerome Forissier /* We might have buffered a future record; if so, 469811fa71b9SJerome Forissier * and if the epoch matches now, load it. 469911fa71b9SJerome Forissier * On success, this call will set ssl->in_left to 470011fa71b9SJerome Forissier * the length of the buffered record, so that 470111fa71b9SJerome Forissier * the calls to ssl_fetch_input() below will 470211fa71b9SJerome Forissier * essentially be no-ops. */ 470311fa71b9SJerome Forissier ret = ssl_load_buffered_record( ssl ); 470411fa71b9SJerome Forissier if( ret != 0 ) 470511fa71b9SJerome Forissier return( ret ); 470611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 470711fa71b9SJerome Forissier 470811fa71b9SJerome Forissier /* Ensure that we have enough space available for the default form 470911fa71b9SJerome Forissier * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, 471011fa71b9SJerome Forissier * with no space for CIDs counted in). */ 471111fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) ); 471211fa71b9SJerome Forissier if( ret != 0 ) 471311fa71b9SJerome Forissier { 471411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); 471511fa71b9SJerome Forissier return( ret ); 471611fa71b9SJerome Forissier } 471711fa71b9SJerome Forissier 471811fa71b9SJerome Forissier ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec ); 471911fa71b9SJerome Forissier if( ret != 0 ) 472011fa71b9SJerome Forissier { 472111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 472211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 472311fa71b9SJerome Forissier { 472411fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE ) 472511fa71b9SJerome Forissier { 472611fa71b9SJerome Forissier ret = ssl_buffer_future_record( ssl, &rec ); 472711fa71b9SJerome Forissier if( ret != 0 ) 472811fa71b9SJerome Forissier return( ret ); 472911fa71b9SJerome Forissier 473011fa71b9SJerome Forissier /* Fall through to handling of unexpected records */ 473111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD; 473211fa71b9SJerome Forissier } 473311fa71b9SJerome Forissier 473411fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) 473511fa71b9SJerome Forissier { 473611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) 473711fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 473811fa71b9SJerome Forissier * assuming no CID and no offset between record content and 473911fa71b9SJerome Forissier * record plaintext. */ 474011fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 474111fa71b9SJerome Forissier 474211fa71b9SJerome Forissier /* Setup internal message pointers from record structure. */ 474311fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 474411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 474511fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 474611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 474711fa71b9SJerome Forissier ssl->in_iv = ssl->in_msg = ssl->in_len + 2; 474811fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 474911fa71b9SJerome Forissier 475011fa71b9SJerome Forissier ret = ssl_check_client_reconnect( ssl ); 475111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret ); 475211fa71b9SJerome Forissier if( ret != 0 ) 475311fa71b9SJerome Forissier return( ret ); 475411fa71b9SJerome Forissier #endif 475511fa71b9SJerome Forissier 475611fa71b9SJerome Forissier /* Skip unexpected record (but not whole datagram) */ 475711fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 475811fa71b9SJerome Forissier 475911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " 476011fa71b9SJerome Forissier "(header)" ) ); 476111fa71b9SJerome Forissier } 476211fa71b9SJerome Forissier else 476311fa71b9SJerome Forissier { 476411fa71b9SJerome Forissier /* Skip invalid record and the rest of the datagram */ 476511fa71b9SJerome Forissier ssl->next_record_offset = 0; 476611fa71b9SJerome Forissier ssl->in_left = 0; 476711fa71b9SJerome Forissier 476811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " 476911fa71b9SJerome Forissier "(header)" ) ); 477011fa71b9SJerome Forissier } 477111fa71b9SJerome Forissier 477211fa71b9SJerome Forissier /* Get next record */ 477311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 477411fa71b9SJerome Forissier } 477511fa71b9SJerome Forissier else 477611fa71b9SJerome Forissier #endif 477711fa71b9SJerome Forissier { 477811fa71b9SJerome Forissier return( ret ); 477911fa71b9SJerome Forissier } 478011fa71b9SJerome Forissier } 478111fa71b9SJerome Forissier 478211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 478311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 478411fa71b9SJerome Forissier { 478511fa71b9SJerome Forissier /* Remember offset of next record within datagram. */ 478611fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len; 478711fa71b9SJerome Forissier if( ssl->next_record_offset < ssl->in_left ) 478811fa71b9SJerome Forissier { 478911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); 479011fa71b9SJerome Forissier } 479111fa71b9SJerome Forissier } 479211fa71b9SJerome Forissier else 479311fa71b9SJerome Forissier #endif 479411fa71b9SJerome Forissier { 479511fa71b9SJerome Forissier /* 479611fa71b9SJerome Forissier * Fetch record contents from underlying transport. 479711fa71b9SJerome Forissier */ 479811fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len ); 479911fa71b9SJerome Forissier if( ret != 0 ) 480011fa71b9SJerome Forissier { 480111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); 480211fa71b9SJerome Forissier return( ret ); 480311fa71b9SJerome Forissier } 480411fa71b9SJerome Forissier 480511fa71b9SJerome Forissier ssl->in_left = 0; 480611fa71b9SJerome Forissier } 480711fa71b9SJerome Forissier 480811fa71b9SJerome Forissier /* 480911fa71b9SJerome Forissier * Decrypt record contents. 481011fa71b9SJerome Forissier */ 481111fa71b9SJerome Forissier 481211fa71b9SJerome Forissier if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 ) 481311fa71b9SJerome Forissier { 481411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 481511fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 481611fa71b9SJerome Forissier { 481711fa71b9SJerome Forissier /* Silently discard invalid records */ 481811fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 481911fa71b9SJerome Forissier { 482011fa71b9SJerome Forissier /* Except when waiting for Finished as a bad mac here 482111fa71b9SJerome Forissier * probably means something went wrong in the handshake 482211fa71b9SJerome Forissier * (eg wrong psk used, mitm downgrade attempt, etc.) */ 482311fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || 482411fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) 482511fa71b9SJerome Forissier { 482611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 482711fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 482811fa71b9SJerome Forissier { 482911fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, 483011fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 483111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); 483211fa71b9SJerome Forissier } 483311fa71b9SJerome Forissier #endif 483411fa71b9SJerome Forissier return( ret ); 483511fa71b9SJerome Forissier } 483611fa71b9SJerome Forissier 483711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) 483811fa71b9SJerome Forissier if( ssl->conf->badmac_limit != 0 && 483911fa71b9SJerome Forissier ++ssl->badmac_seen >= ssl->conf->badmac_limit ) 484011fa71b9SJerome Forissier { 484111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); 484211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_MAC ); 484311fa71b9SJerome Forissier } 484411fa71b9SJerome Forissier #endif 484511fa71b9SJerome Forissier 484611fa71b9SJerome Forissier /* As above, invalid records cause 484711fa71b9SJerome Forissier * dismissal of the whole datagram. */ 484811fa71b9SJerome Forissier 484911fa71b9SJerome Forissier ssl->next_record_offset = 0; 485011fa71b9SJerome Forissier ssl->in_left = 0; 485111fa71b9SJerome Forissier 485211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); 485311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING ); 485411fa71b9SJerome Forissier } 485511fa71b9SJerome Forissier 485611fa71b9SJerome Forissier return( ret ); 485711fa71b9SJerome Forissier } 485811fa71b9SJerome Forissier else 485911fa71b9SJerome Forissier #endif 486011fa71b9SJerome Forissier { 486111fa71b9SJerome Forissier /* Error out (and send alert) on invalid records */ 486211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) 486311fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) 486411fa71b9SJerome Forissier { 486511fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, 486611fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 486711fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); 486811fa71b9SJerome Forissier } 486911fa71b9SJerome Forissier #endif 487011fa71b9SJerome Forissier return( ret ); 487111fa71b9SJerome Forissier } 487211fa71b9SJerome Forissier } 487311fa71b9SJerome Forissier 487411fa71b9SJerome Forissier 487511fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records, 487611fa71b9SJerome Forissier * assuming no CID and no offset between record content and 487711fa71b9SJerome Forissier * record plaintext. */ 487811fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 487911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 488011fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len; 488111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 488211fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 488311fa71b9SJerome Forissier 488411fa71b9SJerome Forissier /* The record content type may change during decryption, 488511fa71b9SJerome Forissier * so re-read it. */ 488611fa71b9SJerome Forissier ssl->in_msgtype = rec.type; 488711fa71b9SJerome Forissier /* Also update the input buffer, because unfortunately 488811fa71b9SJerome Forissier * the server-side ssl_parse_client_hello() reparses the 488911fa71b9SJerome Forissier * record header when receiving a ClientHello initiating 489011fa71b9SJerome Forissier * a renegotiation. */ 489111fa71b9SJerome Forissier ssl->in_hdr[0] = rec.type; 489211fa71b9SJerome Forissier ssl->in_msg = rec.buf + rec.data_offset; 489311fa71b9SJerome Forissier ssl->in_msglen = rec.data_len; 489411fa71b9SJerome Forissier ssl->in_len[0] = (unsigned char)( rec.data_len >> 8 ); 489511fa71b9SJerome Forissier ssl->in_len[1] = (unsigned char)( rec.data_len ); 489611fa71b9SJerome Forissier 489711fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 489811fa71b9SJerome Forissier if( ssl->transform_in != NULL && 489911fa71b9SJerome Forissier ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) 490011fa71b9SJerome Forissier { 490111fa71b9SJerome Forissier if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) 490211fa71b9SJerome Forissier { 490311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); 490411fa71b9SJerome Forissier return( ret ); 490511fa71b9SJerome Forissier } 490611fa71b9SJerome Forissier 490711fa71b9SJerome Forissier /* Check actual (decompress) record content length against 490811fa71b9SJerome Forissier * configured maximum. */ 490911fa71b9SJerome Forissier if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) 491011fa71b9SJerome Forissier { 491111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); 491211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 491311fa71b9SJerome Forissier } 491411fa71b9SJerome Forissier } 491511fa71b9SJerome Forissier #endif /* MBEDTLS_ZLIB_SUPPORT */ 491611fa71b9SJerome Forissier 491711fa71b9SJerome Forissier return( 0 ); 491811fa71b9SJerome Forissier } 491911fa71b9SJerome Forissier 492011fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) 492111fa71b9SJerome Forissier { 492211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 492311fa71b9SJerome Forissier 492411fa71b9SJerome Forissier /* 492511fa71b9SJerome Forissier * Handle particular types of records 492611fa71b9SJerome Forissier */ 492711fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 492811fa71b9SJerome Forissier { 492911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) 493011fa71b9SJerome Forissier { 493111fa71b9SJerome Forissier return( ret ); 493211fa71b9SJerome Forissier } 493311fa71b9SJerome Forissier } 493411fa71b9SJerome Forissier 493511fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 493611fa71b9SJerome Forissier { 493711fa71b9SJerome Forissier if( ssl->in_msglen != 1 ) 493811fa71b9SJerome Forissier { 4939*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET, 494011fa71b9SJerome Forissier ssl->in_msglen ) ); 494111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 494211fa71b9SJerome Forissier } 494311fa71b9SJerome Forissier 494411fa71b9SJerome Forissier if( ssl->in_msg[0] != 1 ) 494511fa71b9SJerome Forissier { 494611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x", 494711fa71b9SJerome Forissier ssl->in_msg[0] ) ); 494811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 494911fa71b9SJerome Forissier } 495011fa71b9SJerome Forissier 495111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 495211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 495311fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && 495411fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) 495511fa71b9SJerome Forissier { 495611fa71b9SJerome Forissier if( ssl->handshake == NULL ) 495711fa71b9SJerome Forissier { 495811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) ); 495911fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); 496011fa71b9SJerome Forissier } 496111fa71b9SJerome Forissier 496211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) ); 496311fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_EARLY_MESSAGE ); 496411fa71b9SJerome Forissier } 496511fa71b9SJerome Forissier #endif 496611fa71b9SJerome Forissier } 496711fa71b9SJerome Forissier 496811fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) 496911fa71b9SJerome Forissier { 497011fa71b9SJerome Forissier if( ssl->in_msglen != 2 ) 497111fa71b9SJerome Forissier { 497211fa71b9SJerome Forissier /* Note: Standard allows for more than one 2 byte alert 497311fa71b9SJerome Forissier to be packed in a single message, but Mbed TLS doesn't 497411fa71b9SJerome Forissier currently support this. */ 4975*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %" MBEDTLS_PRINTF_SIZET, 497611fa71b9SJerome Forissier ssl->in_msglen ) ); 497711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INVALID_RECORD ); 497811fa71b9SJerome Forissier } 497911fa71b9SJerome Forissier 4980*7901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%u:%u]", 498111fa71b9SJerome Forissier ssl->in_msg[0], ssl->in_msg[1] ) ); 498211fa71b9SJerome Forissier 498311fa71b9SJerome Forissier /* 498411fa71b9SJerome Forissier * Ignore non-fatal alerts, except close_notify and no_renegotiation 498511fa71b9SJerome Forissier */ 498611fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) 498711fa71b9SJerome Forissier { 498811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", 498911fa71b9SJerome Forissier ssl->in_msg[1] ) ); 499011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); 499111fa71b9SJerome Forissier } 499211fa71b9SJerome Forissier 499311fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 499411fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) 499511fa71b9SJerome Forissier { 499611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); 499711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); 499811fa71b9SJerome Forissier } 499911fa71b9SJerome Forissier 500011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) 500111fa71b9SJerome Forissier if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 500211fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) 500311fa71b9SJerome Forissier { 500411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) ); 500511fa71b9SJerome Forissier /* Will be handled when trying to parse ServerHello */ 500611fa71b9SJerome Forissier return( 0 ); 500711fa71b9SJerome Forissier } 500811fa71b9SJerome Forissier #endif 500911fa71b9SJerome Forissier 501011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) 501111fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && 501211fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 501311fa71b9SJerome Forissier ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && 501411fa71b9SJerome Forissier ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) 501511fa71b9SJerome Forissier { 501611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); 501711fa71b9SJerome Forissier /* Will be handled in mbedtls_ssl_parse_certificate() */ 501811fa71b9SJerome Forissier return( 0 ); 501911fa71b9SJerome Forissier } 502011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ 502111fa71b9SJerome Forissier 502211fa71b9SJerome Forissier /* Silently ignore: fetch new message */ 502311fa71b9SJerome Forissier return MBEDTLS_ERR_SSL_NON_FATAL; 502411fa71b9SJerome Forissier } 502511fa71b9SJerome Forissier 502611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 502711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 502811fa71b9SJerome Forissier { 502911fa71b9SJerome Forissier /* Drop unexpected ApplicationData records, 503011fa71b9SJerome Forissier * except at the beginning of renegotiations */ 503111fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && 503211fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER 503311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 503411fa71b9SJerome Forissier && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 503511fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_HELLO ) 503611fa71b9SJerome Forissier #endif 503711fa71b9SJerome Forissier ) 503811fa71b9SJerome Forissier { 503911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); 504011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_NON_FATAL ); 504111fa71b9SJerome Forissier } 504211fa71b9SJerome Forissier 504311fa71b9SJerome Forissier if( ssl->handshake != NULL && 504411fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 504511fa71b9SJerome Forissier { 504611fa71b9SJerome Forissier mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl ); 504711fa71b9SJerome Forissier } 504811fa71b9SJerome Forissier } 504911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 505011fa71b9SJerome Forissier 505111fa71b9SJerome Forissier return( 0 ); 505211fa71b9SJerome Forissier } 505311fa71b9SJerome Forissier 505411fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) 505511fa71b9SJerome Forissier { 505611fa71b9SJerome Forissier return( mbedtls_ssl_send_alert_message( ssl, 505711fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL, 505811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ); 505911fa71b9SJerome Forissier } 506011fa71b9SJerome Forissier 506111fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, 506211fa71b9SJerome Forissier unsigned char level, 506311fa71b9SJerome Forissier unsigned char message ) 506411fa71b9SJerome Forissier { 506511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 506611fa71b9SJerome Forissier 506711fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 506811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 506911fa71b9SJerome Forissier 507011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); 507111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); 507211fa71b9SJerome Forissier 507311fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; 507411fa71b9SJerome Forissier ssl->out_msglen = 2; 507511fa71b9SJerome Forissier ssl->out_msg[0] = level; 507611fa71b9SJerome Forissier ssl->out_msg[1] = message; 507711fa71b9SJerome Forissier 507811fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 507911fa71b9SJerome Forissier { 508011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 508111fa71b9SJerome Forissier return( ret ); 508211fa71b9SJerome Forissier } 508311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); 508411fa71b9SJerome Forissier 508511fa71b9SJerome Forissier return( 0 ); 508611fa71b9SJerome Forissier } 508711fa71b9SJerome Forissier 508811fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) 508911fa71b9SJerome Forissier { 509011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 509111fa71b9SJerome Forissier 509211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); 509311fa71b9SJerome Forissier 509411fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; 509511fa71b9SJerome Forissier ssl->out_msglen = 1; 509611fa71b9SJerome Forissier ssl->out_msg[0] = 1; 509711fa71b9SJerome Forissier 509811fa71b9SJerome Forissier ssl->state++; 509911fa71b9SJerome Forissier 510011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 ) 510111fa71b9SJerome Forissier { 510211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret ); 510311fa71b9SJerome Forissier return( ret ); 510411fa71b9SJerome Forissier } 510511fa71b9SJerome Forissier 510611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); 510711fa71b9SJerome Forissier 510811fa71b9SJerome Forissier return( 0 ); 510911fa71b9SJerome Forissier } 511011fa71b9SJerome Forissier 511111fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) 511211fa71b9SJerome Forissier { 511311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 511411fa71b9SJerome Forissier 511511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); 511611fa71b9SJerome Forissier 511711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 511811fa71b9SJerome Forissier { 511911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 512011fa71b9SJerome Forissier return( ret ); 512111fa71b9SJerome Forissier } 512211fa71b9SJerome Forissier 512311fa71b9SJerome Forissier if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) 512411fa71b9SJerome Forissier { 512511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); 512611fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 512711fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); 512811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 512911fa71b9SJerome Forissier } 513011fa71b9SJerome Forissier 513111fa71b9SJerome Forissier /* CCS records are only accepted if they have length 1 and content '1', 513211fa71b9SJerome Forissier * so we don't need to check this here. */ 513311fa71b9SJerome Forissier 513411fa71b9SJerome Forissier /* 513511fa71b9SJerome Forissier * Switch to our negotiated transform and session parameters for inbound 513611fa71b9SJerome Forissier * data. 513711fa71b9SJerome Forissier */ 513811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); 513911fa71b9SJerome Forissier ssl->transform_in = ssl->transform_negotiate; 514011fa71b9SJerome Forissier ssl->session_in = ssl->session_negotiate; 514111fa71b9SJerome Forissier 514211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 514311fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 514411fa71b9SJerome Forissier { 514511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 514611fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_reset( ssl ); 514711fa71b9SJerome Forissier #endif 514811fa71b9SJerome Forissier 514911fa71b9SJerome Forissier /* Increment epoch */ 515011fa71b9SJerome Forissier if( ++ssl->in_epoch == 0 ) 515111fa71b9SJerome Forissier { 515211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); 515311fa71b9SJerome Forissier /* This is highly unlikely to happen for legitimate reasons, so 515411fa71b9SJerome Forissier treat it as an attack and don't send an alert. */ 515511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); 515611fa71b9SJerome Forissier } 515711fa71b9SJerome Forissier } 515811fa71b9SJerome Forissier else 515911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 516011fa71b9SJerome Forissier memset( ssl->in_ctr, 0, 8 ); 516111fa71b9SJerome Forissier 516211fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers( ssl ); 516311fa71b9SJerome Forissier 516411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) 516511fa71b9SJerome Forissier if( mbedtls_ssl_hw_record_activate != NULL ) 516611fa71b9SJerome Forissier { 516711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) 516811fa71b9SJerome Forissier { 516911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); 517011fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 517111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); 517211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); 517311fa71b9SJerome Forissier } 517411fa71b9SJerome Forissier } 517511fa71b9SJerome Forissier #endif 517611fa71b9SJerome Forissier 517711fa71b9SJerome Forissier ssl->state++; 517811fa71b9SJerome Forissier 517911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); 518011fa71b9SJerome Forissier 518111fa71b9SJerome Forissier return( 0 ); 518211fa71b9SJerome Forissier } 518311fa71b9SJerome Forissier 518411fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the 518511fa71b9SJerome Forissier * next outgoing record is set, deduce the other pointers. 518611fa71b9SJerome Forissier * 518711fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 518811fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->out_hdr, 518911fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 519011fa71b9SJerome Forissier */ 519111fa71b9SJerome Forissier 5192*7901324dSJerome Forissier static size_t ssl_transform_get_explicit_iv_len( 5193*7901324dSJerome Forissier mbedtls_ssl_transform const *transform ) 5194*7901324dSJerome Forissier { 5195*7901324dSJerome Forissier if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) 5196*7901324dSJerome Forissier return( 0 ); 5197*7901324dSJerome Forissier 5198*7901324dSJerome Forissier return( transform->ivlen - transform->fixed_ivlen ); 5199*7901324dSJerome Forissier } 5200*7901324dSJerome Forissier 520111fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl, 520211fa71b9SJerome Forissier mbedtls_ssl_transform *transform ) 520311fa71b9SJerome Forissier { 520411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 520511fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 520611fa71b9SJerome Forissier { 520711fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr + 3; 520811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 520911fa71b9SJerome Forissier ssl->out_cid = ssl->out_ctr + 8; 521011fa71b9SJerome Forissier ssl->out_len = ssl->out_cid; 521111fa71b9SJerome Forissier if( transform != NULL ) 521211fa71b9SJerome Forissier ssl->out_len += transform->out_cid_len; 521311fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 521411fa71b9SJerome Forissier ssl->out_len = ssl->out_ctr + 8; 521511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 521611fa71b9SJerome Forissier ssl->out_iv = ssl->out_len + 2; 521711fa71b9SJerome Forissier } 521811fa71b9SJerome Forissier else 521911fa71b9SJerome Forissier #endif 522011fa71b9SJerome Forissier { 522111fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr - 8; 522211fa71b9SJerome Forissier ssl->out_len = ssl->out_hdr + 3; 522311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 522411fa71b9SJerome Forissier ssl->out_cid = ssl->out_len; 522511fa71b9SJerome Forissier #endif 522611fa71b9SJerome Forissier ssl->out_iv = ssl->out_hdr + 5; 522711fa71b9SJerome Forissier } 522811fa71b9SJerome Forissier 522911fa71b9SJerome Forissier ssl->out_msg = ssl->out_iv; 5230*7901324dSJerome Forissier /* Adjust out_msg to make space for explicit IV, if used. */ 5231*7901324dSJerome Forissier if( transform != NULL ) 5232*7901324dSJerome Forissier ssl->out_msg += ssl_transform_get_explicit_iv_len( transform ); 523311fa71b9SJerome Forissier } 523411fa71b9SJerome Forissier 523511fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the 523611fa71b9SJerome Forissier * next incoming record is set, deduce the other pointers. 523711fa71b9SJerome Forissier * 523811fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number 523911fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->in_hdr, 524011fa71b9SJerome Forissier * and the caller has to make sure there's space for this. 524111fa71b9SJerome Forissier */ 524211fa71b9SJerome Forissier 524311fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl ) 524411fa71b9SJerome Forissier { 524511fa71b9SJerome Forissier /* This function sets the pointers to match the case 524611fa71b9SJerome Forissier * of unprotected TLS/DTLS records, with both ssl->in_iv 524711fa71b9SJerome Forissier * and ssl->in_msg pointing to the beginning of the record 524811fa71b9SJerome Forissier * content. 524911fa71b9SJerome Forissier * 525011fa71b9SJerome Forissier * When decrypting a protected record, ssl->in_msg 525111fa71b9SJerome Forissier * will be shifted to point to the beginning of the 525211fa71b9SJerome Forissier * record plaintext. 525311fa71b9SJerome Forissier */ 525411fa71b9SJerome Forissier 525511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 525611fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 525711fa71b9SJerome Forissier { 525811fa71b9SJerome Forissier /* This sets the header pointers to match records 525911fa71b9SJerome Forissier * without CID. When we receive a record containing 526011fa71b9SJerome Forissier * a CID, the fields are shifted accordingly in 526111fa71b9SJerome Forissier * ssl_parse_record_header(). */ 526211fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr + 3; 526311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 526411fa71b9SJerome Forissier ssl->in_cid = ssl->in_ctr + 8; 526511fa71b9SJerome Forissier ssl->in_len = ssl->in_cid; /* Default: no CID */ 526611fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 526711fa71b9SJerome Forissier ssl->in_len = ssl->in_ctr + 8; 526811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 526911fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2; 527011fa71b9SJerome Forissier } 527111fa71b9SJerome Forissier else 527211fa71b9SJerome Forissier #endif 527311fa71b9SJerome Forissier { 527411fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr - 8; 527511fa71b9SJerome Forissier ssl->in_len = ssl->in_hdr + 3; 527611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 527711fa71b9SJerome Forissier ssl->in_cid = ssl->in_len; 527811fa71b9SJerome Forissier #endif 527911fa71b9SJerome Forissier ssl->in_iv = ssl->in_hdr + 5; 528011fa71b9SJerome Forissier } 528111fa71b9SJerome Forissier 528211fa71b9SJerome Forissier /* This will be adjusted at record decryption time. */ 528311fa71b9SJerome Forissier ssl->in_msg = ssl->in_iv; 528411fa71b9SJerome Forissier } 528511fa71b9SJerome Forissier 528611fa71b9SJerome Forissier /* 528711fa71b9SJerome Forissier * Setup an SSL context 528811fa71b9SJerome Forissier */ 528911fa71b9SJerome Forissier 529011fa71b9SJerome Forissier void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) 529111fa71b9SJerome Forissier { 529211fa71b9SJerome Forissier /* Set the incoming and outgoing record pointers. */ 529311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 529411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 529511fa71b9SJerome Forissier { 529611fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf; 529711fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf; 529811fa71b9SJerome Forissier } 529911fa71b9SJerome Forissier else 530011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 530111fa71b9SJerome Forissier { 530211fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8; 530311fa71b9SJerome Forissier ssl->in_hdr = ssl->in_buf + 8; 530411fa71b9SJerome Forissier } 530511fa71b9SJerome Forissier 530611fa71b9SJerome Forissier /* Derive other internal pointers. */ 530711fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); 530811fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers ( ssl ); 530911fa71b9SJerome Forissier } 531011fa71b9SJerome Forissier 531111fa71b9SJerome Forissier /* 531211fa71b9SJerome Forissier * SSL get accessors 531311fa71b9SJerome Forissier */ 531411fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) 531511fa71b9SJerome Forissier { 531611fa71b9SJerome Forissier return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); 531711fa71b9SJerome Forissier } 531811fa71b9SJerome Forissier 531911fa71b9SJerome Forissier int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl ) 532011fa71b9SJerome Forissier { 532111fa71b9SJerome Forissier /* 532211fa71b9SJerome Forissier * Case A: We're currently holding back 532311fa71b9SJerome Forissier * a message for further processing. 532411fa71b9SJerome Forissier */ 532511fa71b9SJerome Forissier 532611fa71b9SJerome Forissier if( ssl->keep_current_message == 1 ) 532711fa71b9SJerome Forissier { 532811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) ); 532911fa71b9SJerome Forissier return( 1 ); 533011fa71b9SJerome Forissier } 533111fa71b9SJerome Forissier 533211fa71b9SJerome Forissier /* 533311fa71b9SJerome Forissier * Case B: Further records are pending in the current datagram. 533411fa71b9SJerome Forissier */ 533511fa71b9SJerome Forissier 533611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 533711fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 533811fa71b9SJerome Forissier ssl->in_left > ssl->next_record_offset ) 533911fa71b9SJerome Forissier { 534011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) ); 534111fa71b9SJerome Forissier return( 1 ); 534211fa71b9SJerome Forissier } 534311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 534411fa71b9SJerome Forissier 534511fa71b9SJerome Forissier /* 534611fa71b9SJerome Forissier * Case C: A handshake message is being processed. 534711fa71b9SJerome Forissier */ 534811fa71b9SJerome Forissier 534911fa71b9SJerome Forissier if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen ) 535011fa71b9SJerome Forissier { 535111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) ); 535211fa71b9SJerome Forissier return( 1 ); 535311fa71b9SJerome Forissier } 535411fa71b9SJerome Forissier 535511fa71b9SJerome Forissier /* 535611fa71b9SJerome Forissier * Case D: An application data message is being processed 535711fa71b9SJerome Forissier */ 535811fa71b9SJerome Forissier if( ssl->in_offt != NULL ) 535911fa71b9SJerome Forissier { 536011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) ); 536111fa71b9SJerome Forissier return( 1 ); 536211fa71b9SJerome Forissier } 536311fa71b9SJerome Forissier 536411fa71b9SJerome Forissier /* 536511fa71b9SJerome Forissier * In all other cases, the rest of the message can be dropped. 536611fa71b9SJerome Forissier * As in ssl_get_next_record, this needs to be adapted if 536711fa71b9SJerome Forissier * we implement support for multiple alerts in single records. 536811fa71b9SJerome Forissier */ 536911fa71b9SJerome Forissier 537011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) ); 537111fa71b9SJerome Forissier return( 0 ); 537211fa71b9SJerome Forissier } 537311fa71b9SJerome Forissier 537411fa71b9SJerome Forissier 537511fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) 537611fa71b9SJerome Forissier { 537711fa71b9SJerome Forissier size_t transform_expansion = 0; 537811fa71b9SJerome Forissier const mbedtls_ssl_transform *transform = ssl->transform_out; 537911fa71b9SJerome Forissier unsigned block_size; 538011fa71b9SJerome Forissier 538111fa71b9SJerome Forissier size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl ); 538211fa71b9SJerome Forissier 538311fa71b9SJerome Forissier if( transform == NULL ) 538411fa71b9SJerome Forissier return( (int) out_hdr_len ); 538511fa71b9SJerome Forissier 538611fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 538711fa71b9SJerome Forissier if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) 538811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 538911fa71b9SJerome Forissier #endif 539011fa71b9SJerome Forissier 539111fa71b9SJerome Forissier switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) 539211fa71b9SJerome Forissier { 539311fa71b9SJerome Forissier case MBEDTLS_MODE_GCM: 539411fa71b9SJerome Forissier case MBEDTLS_MODE_CCM: 539511fa71b9SJerome Forissier case MBEDTLS_MODE_CHACHAPOLY: 539611fa71b9SJerome Forissier case MBEDTLS_MODE_STREAM: 539711fa71b9SJerome Forissier transform_expansion = transform->minlen; 539811fa71b9SJerome Forissier break; 539911fa71b9SJerome Forissier 540011fa71b9SJerome Forissier case MBEDTLS_MODE_CBC: 540111fa71b9SJerome Forissier 540211fa71b9SJerome Forissier block_size = mbedtls_cipher_get_block_size( 540311fa71b9SJerome Forissier &transform->cipher_ctx_enc ); 540411fa71b9SJerome Forissier 540511fa71b9SJerome Forissier /* Expansion due to the addition of the MAC. */ 540611fa71b9SJerome Forissier transform_expansion += transform->maclen; 540711fa71b9SJerome Forissier 540811fa71b9SJerome Forissier /* Expansion due to the addition of CBC padding; 540911fa71b9SJerome Forissier * Theoretically up to 256 bytes, but we never use 541011fa71b9SJerome Forissier * more than the block size of the underlying cipher. */ 541111fa71b9SJerome Forissier transform_expansion += block_size; 541211fa71b9SJerome Forissier 541311fa71b9SJerome Forissier /* For TLS 1.1 or higher, an explicit IV is added 541411fa71b9SJerome Forissier * after the record header. */ 541511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) 541611fa71b9SJerome Forissier if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) 541711fa71b9SJerome Forissier transform_expansion += block_size; 541811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ 541911fa71b9SJerome Forissier 542011fa71b9SJerome Forissier break; 542111fa71b9SJerome Forissier 542211fa71b9SJerome Forissier default: 542311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 542411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 542511fa71b9SJerome Forissier } 542611fa71b9SJerome Forissier 542711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 542811fa71b9SJerome Forissier if( transform->out_cid_len != 0 ) 542911fa71b9SJerome Forissier transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; 543011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 543111fa71b9SJerome Forissier 543211fa71b9SJerome Forissier return( (int)( out_hdr_len + transform_expansion ) ); 543311fa71b9SJerome Forissier } 543411fa71b9SJerome Forissier 543511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 543611fa71b9SJerome Forissier /* 543711fa71b9SJerome Forissier * Check record counters and renegotiate if they're above the limit. 543811fa71b9SJerome Forissier */ 543911fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) 544011fa71b9SJerome Forissier { 544111fa71b9SJerome Forissier size_t ep_len = mbedtls_ssl_ep_len( ssl ); 544211fa71b9SJerome Forissier int in_ctr_cmp; 544311fa71b9SJerome Forissier int out_ctr_cmp; 544411fa71b9SJerome Forissier 544511fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || 544611fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || 544711fa71b9SJerome Forissier ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) 544811fa71b9SJerome Forissier { 544911fa71b9SJerome Forissier return( 0 ); 545011fa71b9SJerome Forissier } 545111fa71b9SJerome Forissier 545211fa71b9SJerome Forissier in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, 545311fa71b9SJerome Forissier ssl->conf->renego_period + ep_len, 8 - ep_len ); 545411fa71b9SJerome Forissier out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len, 545511fa71b9SJerome Forissier ssl->conf->renego_period + ep_len, 8 - ep_len ); 545611fa71b9SJerome Forissier 545711fa71b9SJerome Forissier if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) 545811fa71b9SJerome Forissier { 545911fa71b9SJerome Forissier return( 0 ); 546011fa71b9SJerome Forissier } 546111fa71b9SJerome Forissier 546211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); 546311fa71b9SJerome Forissier return( mbedtls_ssl_renegotiate( ssl ) ); 546411fa71b9SJerome Forissier } 546511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 546611fa71b9SJerome Forissier 546711fa71b9SJerome Forissier /* 546811fa71b9SJerome Forissier * Receive application data decrypted from the SSL layer 546911fa71b9SJerome Forissier */ 547011fa71b9SJerome Forissier int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) 547111fa71b9SJerome Forissier { 547211fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 547311fa71b9SJerome Forissier size_t n; 547411fa71b9SJerome Forissier 547511fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 547611fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 547711fa71b9SJerome Forissier 547811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); 547911fa71b9SJerome Forissier 548011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 548111fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 548211fa71b9SJerome Forissier { 548311fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 548411fa71b9SJerome Forissier return( ret ); 548511fa71b9SJerome Forissier 548611fa71b9SJerome Forissier if( ssl->handshake != NULL && 548711fa71b9SJerome Forissier ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) 548811fa71b9SJerome Forissier { 548911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 ) 549011fa71b9SJerome Forissier return( ret ); 549111fa71b9SJerome Forissier } 549211fa71b9SJerome Forissier } 549311fa71b9SJerome Forissier #endif 549411fa71b9SJerome Forissier 549511fa71b9SJerome Forissier /* 549611fa71b9SJerome Forissier * Check if renegotiation is necessary and/or handshake is 549711fa71b9SJerome Forissier * in process. If yes, perform/continue, and fall through 549811fa71b9SJerome Forissier * if an unexpected packet is received while the client 549911fa71b9SJerome Forissier * is waiting for the ServerHello. 550011fa71b9SJerome Forissier * 550111fa71b9SJerome Forissier * (There is no equivalent to the last condition on 550211fa71b9SJerome Forissier * the server-side as it is not treated as within 550311fa71b9SJerome Forissier * a handshake while waiting for the ClientHello 550411fa71b9SJerome Forissier * after a renegotiation request.) 550511fa71b9SJerome Forissier */ 550611fa71b9SJerome Forissier 550711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 550811fa71b9SJerome Forissier ret = ssl_check_ctr_renegotiate( ssl ); 550911fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 551011fa71b9SJerome Forissier ret != 0 ) 551111fa71b9SJerome Forissier { 551211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); 551311fa71b9SJerome Forissier return( ret ); 551411fa71b9SJerome Forissier } 551511fa71b9SJerome Forissier #endif 551611fa71b9SJerome Forissier 551711fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 551811fa71b9SJerome Forissier { 551911fa71b9SJerome Forissier ret = mbedtls_ssl_handshake( ssl ); 552011fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 552111fa71b9SJerome Forissier ret != 0 ) 552211fa71b9SJerome Forissier { 552311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); 552411fa71b9SJerome Forissier return( ret ); 552511fa71b9SJerome Forissier } 552611fa71b9SJerome Forissier } 552711fa71b9SJerome Forissier 552811fa71b9SJerome Forissier /* Loop as long as no application data record is available */ 552911fa71b9SJerome Forissier while( ssl->in_offt == NULL ) 553011fa71b9SJerome Forissier { 553111fa71b9SJerome Forissier /* Start timer if not already running */ 553211fa71b9SJerome Forissier if( ssl->f_get_timer != NULL && 553311fa71b9SJerome Forissier ssl->f_get_timer( ssl->p_timer ) == -1 ) 553411fa71b9SJerome Forissier { 553511fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout ); 553611fa71b9SJerome Forissier } 553711fa71b9SJerome Forissier 553811fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 553911fa71b9SJerome Forissier { 554011fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) 554111fa71b9SJerome Forissier return( 0 ); 554211fa71b9SJerome Forissier 554311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 554411fa71b9SJerome Forissier return( ret ); 554511fa71b9SJerome Forissier } 554611fa71b9SJerome Forissier 554711fa71b9SJerome Forissier if( ssl->in_msglen == 0 && 554811fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) 554911fa71b9SJerome Forissier { 555011fa71b9SJerome Forissier /* 555111fa71b9SJerome Forissier * OpenSSL sends empty messages to randomize the IV 555211fa71b9SJerome Forissier */ 555311fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) 555411fa71b9SJerome Forissier { 555511fa71b9SJerome Forissier if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) 555611fa71b9SJerome Forissier return( 0 ); 555711fa71b9SJerome Forissier 555811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); 555911fa71b9SJerome Forissier return( ret ); 556011fa71b9SJerome Forissier } 556111fa71b9SJerome Forissier } 556211fa71b9SJerome Forissier 556311fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 556411fa71b9SJerome Forissier { 556511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); 556611fa71b9SJerome Forissier 556711fa71b9SJerome Forissier /* 556811fa71b9SJerome Forissier * - For client-side, expect SERVER_HELLO_REQUEST. 556911fa71b9SJerome Forissier * - For server-side, expect CLIENT_HELLO. 557011fa71b9SJerome Forissier * - Fail (TLS) or silently drop record (DTLS) in other cases. 557111fa71b9SJerome Forissier */ 557211fa71b9SJerome Forissier 557311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C) 557411fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && 557511fa71b9SJerome Forissier ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || 557611fa71b9SJerome Forissier ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) 557711fa71b9SJerome Forissier { 557811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); 557911fa71b9SJerome Forissier 558011fa71b9SJerome Forissier /* With DTLS, drop the packet (probably from last handshake) */ 558111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 558211fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 558311fa71b9SJerome Forissier { 558411fa71b9SJerome Forissier continue; 558511fa71b9SJerome Forissier } 558611fa71b9SJerome Forissier #endif 558711fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 558811fa71b9SJerome Forissier } 558911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */ 559011fa71b9SJerome Forissier 559111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) 559211fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 559311fa71b9SJerome Forissier ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) 559411fa71b9SJerome Forissier { 559511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); 559611fa71b9SJerome Forissier 559711fa71b9SJerome Forissier /* With DTLS, drop the packet (probably from last handshake) */ 559811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 559911fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 560011fa71b9SJerome Forissier { 560111fa71b9SJerome Forissier continue; 560211fa71b9SJerome Forissier } 560311fa71b9SJerome Forissier #endif 560411fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 560511fa71b9SJerome Forissier } 560611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C */ 560711fa71b9SJerome Forissier 560811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 560911fa71b9SJerome Forissier /* Determine whether renegotiation attempt should be accepted */ 561011fa71b9SJerome Forissier if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || 561111fa71b9SJerome Forissier ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 561211fa71b9SJerome Forissier ssl->conf->allow_legacy_renegotiation == 561311fa71b9SJerome Forissier MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) 561411fa71b9SJerome Forissier { 561511fa71b9SJerome Forissier /* 561611fa71b9SJerome Forissier * Accept renegotiation request 561711fa71b9SJerome Forissier */ 561811fa71b9SJerome Forissier 561911fa71b9SJerome Forissier /* DTLS clients need to know renego is server-initiated */ 562011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 562111fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 562211fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) 562311fa71b9SJerome Forissier { 562411fa71b9SJerome Forissier ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; 562511fa71b9SJerome Forissier } 562611fa71b9SJerome Forissier #endif 562711fa71b9SJerome Forissier ret = mbedtls_ssl_start_renegotiation( ssl ); 562811fa71b9SJerome Forissier if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && 562911fa71b9SJerome Forissier ret != 0 ) 563011fa71b9SJerome Forissier { 563111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation", 563211fa71b9SJerome Forissier ret ); 563311fa71b9SJerome Forissier return( ret ); 563411fa71b9SJerome Forissier } 563511fa71b9SJerome Forissier } 563611fa71b9SJerome Forissier else 563711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 563811fa71b9SJerome Forissier { 563911fa71b9SJerome Forissier /* 564011fa71b9SJerome Forissier * Refuse renegotiation 564111fa71b9SJerome Forissier */ 564211fa71b9SJerome Forissier 564311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); 564411fa71b9SJerome Forissier 564511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_SSL3) 564611fa71b9SJerome Forissier if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) 564711fa71b9SJerome Forissier { 564811fa71b9SJerome Forissier /* SSLv3 does not have a "no_renegotiation" warning, so 564911fa71b9SJerome Forissier we send a fatal alert and abort the connection. */ 565011fa71b9SJerome Forissier mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 565111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); 565211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 565311fa71b9SJerome Forissier } 565411fa71b9SJerome Forissier else 565511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_SSL3 */ 565611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ 565711fa71b9SJerome Forissier defined(MBEDTLS_SSL_PROTO_TLS1_2) 565811fa71b9SJerome Forissier if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) 565911fa71b9SJerome Forissier { 566011fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_send_alert_message( ssl, 566111fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING, 566211fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) 566311fa71b9SJerome Forissier { 566411fa71b9SJerome Forissier return( ret ); 566511fa71b9SJerome Forissier } 566611fa71b9SJerome Forissier } 566711fa71b9SJerome Forissier else 566811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || 566911fa71b9SJerome Forissier MBEDTLS_SSL_PROTO_TLS1_2 */ 567011fa71b9SJerome Forissier { 567111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); 567211fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 567311fa71b9SJerome Forissier } 567411fa71b9SJerome Forissier } 567511fa71b9SJerome Forissier 567611fa71b9SJerome Forissier /* At this point, we don't know whether the renegotiation has been 567711fa71b9SJerome Forissier * completed or not. The cases to consider are the following: 567811fa71b9SJerome Forissier * 1) The renegotiation is complete. In this case, no new record 567911fa71b9SJerome Forissier * has been read yet. 568011fa71b9SJerome Forissier * 2) The renegotiation is incomplete because the client received 568111fa71b9SJerome Forissier * an application data record while awaiting the ServerHello. 568211fa71b9SJerome Forissier * 3) The renegotiation is incomplete because the client received 568311fa71b9SJerome Forissier * a non-handshake, non-application data message while awaiting 568411fa71b9SJerome Forissier * the ServerHello. 568511fa71b9SJerome Forissier * In each of these case, looping will be the proper action: 568611fa71b9SJerome Forissier * - For 1), the next iteration will read a new record and check 568711fa71b9SJerome Forissier * if it's application data. 568811fa71b9SJerome Forissier * - For 2), the loop condition isn't satisfied as application data 568911fa71b9SJerome Forissier * is present, hence continue is the same as break 569011fa71b9SJerome Forissier * - For 3), the loop condition is satisfied and read_record 569111fa71b9SJerome Forissier * will re-deliver the message that was held back by the client 569211fa71b9SJerome Forissier * when expecting the ServerHello. 569311fa71b9SJerome Forissier */ 569411fa71b9SJerome Forissier continue; 569511fa71b9SJerome Forissier } 569611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 569711fa71b9SJerome Forissier else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 569811fa71b9SJerome Forissier { 569911fa71b9SJerome Forissier if( ssl->conf->renego_max_records >= 0 ) 570011fa71b9SJerome Forissier { 570111fa71b9SJerome Forissier if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) 570211fa71b9SJerome Forissier { 570311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " 570411fa71b9SJerome Forissier "but not honored by client" ) ); 570511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 570611fa71b9SJerome Forissier } 570711fa71b9SJerome Forissier } 570811fa71b9SJerome Forissier } 570911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */ 571011fa71b9SJerome Forissier 571111fa71b9SJerome Forissier /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ 571211fa71b9SJerome Forissier if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) 571311fa71b9SJerome Forissier { 571411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); 571511fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_WANT_READ ); 571611fa71b9SJerome Forissier } 571711fa71b9SJerome Forissier 571811fa71b9SJerome Forissier if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) 571911fa71b9SJerome Forissier { 572011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); 572111fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); 572211fa71b9SJerome Forissier } 572311fa71b9SJerome Forissier 572411fa71b9SJerome Forissier ssl->in_offt = ssl->in_msg; 572511fa71b9SJerome Forissier 572611fa71b9SJerome Forissier /* We're going to return something now, cancel timer, 572711fa71b9SJerome Forissier * except if handshake (renegotiation) is in progress */ 572811fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 572911fa71b9SJerome Forissier mbedtls_ssl_set_timer( ssl, 0 ); 573011fa71b9SJerome Forissier 573111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 573211fa71b9SJerome Forissier /* If we requested renego but received AppData, resend HelloRequest. 573311fa71b9SJerome Forissier * Do it now, after setting in_offt, to avoid taking this branch 573411fa71b9SJerome Forissier * again if ssl_write_hello_request() returns WANT_WRITE */ 573511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) 573611fa71b9SJerome Forissier if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && 573711fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) 573811fa71b9SJerome Forissier { 573911fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 ) 574011fa71b9SJerome Forissier { 574111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request", 574211fa71b9SJerome Forissier ret ); 574311fa71b9SJerome Forissier return( ret ); 574411fa71b9SJerome Forissier } 574511fa71b9SJerome Forissier } 574611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ 574711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 574811fa71b9SJerome Forissier } 574911fa71b9SJerome Forissier 575011fa71b9SJerome Forissier n = ( len < ssl->in_msglen ) 575111fa71b9SJerome Forissier ? len : ssl->in_msglen; 575211fa71b9SJerome Forissier 575311fa71b9SJerome Forissier memcpy( buf, ssl->in_offt, n ); 575411fa71b9SJerome Forissier ssl->in_msglen -= n; 575511fa71b9SJerome Forissier 5756*7901324dSJerome Forissier /* Zeroising the plaintext buffer to erase unused application data 5757*7901324dSJerome Forissier from the memory. */ 5758*7901324dSJerome Forissier mbedtls_platform_zeroize( ssl->in_offt, n ); 5759*7901324dSJerome Forissier 576011fa71b9SJerome Forissier if( ssl->in_msglen == 0 ) 576111fa71b9SJerome Forissier { 576211fa71b9SJerome Forissier /* all bytes consumed */ 576311fa71b9SJerome Forissier ssl->in_offt = NULL; 576411fa71b9SJerome Forissier ssl->keep_current_message = 0; 576511fa71b9SJerome Forissier } 576611fa71b9SJerome Forissier else 576711fa71b9SJerome Forissier { 576811fa71b9SJerome Forissier /* more data available */ 576911fa71b9SJerome Forissier ssl->in_offt += n; 577011fa71b9SJerome Forissier } 577111fa71b9SJerome Forissier 577211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); 577311fa71b9SJerome Forissier 577411fa71b9SJerome Forissier return( (int) n ); 577511fa71b9SJerome Forissier } 577611fa71b9SJerome Forissier 577711fa71b9SJerome Forissier /* 577811fa71b9SJerome Forissier * Send application data to be encrypted by the SSL layer, taking care of max 577911fa71b9SJerome Forissier * fragment length and buffer size. 578011fa71b9SJerome Forissier * 578111fa71b9SJerome Forissier * According to RFC 5246 Section 6.2.1: 578211fa71b9SJerome Forissier * 578311fa71b9SJerome Forissier * Zero-length fragments of Application data MAY be sent as they are 578411fa71b9SJerome Forissier * potentially useful as a traffic analysis countermeasure. 578511fa71b9SJerome Forissier * 578611fa71b9SJerome Forissier * Therefore, it is possible that the input message length is 0 and the 578711fa71b9SJerome Forissier * corresponding return code is 0 on success. 578811fa71b9SJerome Forissier */ 578911fa71b9SJerome Forissier static int ssl_write_real( mbedtls_ssl_context *ssl, 579011fa71b9SJerome Forissier const unsigned char *buf, size_t len ) 579111fa71b9SJerome Forissier { 579211fa71b9SJerome Forissier int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); 579311fa71b9SJerome Forissier const size_t max_len = (size_t) ret; 579411fa71b9SJerome Forissier 579511fa71b9SJerome Forissier if( ret < 0 ) 579611fa71b9SJerome Forissier { 579711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret ); 579811fa71b9SJerome Forissier return( ret ); 579911fa71b9SJerome Forissier } 580011fa71b9SJerome Forissier 580111fa71b9SJerome Forissier if( len > max_len ) 580211fa71b9SJerome Forissier { 580311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 580411fa71b9SJerome Forissier if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 580511fa71b9SJerome Forissier { 580611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " 5807*7901324dSJerome Forissier "maximum fragment length: %" MBEDTLS_PRINTF_SIZET 5808*7901324dSJerome Forissier " > %" MBEDTLS_PRINTF_SIZET, 580911fa71b9SJerome Forissier len, max_len ) ); 581011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 581111fa71b9SJerome Forissier } 581211fa71b9SJerome Forissier else 581311fa71b9SJerome Forissier #endif 581411fa71b9SJerome Forissier len = max_len; 581511fa71b9SJerome Forissier } 581611fa71b9SJerome Forissier 581711fa71b9SJerome Forissier if( ssl->out_left != 0 ) 581811fa71b9SJerome Forissier { 581911fa71b9SJerome Forissier /* 582011fa71b9SJerome Forissier * The user has previously tried to send the data and 582111fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially 582211fa71b9SJerome Forissier * written. In this case, we expect the high-level write function 582311fa71b9SJerome Forissier * (e.g. mbedtls_ssl_write()) to be called with the same parameters 582411fa71b9SJerome Forissier */ 582511fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) 582611fa71b9SJerome Forissier { 582711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); 582811fa71b9SJerome Forissier return( ret ); 582911fa71b9SJerome Forissier } 583011fa71b9SJerome Forissier } 583111fa71b9SJerome Forissier else 583211fa71b9SJerome Forissier { 583311fa71b9SJerome Forissier /* 583411fa71b9SJerome Forissier * The user is trying to send a message the first time, so we need to 583511fa71b9SJerome Forissier * copy the data into the internal buffers and setup the data structure 583611fa71b9SJerome Forissier * to keep track of partial writes 583711fa71b9SJerome Forissier */ 583811fa71b9SJerome Forissier ssl->out_msglen = len; 583911fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; 584011fa71b9SJerome Forissier memcpy( ssl->out_msg, buf, len ); 584111fa71b9SJerome Forissier 584211fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 ) 584311fa71b9SJerome Forissier { 584411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); 584511fa71b9SJerome Forissier return( ret ); 584611fa71b9SJerome Forissier } 584711fa71b9SJerome Forissier } 584811fa71b9SJerome Forissier 584911fa71b9SJerome Forissier return( (int) len ); 585011fa71b9SJerome Forissier } 585111fa71b9SJerome Forissier 585211fa71b9SJerome Forissier /* 585311fa71b9SJerome Forissier * Write application data, doing 1/n-1 splitting if necessary. 585411fa71b9SJerome Forissier * 585511fa71b9SJerome Forissier * With non-blocking I/O, ssl_write_real() may return WANT_WRITE, 585611fa71b9SJerome Forissier * then the caller will call us again with the same arguments, so 585711fa71b9SJerome Forissier * remember whether we already did the split or not. 585811fa71b9SJerome Forissier */ 585911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) 586011fa71b9SJerome Forissier static int ssl_write_split( mbedtls_ssl_context *ssl, 586111fa71b9SJerome Forissier const unsigned char *buf, size_t len ) 586211fa71b9SJerome Forissier { 586311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 586411fa71b9SJerome Forissier 586511fa71b9SJerome Forissier if( ssl->conf->cbc_record_splitting == 586611fa71b9SJerome Forissier MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || 586711fa71b9SJerome Forissier len <= 1 || 586811fa71b9SJerome Forissier ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || 586911fa71b9SJerome Forissier mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) 587011fa71b9SJerome Forissier != MBEDTLS_MODE_CBC ) 587111fa71b9SJerome Forissier { 587211fa71b9SJerome Forissier return( ssl_write_real( ssl, buf, len ) ); 587311fa71b9SJerome Forissier } 587411fa71b9SJerome Forissier 587511fa71b9SJerome Forissier if( ssl->split_done == 0 ) 587611fa71b9SJerome Forissier { 587711fa71b9SJerome Forissier if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) 587811fa71b9SJerome Forissier return( ret ); 587911fa71b9SJerome Forissier ssl->split_done = 1; 588011fa71b9SJerome Forissier } 588111fa71b9SJerome Forissier 588211fa71b9SJerome Forissier if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) 588311fa71b9SJerome Forissier return( ret ); 588411fa71b9SJerome Forissier ssl->split_done = 0; 588511fa71b9SJerome Forissier 588611fa71b9SJerome Forissier return( ret + 1 ); 588711fa71b9SJerome Forissier } 588811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ 588911fa71b9SJerome Forissier 589011fa71b9SJerome Forissier /* 589111fa71b9SJerome Forissier * Write application data (public-facing wrapper) 589211fa71b9SJerome Forissier */ 589311fa71b9SJerome Forissier int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) 589411fa71b9SJerome Forissier { 589511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 589611fa71b9SJerome Forissier 589711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); 589811fa71b9SJerome Forissier 589911fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 590011fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 590111fa71b9SJerome Forissier 590211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION) 590311fa71b9SJerome Forissier if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) 590411fa71b9SJerome Forissier { 590511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); 590611fa71b9SJerome Forissier return( ret ); 590711fa71b9SJerome Forissier } 590811fa71b9SJerome Forissier #endif 590911fa71b9SJerome Forissier 591011fa71b9SJerome Forissier if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) 591111fa71b9SJerome Forissier { 591211fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) 591311fa71b9SJerome Forissier { 591411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); 591511fa71b9SJerome Forissier return( ret ); 591611fa71b9SJerome Forissier } 591711fa71b9SJerome Forissier } 591811fa71b9SJerome Forissier 591911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) 592011fa71b9SJerome Forissier ret = ssl_write_split( ssl, buf, len ); 592111fa71b9SJerome Forissier #else 592211fa71b9SJerome Forissier ret = ssl_write_real( ssl, buf, len ); 592311fa71b9SJerome Forissier #endif 592411fa71b9SJerome Forissier 592511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); 592611fa71b9SJerome Forissier 592711fa71b9SJerome Forissier return( ret ); 592811fa71b9SJerome Forissier } 592911fa71b9SJerome Forissier 593011fa71b9SJerome Forissier /* 593111fa71b9SJerome Forissier * Notify the peer that the connection is being closed 593211fa71b9SJerome Forissier */ 593311fa71b9SJerome Forissier int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) 593411fa71b9SJerome Forissier { 593511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 593611fa71b9SJerome Forissier 593711fa71b9SJerome Forissier if( ssl == NULL || ssl->conf == NULL ) 593811fa71b9SJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 593911fa71b9SJerome Forissier 594011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); 594111fa71b9SJerome Forissier 594211fa71b9SJerome Forissier if( ssl->out_left != 0 ) 594311fa71b9SJerome Forissier return( mbedtls_ssl_flush_output( ssl ) ); 594411fa71b9SJerome Forissier 594511fa71b9SJerome Forissier if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) 594611fa71b9SJerome Forissier { 594711fa71b9SJerome Forissier if( ( ret = mbedtls_ssl_send_alert_message( ssl, 594811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING, 594911fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) 595011fa71b9SJerome Forissier { 595111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); 595211fa71b9SJerome Forissier return( ret ); 595311fa71b9SJerome Forissier } 595411fa71b9SJerome Forissier } 595511fa71b9SJerome Forissier 595611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); 595711fa71b9SJerome Forissier 595811fa71b9SJerome Forissier return( 0 ); 595911fa71b9SJerome Forissier } 596011fa71b9SJerome Forissier 596111fa71b9SJerome Forissier void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) 596211fa71b9SJerome Forissier { 596311fa71b9SJerome Forissier if( transform == NULL ) 596411fa71b9SJerome Forissier return; 596511fa71b9SJerome Forissier 596611fa71b9SJerome Forissier #if defined(MBEDTLS_ZLIB_SUPPORT) 596711fa71b9SJerome Forissier deflateEnd( &transform->ctx_deflate ); 596811fa71b9SJerome Forissier inflateEnd( &transform->ctx_inflate ); 596911fa71b9SJerome Forissier #endif 597011fa71b9SJerome Forissier 597111fa71b9SJerome Forissier mbedtls_cipher_free( &transform->cipher_ctx_enc ); 597211fa71b9SJerome Forissier mbedtls_cipher_free( &transform->cipher_ctx_dec ); 597311fa71b9SJerome Forissier 597411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 597511fa71b9SJerome Forissier mbedtls_md_free( &transform->md_ctx_enc ); 597611fa71b9SJerome Forissier mbedtls_md_free( &transform->md_ctx_dec ); 597711fa71b9SJerome Forissier #endif 597811fa71b9SJerome Forissier 597911fa71b9SJerome Forissier mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); 598011fa71b9SJerome Forissier } 598111fa71b9SJerome Forissier 598211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 598311fa71b9SJerome Forissier 598411fa71b9SJerome Forissier void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl ) 598511fa71b9SJerome Forissier { 598611fa71b9SJerome Forissier unsigned offset; 598711fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 598811fa71b9SJerome Forissier 598911fa71b9SJerome Forissier if( hs == NULL ) 599011fa71b9SJerome Forissier return; 599111fa71b9SJerome Forissier 599211fa71b9SJerome Forissier ssl_free_buffered_record( ssl ); 599311fa71b9SJerome Forissier 599411fa71b9SJerome Forissier for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ ) 599511fa71b9SJerome Forissier ssl_buffering_free_slot( ssl, offset ); 599611fa71b9SJerome Forissier } 599711fa71b9SJerome Forissier 599811fa71b9SJerome Forissier static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, 599911fa71b9SJerome Forissier uint8_t slot ) 600011fa71b9SJerome Forissier { 600111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake; 600211fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot]; 600311fa71b9SJerome Forissier 600411fa71b9SJerome Forissier if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS ) 600511fa71b9SJerome Forissier return; 600611fa71b9SJerome Forissier 600711fa71b9SJerome Forissier if( hs_buf->is_valid == 1 ) 600811fa71b9SJerome Forissier { 600911fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= hs_buf->data_len; 601011fa71b9SJerome Forissier mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len ); 601111fa71b9SJerome Forissier mbedtls_free( hs_buf->data ); 601211fa71b9SJerome Forissier memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) ); 601311fa71b9SJerome Forissier } 601411fa71b9SJerome Forissier } 601511fa71b9SJerome Forissier 601611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */ 601711fa71b9SJerome Forissier 601811fa71b9SJerome Forissier /* 601911fa71b9SJerome Forissier * Convert version numbers to/from wire format 602011fa71b9SJerome Forissier * and, for DTLS, to/from TLS equivalent. 602111fa71b9SJerome Forissier * 602211fa71b9SJerome Forissier * For TLS this is the identity. 602311fa71b9SJerome Forissier * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: 602411fa71b9SJerome Forissier * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) 602511fa71b9SJerome Forissier * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) 602611fa71b9SJerome Forissier */ 602711fa71b9SJerome Forissier void mbedtls_ssl_write_version( int major, int minor, int transport, 602811fa71b9SJerome Forissier unsigned char ver[2] ) 602911fa71b9SJerome Forissier { 603011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 603111fa71b9SJerome Forissier if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 603211fa71b9SJerome Forissier { 603311fa71b9SJerome Forissier if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) 603411fa71b9SJerome Forissier --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ 603511fa71b9SJerome Forissier 603611fa71b9SJerome Forissier ver[0] = (unsigned char)( 255 - ( major - 2 ) ); 603711fa71b9SJerome Forissier ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); 603811fa71b9SJerome Forissier } 603911fa71b9SJerome Forissier else 604011fa71b9SJerome Forissier #else 604111fa71b9SJerome Forissier ((void) transport); 604211fa71b9SJerome Forissier #endif 604311fa71b9SJerome Forissier { 604411fa71b9SJerome Forissier ver[0] = (unsigned char) major; 604511fa71b9SJerome Forissier ver[1] = (unsigned char) minor; 604611fa71b9SJerome Forissier } 604711fa71b9SJerome Forissier } 604811fa71b9SJerome Forissier 604911fa71b9SJerome Forissier void mbedtls_ssl_read_version( int *major, int *minor, int transport, 605011fa71b9SJerome Forissier const unsigned char ver[2] ) 605111fa71b9SJerome Forissier { 605211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS) 605311fa71b9SJerome Forissier if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) 605411fa71b9SJerome Forissier { 605511fa71b9SJerome Forissier *major = 255 - ver[0] + 2; 605611fa71b9SJerome Forissier *minor = 255 - ver[1] + 1; 605711fa71b9SJerome Forissier 605811fa71b9SJerome Forissier if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) 605911fa71b9SJerome Forissier ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ 606011fa71b9SJerome Forissier } 606111fa71b9SJerome Forissier else 606211fa71b9SJerome Forissier #else 606311fa71b9SJerome Forissier ((void) transport); 606411fa71b9SJerome Forissier #endif 606511fa71b9SJerome Forissier { 606611fa71b9SJerome Forissier *major = ver[0]; 606711fa71b9SJerome Forissier *minor = ver[1]; 606811fa71b9SJerome Forissier } 606911fa71b9SJerome Forissier } 607011fa71b9SJerome Forissier 607111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */ 6072