blob: e47c538888e32a3b87808b7e65b694c91f8b925a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
Hanno Beckerf1a38282020-02-05 16:14:29 +00002 * Generic SSL/TLS messaging layer functions
3 * (record layer + retransmission state machine)
Paul Bakker5121ce52009-01-03 21:22:43 +00004 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02006 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000019 */
20/*
21 * The SSL 3.0 specification was drafted by Netscape in 1996,
22 * and became an IETF standard in 1999.
23 *
24 * http://wp.netscape.com/eng/ssl3/
25 * http://www.ietf.org/rfc/rfc2246.txt
26 * http://www.ietf.org/rfc/rfc4346.txt
27 */
28
Gilles Peskinedb09ef62020-06-03 01:43:33 +020029#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#if defined(MBEDTLS_SSL_TLS_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000032
SimonBd5800b72016-04-26 07:43:27 +010033#if defined(MBEDTLS_PLATFORM_C)
34#include "mbedtls/platform.h"
35#else
36#include <stdlib.h>
37#define mbedtls_calloc calloc
38#define mbedtls_free free
SimonBd5800b72016-04-26 07:43:27 +010039#endif
40
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/ssl.h"
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +020042#include "mbedtls/ssl_internal.h"
Janos Follath73c616b2019-12-18 15:07:04 +000043#include "mbedtls/debug.h"
44#include "mbedtls/error.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050045#include "mbedtls/platform_util.h"
Hanno Beckera835da52019-05-16 12:39:07 +010046#include "mbedtls/version.h"
Gabor Mezeic0ae1cf2021-10-20 12:09:35 +020047#include "constant_time_internal.h"
Gabor Mezeie24dea82021-10-19 12:22:25 +020048#include "mbedtls/constant_time.h"
Paul Bakker0be444a2013-08-27 21:55:01 +020049
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <string.h>
51
Andrzej Kurekd6db9be2019-01-10 05:27:10 -050052#if defined(MBEDTLS_USE_PSA_CRYPTO)
53#include "mbedtls/psa_util.h"
54#include "psa/crypto.h"
55#endif
56
Janos Follath23bdca02016-10-07 14:47:14 +010057#if defined(MBEDTLS_X509_CRT_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000058#include "mbedtls/oid.h"
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +020059#endif
60
Hanno Beckercd9dcda2018-08-28 17:18:56 +010061static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
Hanno Becker2a43f6f2018-08-10 11:12:52 +010062
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020063/*
64 * Start a timer.
65 * Passing millisecs = 0 cancels a running timer.
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020066 */
Hanno Becker0f57a652020-02-05 10:37:26 +000067void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020068{
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +020069 if( ssl->f_set_timer == NULL )
70 return;
71
72 MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
73 ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020074}
75
76/*
77 * Return -1 is timer is expired, 0 if it isn't.
78 */
Hanno Becker7876d122020-02-05 10:39:31 +000079int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020080{
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +020081 if( ssl->f_get_timer == NULL )
Manuel Pégourié-Gonnard545102e2015-05-13 17:28:43 +020082 return( 0 );
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +020083
84 if( ssl->f_get_timer( ssl->p_timer ) == 2 )
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +020085 {
86 MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020087 return( -1 );
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +020088 }
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020089
90 return( 0 );
91}
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020092
Hanno Beckercfe45792019-07-03 16:13:00 +010093#if defined(MBEDTLS_SSL_RECORD_CHECKING)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +020094MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker54229812019-07-12 14:40:00 +010095static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
96 unsigned char *buf,
97 size_t len,
98 mbedtls_record *rec );
99
Hanno Beckercfe45792019-07-03 16:13:00 +0100100int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
101 unsigned char *buf,
102 size_t buflen )
103{
Hanno Becker54229812019-07-12 14:40:00 +0100104 int ret = 0;
Hanno Becker54229812019-07-12 14:40:00 +0100105 MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
106 MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
107
108 /* We don't support record checking in TLS because
109 * (a) there doesn't seem to be a usecase for it, and
110 * (b) In SSLv3 and TLS 1.0, CBC record decryption has state
111 * and we'd need to backup the transform here.
112 */
113 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
114 {
115 ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
116 goto exit;
117 }
118#if defined(MBEDTLS_SSL_PROTO_DTLS)
119 else
120 {
irwir734f0cf2019-09-26 21:03:24 +0300121 mbedtls_record rec;
122
Hanno Becker54229812019-07-12 14:40:00 +0100123 ret = ssl_parse_record_header( ssl, buf, buflen, &rec );
124 if( ret != 0 )
125 {
126 MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret );
127 goto exit;
128 }
129
130 if( ssl->transform_in != NULL )
131 {
132 ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec );
133 if( ret != 0 )
134 {
135 MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret );
136 goto exit;
137 }
138 }
139 }
140#endif /* MBEDTLS_SSL_PROTO_DTLS */
141
142exit:
143 /* On success, we have decrypted the buffer in-place, so make
144 * sure we don't leak any plaintext data. */
145 mbedtls_platform_zeroize( buf, buflen );
146
147 /* For the purpose of this API, treat messages with unexpected CID
148 * as well as such from future epochs as unexpected. */
149 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
150 ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
151 {
152 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
153 }
154
155 MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
156 return( ret );
Hanno Beckercfe45792019-07-03 16:13:00 +0100157}
158#endif /* MBEDTLS_SSL_RECORD_CHECKING */
159
Hanno Becker67bc7c32018-08-06 11:33:50 +0100160#define SSL_DONT_FORCE_FLUSH 0
161#define SSL_FORCE_FLUSH 1
162
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +0200163#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2b1e3542018-08-06 11:19:13 +0100164
Hanno Beckerd5847772018-08-28 10:09:23 +0100165/* Forward declarations for functions related to message buffering. */
Hanno Beckerd5847772018-08-28 10:09:23 +0100166static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
167 uint8_t slot );
168static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200169MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckerd5847772018-08-28 10:09:23 +0100170static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200171MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckerd5847772018-08-28 10:09:23 +0100172static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200173MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckerd5847772018-08-28 10:09:23 +0100174static int ssl_buffer_message( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200175MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker519f15d2019-07-11 12:43:20 +0100176static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
177 mbedtls_record const *rec );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200178MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckeref7afdf2018-08-28 17:16:31 +0100179static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
Hanno Beckerd5847772018-08-28 10:09:23 +0100180
Hanno Becker11682cc2018-08-22 14:41:02 +0100181static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
Hanno Becker2b1e3542018-08-06 11:19:13 +0100182{
Hanno Becker89490712020-02-05 10:50:12 +0000183 size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
Darryl Greenb33cc762019-11-28 14:29:44 +0000184#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
185 size_t out_buf_len = ssl->out_buf_len;
186#else
187 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
188#endif
Hanno Becker2b1e3542018-08-06 11:19:13 +0100189
Darryl Greenb33cc762019-11-28 14:29:44 +0000190 if( mtu != 0 && mtu < out_buf_len )
Hanno Becker11682cc2018-08-22 14:41:02 +0100191 return( mtu );
Hanno Becker2b1e3542018-08-06 11:19:13 +0100192
Darryl Greenb33cc762019-11-28 14:29:44 +0000193 return( out_buf_len );
Hanno Becker2b1e3542018-08-06 11:19:13 +0100194}
195
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200196MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker67bc7c32018-08-06 11:33:50 +0100197static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
198{
Hanno Becker11682cc2018-08-22 14:41:02 +0100199 size_t const bytes_written = ssl->out_left;
200 size_t const mtu = ssl_get_maximum_datagram_size( ssl );
Hanno Becker67bc7c32018-08-06 11:33:50 +0100201
202 /* Double-check that the write-index hasn't gone
203 * past what we can transmit in a single datagram. */
Hanno Becker11682cc2018-08-22 14:41:02 +0100204 if( bytes_written > mtu )
Hanno Becker67bc7c32018-08-06 11:33:50 +0100205 {
206 /* Should never happen... */
207 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
208 }
209
210 return( (int) ( mtu - bytes_written ) );
211}
212
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200213MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker67bc7c32018-08-06 11:33:50 +0100214static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
215{
Janos Follath865b3eb2019-12-16 11:46:15 +0000216 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100217 size_t remaining, expansion;
Andrzej Kurek748face2018-10-11 07:20:19 -0400218 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100219
220#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Andrzej Kurek90c6e842020-04-03 05:25:29 -0400221 const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
Hanno Becker67bc7c32018-08-06 11:33:50 +0100222
223 if( max_len > mfl )
224 max_len = mfl;
Hanno Beckerf4b010e2018-08-24 10:47:29 +0100225
226 /* By the standard (RFC 6066 Sect. 4), the MFL extension
227 * only limits the maximum record payload size, so in theory
228 * we would be allowed to pack multiple records of payload size
229 * MFL into a single datagram. However, this would mean that there's
230 * no way to explicitly communicate MTU restrictions to the peer.
231 *
232 * The following reduction of max_len makes sure that we never
233 * write datagrams larger than MFL + Record Expansion Overhead.
234 */
235 if( max_len <= ssl->out_left )
236 return( 0 );
237
238 max_len -= ssl->out_left;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100239#endif
240
241 ret = ssl_get_remaining_space_in_datagram( ssl );
242 if( ret < 0 )
243 return( ret );
244 remaining = (size_t) ret;
245
246 ret = mbedtls_ssl_get_record_expansion( ssl );
247 if( ret < 0 )
248 return( ret );
249 expansion = (size_t) ret;
250
251 if( remaining <= expansion )
252 return( 0 );
253
254 remaining -= expansion;
255 if( remaining >= max_len )
256 remaining = max_len;
257
258 return( (int) remaining );
259}
260
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200261/*
262 * Double the retransmit timeout value, within the allowed range,
263 * returning -1 if the maximum value has already been reached.
264 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200265MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200267{
268 uint32_t new_timeout;
269
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200270 if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200271 return( -1 );
272
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200273 /* Implement the final paragraph of RFC 6347 section 4.1.1.1
274 * in the following way: after the initial transmission and a first
275 * retransmission, back off to a temporary estimated MTU of 508 bytes.
276 * This value is guaranteed to be deliverable (if not guaranteed to be
277 * delivered) of any compliant IPv4 (and IPv6) network, and should work
278 * on most non-IP stacks too. */
279 if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
Andrzej Kurek6290dae2018-10-05 08:06:01 -0400280 {
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200281 ssl->handshake->mtu = 508;
Andrzej Kurek6290dae2018-10-05 08:06:01 -0400282 MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
283 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200284
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200285 new_timeout = 2 * ssl->handshake->retransmit_timeout;
286
287 /* Avoid arithmetic overflow and range overflow */
288 if( new_timeout < ssl->handshake->retransmit_timeout ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200289 new_timeout > ssl->conf->hs_timeout_max )
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200290 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200291 new_timeout = ssl->conf->hs_timeout_max;
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200292 }
293
294 ssl->handshake->retransmit_timeout = new_timeout;
Paul Elliott9f352112020-12-09 14:55:45 +0000295 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
296 (unsigned long) ssl->handshake->retransmit_timeout ) );
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200297
298 return( 0 );
299}
300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200302{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200303 ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
Paul Elliott9f352112020-12-09 14:55:45 +0000304 MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
305 (unsigned long) ssl->handshake->retransmit_timeout ) );
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200306}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200308
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
310int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
Paul Bakker9af723c2014-05-01 13:03:14 +0200311 const unsigned char *key_enc, const unsigned char *key_dec,
312 size_t keylen,
313 const unsigned char *iv_enc, const unsigned char *iv_dec,
314 size_t ivlen,
315 const unsigned char *mac_enc, const unsigned char *mac_dec,
Paul Bakker66d5d072014-06-17 16:39:18 +0200316 size_t maclen ) = NULL;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
318int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
319int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
320int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
321int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
322#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
Paul Bakker05ef8352012-05-08 09:17:57 +0000323
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +0100324/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 * Encryption/decryption functions
Paul Bakkerf7abd422013-04-16 13:15:56 +0200326 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000327
Hanno Beckerccc13d02020-05-04 12:30:04 +0100328#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \
329 defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
Hanno Becker13996922020-05-28 16:15:19 +0100330
331static size_t ssl_compute_padding_length( size_t len,
332 size_t granularity )
333{
334 return( ( granularity - ( len + 1 ) % granularity ) % granularity );
335}
336
Hanno Becker581bc1b2020-05-04 12:20:03 +0100337/* This functions transforms a (D)TLS plaintext fragment and a record content
338 * type into an instance of the (D)TLSInnerPlaintext structure. This is used
339 * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
340 * a record's content type.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100341 *
342 * struct {
343 * opaque content[DTLSPlaintext.length];
344 * ContentType real_type;
345 * uint8 zeros[length_of_padding];
Hanno Becker581bc1b2020-05-04 12:20:03 +0100346 * } (D)TLSInnerPlaintext;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100347 *
348 * Input:
349 * - `content`: The beginning of the buffer holding the
350 * plaintext to be wrapped.
351 * - `*content_size`: The length of the plaintext in Bytes.
352 * - `max_len`: The number of Bytes available starting from
353 * `content`. This must be `>= *content_size`.
354 * - `rec_type`: The desired record content type.
355 *
356 * Output:
Hanno Becker581bc1b2020-05-04 12:20:03 +0100357 * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
358 * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100359 *
360 * Returns:
361 * - `0` on success.
362 * - A negative error code if `max_len` didn't offer enough space
363 * for the expansion.
364 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200365MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker581bc1b2020-05-04 12:20:03 +0100366static int ssl_build_inner_plaintext( unsigned char *content,
367 size_t *content_size,
368 size_t remaining,
Hanno Becker13996922020-05-28 16:15:19 +0100369 uint8_t rec_type,
370 size_t pad )
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100371{
372 size_t len = *content_size;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100373
374 /* Write real content type */
375 if( remaining == 0 )
376 return( -1 );
377 content[ len ] = rec_type;
378 len++;
379 remaining--;
380
381 if( remaining < pad )
382 return( -1 );
383 memset( content + len, 0, pad );
384 len += pad;
385 remaining -= pad;
386
387 *content_size = len;
388 return( 0 );
389}
390
Hanno Becker581bc1b2020-05-04 12:20:03 +0100391/* This function parses a (D)TLSInnerPlaintext structure.
392 * See ssl_build_inner_plaintext() for details. */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200393MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker581bc1b2020-05-04 12:20:03 +0100394static int ssl_parse_inner_plaintext( unsigned char const *content,
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100395 size_t *content_size,
396 uint8_t *rec_type )
397{
398 size_t remaining = *content_size;
399
400 /* Determine length of padding by skipping zeroes from the back. */
401 do
402 {
403 if( remaining == 0 )
404 return( -1 );
405 remaining--;
406 } while( content[ remaining ] == 0 );
407
408 *content_size = remaining;
409 *rec_type = content[ remaining ];
410
411 return( 0 );
412}
Hanno Beckerccc13d02020-05-04 12:30:04 +0100413#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID ||
414 MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100415
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100416/* `add_data` must have size 13 Bytes if the CID extension is disabled,
Hanno Beckerc4a190b2019-05-08 18:15:21 +0100417 * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000418static void ssl_extract_add_data_from_record( unsigned char* add_data,
Hanno Beckercab87e62019-04-29 13:52:53 +0100419 size_t *add_data_len,
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100420 mbedtls_record *rec,
421 unsigned minor_ver )
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000422{
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100423 /* Quoting RFC 5246 (TLS 1.2):
Hanno Beckercab87e62019-04-29 13:52:53 +0100424 *
425 * additional_data = seq_num + TLSCompressed.type +
426 * TLSCompressed.version + TLSCompressed.length;
427 *
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100428 * For the CID extension, this is extended as follows
429 * (quoting draft-ietf-tls-dtls-connection-id-05,
430 * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
Hanno Beckercab87e62019-04-29 13:52:53 +0100431 *
432 * additional_data = seq_num + DTLSPlaintext.type +
433 * DTLSPlaintext.version +
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100434 * cid +
435 * cid_length +
Hanno Beckercab87e62019-04-29 13:52:53 +0100436 * length_of_DTLSInnerPlaintext;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100437 *
438 * For TLS 1.3, the record sequence number is dropped from the AAD
439 * and encoded within the nonce of the AEAD operation instead.
Hanno Beckercab87e62019-04-29 13:52:53 +0100440 */
441
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100442 unsigned char *cur = add_data;
443
444#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
445 if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
446#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
447 {
448 ((void) minor_ver);
449 memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
450 cur += sizeof( rec->ctr );
451 }
452
453 *cur = rec->type;
454 cur++;
455
456 memcpy( cur, rec->ver, sizeof( rec->ver ) );
457 cur += sizeof( rec->ver );
Hanno Beckercab87e62019-04-29 13:52:53 +0100458
Hanno Beckera0e20d02019-05-15 14:03:01 +0100459#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100460 if( rec->cid_len != 0 )
461 {
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100462 memcpy( cur, rec->cid, rec->cid_len );
463 cur += rec->cid_len;
464
465 *cur = rec->cid_len;
466 cur++;
467
Joe Subbianic54e9082021-07-19 11:56:54 +0100468 MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100469 cur += 2;
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100470 }
471 else
Hanno Beckera0e20d02019-05-15 14:03:01 +0100472#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100473 {
Joe Subbianic54e9082021-07-19 11:56:54 +0100474 MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100475 cur += 2;
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100476 }
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100477
478 *add_data_len = cur - add_data;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000479}
480
Hanno Becker9d062f92020-02-07 10:26:36 +0000481#if defined(MBEDTLS_SSL_PROTO_SSL3)
482
483#define SSL3_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
484
485/*
486 * SSLv3.0 MAC functions
487 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200488MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100489static int ssl_mac( mbedtls_md_context_t *md_ctx,
490 const unsigned char *secret,
491 const unsigned char *buf, size_t len,
492 const unsigned char *ctr, int type,
493 unsigned char out[SSL3_MAC_MAX_BYTES] )
Hanno Becker9d062f92020-02-07 10:26:36 +0000494{
495 unsigned char header[11];
496 unsigned char padding[48];
497 int padlen;
498 int md_size = mbedtls_md_get_size( md_ctx->md_info );
499 int md_type = mbedtls_md_get_type( md_ctx->md_info );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100500 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker9d062f92020-02-07 10:26:36 +0000501
502 /* Only MD5 and SHA-1 supported */
503 if( md_type == MBEDTLS_MD_MD5 )
504 padlen = 48;
505 else
506 padlen = 40;
507
508 memcpy( header, ctr, 8 );
Joe Subbiania651e6f2021-08-23 11:35:25 +0100509 header[8] = (unsigned char) type;
Joe Subbiani11b71312021-08-23 12:49:14 +0100510 MBEDTLS_PUT_UINT16_BE( len, header, 9);
Hanno Becker9d062f92020-02-07 10:26:36 +0000511
512 memset( padding, 0x36, padlen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100513 ret = mbedtls_md_starts( md_ctx );
514 if( ret != 0 )
515 return( ret );
516 ret = mbedtls_md_update( md_ctx, secret, md_size );
517 if( ret != 0 )
518 return( ret );
519 ret = mbedtls_md_update( md_ctx, padding, padlen );
520 if( ret != 0 )
521 return( ret );
522 ret = mbedtls_md_update( md_ctx, header, 11 );
523 if( ret != 0 )
524 return( ret );
525 ret = mbedtls_md_update( md_ctx, buf, len );
526 if( ret != 0 )
527 return( ret );
528 ret = mbedtls_md_finish( md_ctx, out );
529 if( ret != 0 )
530 return( ret );
Hanno Becker9d062f92020-02-07 10:26:36 +0000531
532 memset( padding, 0x5C, padlen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100533 ret = mbedtls_md_starts( md_ctx );
534 if( ret != 0 )
535 return( ret );
536 ret = mbedtls_md_update( md_ctx, secret, md_size );
537 if( ret != 0 )
538 return( ret );
539 ret = mbedtls_md_update( md_ctx, padding, padlen );
540 if( ret != 0 )
541 return( ret );
542 ret = mbedtls_md_update( md_ctx, out, md_size );
543 if( ret != 0 )
544 return( ret );
545 ret = mbedtls_md_finish( md_ctx, out );
546 if( ret != 0 )
547 return( ret );
548
549 return( 0 );
Hanno Becker9d062f92020-02-07 10:26:36 +0000550}
551#endif /* MBEDTLS_SSL_PROTO_SSL3 */
552
Hanno Becker67a37db2020-05-28 16:27:07 +0100553#if defined(MBEDTLS_GCM_C) || \
554 defined(MBEDTLS_CCM_C) || \
555 defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +0200556MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker17263802020-05-28 07:05:48 +0100557static int ssl_transform_aead_dynamic_iv_is_explicit(
558 mbedtls_ssl_transform const *transform )
Hanno Beckerdf8be222020-05-21 15:30:57 +0100559{
Hanno Becker17263802020-05-28 07:05:48 +0100560 return( transform->ivlen != transform->fixed_ivlen );
Hanno Beckerdf8be222020-05-21 15:30:57 +0100561}
562
Hanno Becker17263802020-05-28 07:05:48 +0100563/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
564 *
565 * Concretely, this occurs in two variants:
566 *
567 * a) Fixed and dynamic IV lengths add up to total IV length, giving
568 * IV = fixed_iv || dynamic_iv
569 *
Hanno Becker15952812020-06-04 13:31:46 +0100570 * This variant is used in TLS 1.2 when used with GCM or CCM.
571 *
Hanno Becker17263802020-05-28 07:05:48 +0100572 * b) Fixed IV lengths matches total IV length, giving
573 * IV = fixed_iv XOR ( 0 || dynamic_iv )
Hanno Becker15952812020-06-04 13:31:46 +0100574 *
575 * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
576 *
577 * See also the documentation of mbedtls_ssl_transform.
Hanno Beckerf486e282020-06-04 13:33:08 +0100578 *
579 * This function has the precondition that
580 *
581 * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
582 *
583 * which has to be ensured by the caller. If this precondition
584 * violated, the behavior of this function is undefined.
Hanno Becker17263802020-05-28 07:05:48 +0100585 */
586static void ssl_build_record_nonce( unsigned char *dst_iv,
587 size_t dst_iv_len,
588 unsigned char const *fixed_iv,
589 size_t fixed_iv_len,
590 unsigned char const *dynamic_iv,
591 size_t dynamic_iv_len )
592{
593 size_t i;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100594
595 /* Start with Fixed IV || 0 */
Hanno Becker17263802020-05-28 07:05:48 +0100596 memset( dst_iv, 0, dst_iv_len );
597 memcpy( dst_iv, fixed_iv, fixed_iv_len );
Hanno Beckerdf8be222020-05-21 15:30:57 +0100598
Hanno Becker17263802020-05-28 07:05:48 +0100599 dst_iv += dst_iv_len - dynamic_iv_len;
600 for( i = 0; i < dynamic_iv_len; i++ )
601 dst_iv[i] ^= dynamic_iv[i];
Hanno Beckerdf8be222020-05-21 15:30:57 +0100602}
Hanno Becker67a37db2020-05-28 16:27:07 +0100603#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
Hanno Beckerdf8be222020-05-21 15:30:57 +0100604
Hanno Beckera18d1322018-01-03 14:27:32 +0000605int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
606 mbedtls_ssl_transform *transform,
607 mbedtls_record *rec,
608 int (*f_rng)(void *, unsigned char *, size_t),
609 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000610{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_cipher_mode_t mode;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100612 int auth_done = 0;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000613 unsigned char * data;
Hanno Becker92fb4fa2019-05-20 14:54:26 +0100614 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
Hanno Beckercab87e62019-04-29 13:52:53 +0100615 size_t add_data_len;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000616 size_t post_avail;
617
618 /* The SSL context is only used for debugging purposes! */
Hanno Beckera18d1322018-01-03 14:27:32 +0000619#if !defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +0200620 ssl = NULL; /* make sure we don't use it except for debug */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000621 ((void) ssl);
622#endif
623
624 /* The PRNG is used for dynamic IV generation that's used
625 * for CBC transformations in TLS 1.1 and TLS 1.2. */
Manuel Pégourié-Gonnard2df1f1f2020-07-09 12:11:39 +0200626#if !( defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000627 ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) )
628 ((void) f_rng);
629 ((void) p_rng);
630#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000634 if( transform == NULL )
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100635 {
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000636 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) );
637 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
638 }
Hanno Becker43c24b82019-05-01 09:45:57 +0100639 if( rec == NULL
640 || rec->buf == NULL
641 || rec->buf_len < rec->data_offset
642 || rec->buf_len - rec->data_offset < rec->data_len
Hanno Beckera0e20d02019-05-15 14:03:01 +0100643#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker43c24b82019-05-01 09:45:57 +0100644 || rec->cid_len != 0
645#endif
646 )
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000647 {
648 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100650 }
651
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000652 data = rec->buf + rec->data_offset;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100653 post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000655 data, rec->data_len );
656
657 mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
658
659 if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
660 {
Paul Elliottd48d5c62021-01-07 14:47:05 +0000661 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %" MBEDTLS_PRINTF_SIZET
662 " too large, maximum %" MBEDTLS_PRINTF_SIZET,
Paul Elliott3891caf2020-12-17 18:42:40 +0000663 rec->data_len,
664 (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000665 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
666 }
Manuel Pégourié-Gonnard60346be2014-11-21 11:38:37 +0100667
Hanno Becker92313402020-05-20 13:58:58 +0100668 /* The following two code paths implement the (D)TLSInnerPlaintext
669 * structure present in TLS 1.3 and DTLS 1.2 + CID.
670 *
671 * See ssl_build_inner_plaintext() for more information.
672 *
673 * Note that this changes `rec->data_len`, and hence
674 * `post_avail` needs to be recalculated afterwards.
675 *
676 * Note also that the two code paths cannot occur simultaneously
677 * since they apply to different versions of the protocol. There
678 * is hence no risk of double-addition of the inner plaintext.
679 */
Hanno Beckerccc13d02020-05-04 12:30:04 +0100680#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
681 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
682 {
Hanno Becker13996922020-05-28 16:15:19 +0100683 size_t padding =
684 ssl_compute_padding_length( rec->data_len,
Hanno Beckerceef8482020-06-02 06:16:00 +0100685 MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY );
Hanno Beckerccc13d02020-05-04 12:30:04 +0100686 if( ssl_build_inner_plaintext( data,
Hanno Becker13996922020-05-28 16:15:19 +0100687 &rec->data_len,
688 post_avail,
689 rec->type,
690 padding ) != 0 )
Hanno Beckerccc13d02020-05-04 12:30:04 +0100691 {
692 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
693 }
694
695 rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
696 }
697#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
698
Hanno Beckera0e20d02019-05-15 14:03:01 +0100699#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckercab87e62019-04-29 13:52:53 +0100700 /*
701 * Add CID information
702 */
703 rec->cid_len = transform->out_cid_len;
704 memcpy( rec->cid, transform->out_cid, transform->out_cid_len );
705 MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len );
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100706
707 if( rec->cid_len != 0 )
708 {
Hanno Becker13996922020-05-28 16:15:19 +0100709 size_t padding =
710 ssl_compute_padding_length( rec->data_len,
711 MBEDTLS_SSL_CID_PADDING_GRANULARITY );
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100712 /*
Hanno Becker07dc97d2019-05-20 15:08:01 +0100713 * Wrap plaintext into DTLSInnerPlaintext structure.
Hanno Becker581bc1b2020-05-04 12:20:03 +0100714 * See ssl_build_inner_plaintext() for more information.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100715 *
Hanno Becker07dc97d2019-05-20 15:08:01 +0100716 * Note that this changes `rec->data_len`, and hence
717 * `post_avail` needs to be recalculated afterwards.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100718 */
Hanno Becker581bc1b2020-05-04 12:20:03 +0100719 if( ssl_build_inner_plaintext( data,
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100720 &rec->data_len,
721 post_avail,
Hanno Becker13996922020-05-28 16:15:19 +0100722 rec->type,
723 padding ) != 0 )
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100724 {
725 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
726 }
727
728 rec->type = MBEDTLS_SSL_MSG_CID;
729 }
Hanno Beckera0e20d02019-05-15 14:03:01 +0100730#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +0100731
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100732 post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
733
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 /*
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +0100735 * Add MAC before if needed
Paul Bakker5121ce52009-01-03 21:22:43 +0000736 */
Hanno Becker52344c22018-01-03 15:24:20 +0000737#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 if( mode == MBEDTLS_MODE_STREAM ||
739 ( mode == MBEDTLS_MODE_CBC
740#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000741 && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100742#endif
743 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 {
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000745 if( post_avail < transform->maclen )
746 {
747 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
748 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
749 }
750
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751#if defined(MBEDTLS_SSL_PROTO_SSL3)
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000752 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200753 {
Hanno Becker9d062f92020-02-07 10:26:36 +0000754 unsigned char mac[SSL3_MAC_MAX_BYTES];
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100755 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
756 ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
757 data, rec->data_len, rec->ctr, rec->type, mac );
758 if( ret == 0 )
759 memcpy( data + rec->data_len, mac, transform->maclen );
Gilles Peskined8e2e832021-12-10 21:33:21 +0100760 mbedtls_platform_zeroize( mac, transform->maclen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100761 if( ret != 0 )
762 {
763 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
764 return( ret );
765 }
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200766 }
767 else
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200768#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
770 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000771 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200772 {
Hanno Becker992b6872017-11-09 18:57:39 +0000773 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100774 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker992b6872017-11-09 18:57:39 +0000775
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100776 ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
777 transform->minor_ver );
Hanno Becker992b6872017-11-09 18:57:39 +0000778
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100779 ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
780 add_data, add_data_len );
781 if( ret != 0 )
782 goto hmac_failed_etm_disabled;
783 ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
784 data, rec->data_len );
785 if( ret != 0 )
786 goto hmac_failed_etm_disabled;
787 ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
788 if( ret != 0 )
789 goto hmac_failed_etm_disabled;
790 ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
791 if( ret != 0 )
792 goto hmac_failed_etm_disabled;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000793
794 memcpy( data + rec->data_len, mac, transform->maclen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100795
796 hmac_failed_etm_disabled:
Gilles Peskined8e2e832021-12-10 21:33:21 +0100797 mbedtls_platform_zeroize( mac, transform->maclen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +0100798 if( ret != 0 )
799 {
800 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
801 return( ret );
802 }
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200803 }
804 else
Paul Bakkerd2f068e2013-08-27 21:19:20 +0200805#endif
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200806 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
808 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200809 }
810
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000811 MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
812 transform->maclen );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200813
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000814 rec->data_len += transform->maclen;
815 post_avail -= transform->maclen;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100816 auth_done++;
Paul Bakker577e0062013-08-28 11:57:20 +0200817 }
Hanno Becker52344c22018-01-03 15:24:20 +0000818#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200820 /*
821 * Encrypt
822 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
824 if( mode == MBEDTLS_MODE_STREAM )
Paul Bakker5121ce52009-01-03 21:22:43 +0000825 {
Janos Follath865b3eb2019-12-16 11:46:15 +0000826 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000827 size_t olen;
Paul Elliottd48d5c62021-01-07 14:47:05 +0000828 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000829 "including %d bytes of padding",
830 rec->data_len, 0 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000832 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
833 transform->iv_enc, transform->ivlen,
834 data, rec->data_len,
835 data, &olen ) ) != 0 )
Paul Bakker45125bc2013-09-04 16:47:11 +0200836 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
Paul Bakkerea6ad3f2013-09-02 14:57:01 +0200838 return( ret );
839 }
840
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000841 if( rec->data_len != olen )
Paul Bakkerea6ad3f2013-09-02 14:57:01 +0200842 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
844 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkerea6ad3f2013-09-02 14:57:01 +0200845 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000846 }
Paul Bakker68884e32013-01-07 18:20:04 +0100847 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
Hanno Becker2e24c3b2017-12-27 21:28:58 +0000849
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200850#if defined(MBEDTLS_GCM_C) || \
851 defined(MBEDTLS_CCM_C) || \
852 defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 if( mode == MBEDTLS_MODE_GCM ||
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200854 mode == MBEDTLS_MODE_CCM ||
855 mode == MBEDTLS_MODE_CHACHAPOLY )
Paul Bakkerca4ab492012-04-18 14:23:57 +0000856 {
Janos Follath865b3eb2019-12-16 11:46:15 +0000857 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200858 unsigned char iv[12];
Hanno Beckerdf8be222020-05-21 15:30:57 +0100859 unsigned char *dynamic_iv;
860 size_t dynamic_iv_len;
Hanno Becker17263802020-05-28 07:05:48 +0100861 int dynamic_iv_is_explicit =
862 ssl_transform_aead_dynamic_iv_is_explicit( transform );
Paul Bakkerca4ab492012-04-18 14:23:57 +0000863
Hanno Beckerbd5ed1d2020-05-21 15:26:39 +0100864 /* Check that there's space for the authentication tag. */
865 if( post_avail < transform->taglen )
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000866 {
867 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
868 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
869 }
Paul Bakkerca4ab492012-04-18 14:23:57 +0000870
Paul Bakker68884e32013-01-07 18:20:04 +0100871 /*
Hanno Beckerdf8be222020-05-21 15:30:57 +0100872 * Build nonce for AEAD encryption.
873 *
874 * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
875 * part of the IV is prepended to the ciphertext and
876 * can be chosen freely - in particular, it need not
877 * agree with the record sequence number.
878 * However, since ChaChaPoly as well as all AEAD modes
879 * in TLS 1.3 use the record sequence number as the
880 * dynamic part of the nonce, we uniformly use the
881 * record sequence number here in all cases.
Paul Bakker68884e32013-01-07 18:20:04 +0100882 */
Hanno Beckerdf8be222020-05-21 15:30:57 +0100883 dynamic_iv = rec->ctr;
884 dynamic_iv_len = sizeof( rec->ctr );
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200885
Hanno Becker17263802020-05-28 07:05:48 +0100886 ssl_build_record_nonce( iv, sizeof( iv ),
887 transform->iv_enc,
888 transform->fixed_ivlen,
889 dynamic_iv,
890 dynamic_iv_len );
Manuel Pégourié-Gonnardd056ce02014-10-29 22:29:20 +0100891
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100892 /*
893 * Build additional data for AEAD encryption.
894 * This depends on the TLS version.
895 */
896 ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
897 transform->minor_ver );
Hanno Becker1f10d762019-04-26 13:34:37 +0100898
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200899 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
Hanno Becker7cca3582020-06-04 13:27:22 +0100900 iv, transform->ivlen );
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200901 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
Hanno Becker16bf0e22020-06-04 13:27:34 +0100902 dynamic_iv,
903 dynamic_iv_is_explicit ? dynamic_iv_len : 0 );
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000904 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
Hanno Beckercab87e62019-04-29 13:52:53 +0100905 add_data, add_data_len );
Paul Elliottd48d5c62021-01-07 14:47:05 +0000906 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200907 "including 0 bytes of padding",
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000908 rec->data_len ) );
Paul Bakkerca4ab492012-04-18 14:23:57 +0000909
Paul Bakker68884e32013-01-07 18:20:04 +0100910 /*
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +0200911 * Encrypt and authenticate
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +0200912 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000913
Manuel Pégourié-Gonnardf5cf71e2020-12-01 11:43:40 +0100914 if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc,
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000915 iv, transform->ivlen,
Manuel Pégourié-Gonnardf5cf71e2020-12-01 11:43:40 +0100916 add_data, add_data_len,
917 data, rec->data_len, /* src */
918 data, rec->buf_len - (data - rec->buf), /* dst */
919 &rec->data_len,
920 transform->taglen ) ) != 0 )
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +0200921 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +0200923 return( ret );
924 }
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000925 MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
Manuel Pégourié-Gonnardf5cf71e2020-12-01 11:43:40 +0100926 data + rec->data_len - transform->taglen,
927 transform->taglen );
Hanno Beckerdf8be222020-05-21 15:30:57 +0100928 /* Account for authentication tag. */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000929 post_avail -= transform->taglen;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100930
931 /*
932 * Prefix record content with dynamic IV in case it is explicit.
933 */
Hanno Becker1cda2662020-06-04 13:28:28 +0100934 if( dynamic_iv_is_explicit != 0 )
Hanno Beckerdf8be222020-05-21 15:30:57 +0100935 {
936 if( rec->data_offset < dynamic_iv_len )
937 {
938 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
939 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
940 }
941
942 memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len );
943 rec->data_offset -= dynamic_iv_len;
944 rec->data_len += dynamic_iv_len;
945 }
946
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100947 auth_done++;
Paul Bakkerca4ab492012-04-18 14:23:57 +0000948 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 else
Hanno Beckerc3f7b0b2020-05-28 16:27:16 +0100950#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
Manuel Pégourié-Gonnard2df1f1f2020-07-09 12:11:39 +0200951#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 if( mode == MBEDTLS_MODE_CBC )
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 {
Janos Follath865b3eb2019-12-16 11:46:15 +0000954 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000955 size_t padlen, i;
956 size_t olen;
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000957
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000958 /* Currently we're always using minimal padding
959 * (up to 255 bytes would be allowed). */
960 padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen;
961 if( padlen == transform->ivlen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 padlen = 0;
963
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000964 /* Check there's enough space in the buffer for the padding. */
965 if( post_avail < padlen + 1 )
966 {
967 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
968 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
969 }
970
Paul Bakker5121ce52009-01-03 21:22:43 +0000971 for( i = 0; i <= padlen; i++ )
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000972 data[rec->data_len + i] = (unsigned char) padlen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000973
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000974 rec->data_len += padlen + 1;
975 post_avail -= padlen + 1;
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000978 /*
Paul Bakker1ef83d62012-04-11 12:09:53 +0000979 * Prepend per-record IV for block cipher in TLS v1.1 and up as per
980 * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000981 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000982 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000983 {
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000984 if( f_rng == NULL )
985 {
986 MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
987 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
988 }
989
990 if( rec->data_offset < transform->ivlen )
991 {
992 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
993 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
994 }
995
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000996 /*
997 * Generate IV
998 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000999 ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
Paul Bakkera3d195c2011-11-27 21:07:34 +00001000 if( ret != 0 )
1001 return( ret );
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001002
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001003 memcpy( data - transform->ivlen, transform->iv_enc,
1004 transform->ivlen );
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001005
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001006 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001008
Paul Elliottd48d5c62021-01-07 14:47:05 +00001009 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
1010 "including %" MBEDTLS_PRINTF_SIZET
1011 " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001012 rec->data_len, transform->ivlen,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001013 padlen + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001014
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001015 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
1016 transform->iv_enc,
1017 transform->ivlen,
1018 data, rec->data_len,
1019 data, &olen ) ) != 0 )
Paul Bakker45125bc2013-09-04 16:47:11 +02001020 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
Paul Bakkercca5b812013-08-31 17:40:26 +02001022 return( ret );
1023 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001024
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001025 if( rec->data_len != olen )
Paul Bakkercca5b812013-08-31 17:40:26 +02001026 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1028 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkercca5b812013-08-31 17:40:26 +02001029 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001032 if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
Paul Bakkercca5b812013-08-31 17:40:26 +02001033 {
1034 /*
1035 * Save IV in SSL3 and TLS1
1036 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001037 memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
1038 transform->ivlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 }
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001040 else
Paul Bakkercca5b812013-08-31 17:40:26 +02001041#endif
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001042 {
1043 data -= transform->ivlen;
1044 rec->data_offset -= transform->ivlen;
1045 rec->data_len += transform->ivlen;
1046 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001049 if( auth_done == 0 )
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001050 {
Hanno Becker3d8c9072018-01-05 16:24:22 +00001051 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
1052
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001053 /*
1054 * MAC(MAC_write_key, seq_num +
1055 * TLSCipherText.type +
1056 * TLSCipherText.version +
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +01001057 * length_of( (IV +) ENC(...) ) +
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001058 * IV + // except for TLS 1.0
1059 * ENC(content + padding + padding_length));
1060 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001061
1062 if( post_avail < transform->maclen)
1063 {
1064 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
1065 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1066 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001067
Hanno Becker1cb6c2a2020-05-21 15:25:21 +01001068 ssl_extract_add_data_from_record( add_data, &add_data_len,
1069 rec, transform->minor_ver );
Hanno Becker1f10d762019-04-26 13:34:37 +01001070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001072 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
Hanno Beckercab87e62019-04-29 13:52:53 +01001073 add_data_len );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001074
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001075 ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
1076 add_data_len );
1077 if( ret != 0 )
1078 goto hmac_failed_etm_enabled;
1079 ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
1080 data, rec->data_len );
1081 if( ret != 0 )
1082 goto hmac_failed_etm_enabled;
1083 ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
1084 if( ret != 0 )
1085 goto hmac_failed_etm_enabled;
1086 ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
1087 if( ret != 0 )
1088 goto hmac_failed_etm_enabled;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001089
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001090 memcpy( data + rec->data_len, mac, transform->maclen );
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001091
Hanno Becker9eddaeb2017-12-27 21:37:21 +00001092 rec->data_len += transform->maclen;
1093 post_avail -= transform->maclen;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001094 auth_done++;
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001095
1096 hmac_failed_etm_enabled:
Gilles Peskined8e2e832021-12-10 21:33:21 +01001097 mbedtls_platform_zeroize( mac, transform->maclen );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001098 if( ret != 0 )
1099 {
1100 MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
1101 return( ret );
1102 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001103 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001105 }
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001106 else
Manuel Pégourié-Gonnard2df1f1f2020-07-09 12:11:39 +02001107#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1110 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001111 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001112
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001113 /* Make extra sure authentication was performed, exactly once */
1114 if( auth_done != 1 )
1115 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1117 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001118 }
1119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001121
1122 return( 0 );
1123}
1124
Hanno Becker605949f2019-07-12 08:23:59 +01001125int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
Hanno Beckera18d1322018-01-03 14:27:32 +00001126 mbedtls_ssl_transform *transform,
1127 mbedtls_record *rec )
Paul Bakker5121ce52009-01-03 21:22:43 +00001128{
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001129 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001130 mbedtls_cipher_mode_t mode;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001131 int ret, auth_done = 0;
Hanno Becker52344c22018-01-03 15:24:20 +00001132#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Paul Bakker1e5369c2013-12-19 16:40:57 +01001133 size_t padlen = 0, correct = 1;
1134#endif
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001135 unsigned char* data;
Hanno Becker92fb4fa2019-05-20 14:54:26 +01001136 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
Hanno Beckercab87e62019-04-29 13:52:53 +01001137 size_t add_data_len;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001138
Hanno Beckera18d1322018-01-03 14:27:32 +00001139#if !defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +02001140 ssl = NULL; /* make sure we don't use it except for debug */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001141 ((void) ssl);
1142#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001145 if( rec == NULL ||
1146 rec->buf == NULL ||
1147 rec->buf_len < rec->data_offset ||
1148 rec->buf_len - rec->data_offset < rec->data_len )
1149 {
1150 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001152 }
1153
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001154 data = rec->buf + rec->data_offset;
1155 mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
Paul Bakker5121ce52009-01-03 21:22:43 +00001156
Hanno Beckera0e20d02019-05-15 14:03:01 +01001157#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckercab87e62019-04-29 13:52:53 +01001158 /*
1159 * Match record's CID with incoming CID.
1160 */
Hanno Becker938489a2019-05-08 13:02:22 +01001161 if( rec->cid_len != transform->in_cid_len ||
1162 memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 )
1163 {
Hanno Becker8367ccc2019-05-14 11:30:10 +01001164 return( MBEDTLS_ERR_SSL_UNEXPECTED_CID );
Hanno Becker938489a2019-05-08 13:02:22 +01001165 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01001166#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +01001167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
1169 if( mode == MBEDTLS_MODE_STREAM )
Paul Bakker68884e32013-01-07 18:20:04 +01001170 {
1171 padlen = 0;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001172 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
1173 transform->iv_dec,
1174 transform->ivlen,
1175 data, rec->data_len,
1176 data, &olen ) ) != 0 )
Paul Bakker45125bc2013-09-04 16:47:11 +02001177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001179 return( ret );
1180 }
1181
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001182 if( rec->data_len != olen )
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001183 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1185 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001186 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 }
Paul Bakker68884e32013-01-07 18:20:04 +01001188 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001190#if defined(MBEDTLS_GCM_C) || \
1191 defined(MBEDTLS_CCM_C) || \
1192 defined(MBEDTLS_CHACHAPOLY_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 if( mode == MBEDTLS_MODE_GCM ||
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001194 mode == MBEDTLS_MODE_CCM ||
1195 mode == MBEDTLS_MODE_CHACHAPOLY )
Paul Bakkerca4ab492012-04-18 14:23:57 +00001196 {
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001197 unsigned char iv[12];
Hanno Beckerdf8be222020-05-21 15:30:57 +01001198 unsigned char *dynamic_iv;
1199 size_t dynamic_iv_len;
Paul Bakkerca4ab492012-04-18 14:23:57 +00001200
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001201 /*
Hanno Beckerdf8be222020-05-21 15:30:57 +01001202 * Extract dynamic part of nonce for AEAD decryption.
1203 *
1204 * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
1205 * part of the IV is prepended to the ciphertext and
1206 * can be chosen freely - in particular, it need not
1207 * agree with the record sequence number.
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001208 */
Hanno Beckerdf8be222020-05-21 15:30:57 +01001209 dynamic_iv_len = sizeof( rec->ctr );
Hanno Becker17263802020-05-28 07:05:48 +01001210 if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 )
Hanno Beckerdf8be222020-05-21 15:30:57 +01001211 {
1212 if( rec->data_len < dynamic_iv_len )
1213 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001214 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
1215 " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
Hanno Beckerdf8be222020-05-21 15:30:57 +01001216 rec->data_len,
1217 dynamic_iv_len ) );
1218 return( MBEDTLS_ERR_SSL_INVALID_MAC );
1219 }
1220 dynamic_iv = data;
1221
1222 data += dynamic_iv_len;
1223 rec->data_offset += dynamic_iv_len;
1224 rec->data_len -= dynamic_iv_len;
1225 }
Hanno Becker17263802020-05-28 07:05:48 +01001226 else
1227 {
1228 dynamic_iv = rec->ctr;
1229 }
Hanno Beckerdf8be222020-05-21 15:30:57 +01001230
1231 /* Check that there's space for the authentication tag. */
1232 if( rec->data_len < transform->taglen )
1233 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001234 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
1235 ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
Christian von Arnim883d3042020-12-01 11:58:29 +01001236 rec->data_len,
1237 transform->taglen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Manuel Pégourié-Gonnard0bcc4e12014-06-17 10:54:17 +02001239 }
Hanno Beckerdf8be222020-05-21 15:30:57 +01001240 rec->data_len -= transform->taglen;
Paul Bakker68884e32013-01-07 18:20:04 +01001241
Hanno Beckerdf8be222020-05-21 15:30:57 +01001242 /*
1243 * Prepare nonce from dynamic and static parts.
1244 */
Hanno Becker17263802020-05-28 07:05:48 +01001245 ssl_build_record_nonce( iv, sizeof( iv ),
1246 transform->iv_dec,
1247 transform->fixed_ivlen,
1248 dynamic_iv,
1249 dynamic_iv_len );
Paul Bakker68884e32013-01-07 18:20:04 +01001250
Hanno Beckerdf8be222020-05-21 15:30:57 +01001251 /*
1252 * Build additional data for AEAD encryption.
1253 * This depends on the TLS version.
1254 */
Hanno Becker1cb6c2a2020-05-21 15:25:21 +01001255 ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
1256 transform->minor_ver );
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001257 MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
Hanno Beckercab87e62019-04-29 13:52:53 +01001258 add_data, add_data_len );
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001259
Hanno Beckerd96a6522019-07-10 13:55:25 +01001260 /* Because of the check above, we know that there are
Shaun Case0e7791f2021-12-20 21:14:10 -08001261 * explicit_iv_len Bytes preceding data, and taglen
Hanno Beckerd96a6522019-07-10 13:55:25 +01001262 * bytes following data + data_len. This justifies
Hanno Becker20016652019-07-10 11:44:13 +01001263 * the debug message and the invocation of
Hanno Beckerd96a6522019-07-10 13:55:25 +01001264 * mbedtls_cipher_auth_decrypt() below. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001265
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001266 MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001267 MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len,
Hanno Beckere694c3e2017-12-27 21:34:08 +00001268 transform->taglen );
Paul Bakker68884e32013-01-07 18:20:04 +01001269
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001270 /*
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001271 * Decrypt and authenticate
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001272 */
Manuel Pégourié-Gonnardf5cf71e2020-12-01 11:43:40 +01001273 if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec,
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001274 iv, transform->ivlen,
Hanno Beckercab87e62019-04-29 13:52:53 +01001275 add_data, add_data_len,
Manuel Pégourié-Gonnardf5cf71e2020-12-01 11:43:40 +01001276 data, rec->data_len + transform->taglen, /* src */
1277 data, rec->buf_len - (data - rec->buf), &olen, /* dst */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001278 transform->taglen ) ) != 0 )
Paul Bakkerca4ab492012-04-18 14:23:57 +00001279 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001280 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282 if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
1283 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001284
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001285 return( ret );
1286 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001287 auth_done++;
Paul Bakkerca4ab492012-04-18 14:23:57 +00001288
Hanno Beckerd96a6522019-07-10 13:55:25 +01001289 /* Double-check that AEAD decryption doesn't change content length. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001290 if( olen != rec->data_len )
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001291 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1293 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001294 }
Paul Bakkerca4ab492012-04-18 14:23:57 +00001295 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001296 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001297#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
Manuel Pégourié-Gonnard2df1f1f2020-07-09 12:11:39 +02001298#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299 if( mode == MBEDTLS_MODE_CBC )
Paul Bakker5121ce52009-01-03 21:22:43 +00001300 {
Paul Bakkere47b34b2013-02-27 14:48:00 +01001301 size_t minlen = 0;
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001302
Paul Bakker5121ce52009-01-03 21:22:43 +00001303 /*
Paul Bakker45829992013-01-03 14:52:21 +01001304 * Check immediate ciphertext sanity
Paul Bakker5121ce52009-01-03 21:22:43 +00001305 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001306#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001307 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
1308 {
1309 /* The ciphertext is prefixed with the CBC IV. */
1310 minlen += transform->ivlen;
1311 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02001312#endif
Paul Bakker45829992013-01-03 14:52:21 +01001313
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001314 /* Size considerations:
1315 *
1316 * - The CBC cipher text must not be empty and hence
1317 * at least of size transform->ivlen.
1318 *
1319 * Together with the potential IV-prefix, this explains
1320 * the first of the two checks below.
1321 *
1322 * - The record must contain a MAC, either in plain or
1323 * encrypted, depending on whether Encrypt-then-MAC
1324 * is used or not.
1325 * - If it is, the message contains the IV-prefix,
1326 * the CBC ciphertext, and the MAC.
1327 * - If it is not, the padded plaintext, and hence
1328 * the CBC ciphertext, has at least length maclen + 1
1329 * because there is at least the padding length byte.
1330 *
1331 * As the CBC ciphertext is not empty, both cases give the
1332 * lower bound minlen + maclen + 1 on the record size, which
1333 * we test for in the second check below.
1334 */
1335 if( rec->data_len < minlen + transform->ivlen ||
1336 rec->data_len < minlen + transform->maclen + 1 )
Paul Bakker45829992013-01-03 14:52:21 +01001337 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001338 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
1339 ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
1340 "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001341 "+ 1 ) ( + expl IV )", rec->data_len,
1342 transform->ivlen,
1343 transform->maclen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Paul Bakker45829992013-01-03 14:52:21 +01001345 }
1346
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001347 /*
1348 * Authenticate before decrypt if enabled
1349 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001350#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001351 if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001352 {
Hanno Becker992b6872017-11-09 18:57:39 +00001353 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001355 MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001356
Hanno Beckerd96a6522019-07-10 13:55:25 +01001357 /* Update data_len in tandem with add_data.
1358 *
1359 * The subtraction is safe because of the previous check
1360 * data_len >= minlen + maclen + 1.
1361 *
1362 * Afterwards, we know that data + data_len is followed by at
1363 * least maclen Bytes, which justifies the call to
Gabor Mezei18a44942021-10-20 11:59:27 +02001364 * mbedtls_ct_memcmp() below.
Hanno Beckerd96a6522019-07-10 13:55:25 +01001365 *
1366 * Further, we still know that data_len > minlen */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001367 rec->data_len -= transform->maclen;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +01001368 ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
1369 transform->minor_ver );
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +01001370
Hanno Beckerd96a6522019-07-10 13:55:25 +01001371 /* Calculate expected MAC. */
Hanno Beckercab87e62019-04-29 13:52:53 +01001372 MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
1373 add_data_len );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001374 ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
1375 add_data_len );
1376 if( ret != 0 )
1377 goto hmac_failed_etm_enabled;
1378 ret = mbedtls_md_hmac_update( &transform->md_ctx_dec,
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001379 data, rec->data_len );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001380 if( ret != 0 )
1381 goto hmac_failed_etm_enabled;
1382 ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
1383 if( ret != 0 )
1384 goto hmac_failed_etm_enabled;
1385 ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec );
1386 if( ret != 0 )
1387 goto hmac_failed_etm_enabled;
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +01001388
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001389 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len,
1390 transform->maclen );
Hanno Becker992b6872017-11-09 18:57:39 +00001391 MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001392 transform->maclen );
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001393
Hanno Beckerd96a6522019-07-10 13:55:25 +01001394 /* Compare expected MAC with MAC at the end of the record. */
Gabor Mezei18a44942021-10-20 11:59:27 +02001395 if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect,
gabor-mezei-arm378e7eb2021-07-19 15:19:19 +02001396 transform->maclen ) != 0 )
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001397 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001398 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
Gilles Peskined8e2e832021-12-10 21:33:21 +01001399 ret = MBEDTLS_ERR_SSL_INVALID_MAC;
1400 goto hmac_failed_etm_enabled;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001401 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001402 auth_done++;
Gilles Peskined8e2e832021-12-10 21:33:21 +01001403
1404 hmac_failed_etm_enabled:
1405 mbedtls_platform_zeroize( mac_expect, transform->maclen );
1406 if( ret != 0 )
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001407 {
1408 if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
1409 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
Gilles Peskined8e2e832021-12-10 21:33:21 +01001410 return( ret );
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001411 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001412 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001413#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001414
1415 /*
1416 * Check length sanity
1417 */
Hanno Beckerd96a6522019-07-10 13:55:25 +01001418
1419 /* We know from above that data_len > minlen >= 0,
1420 * so the following check in particular implies that
1421 * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001422 if( rec->data_len % transform->ivlen != 0 )
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001423 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001424 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
1425 ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001426 rec->data_len, transform->ivlen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001428 }
1429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001431 /*
Paul Bakker1ef83d62012-04-11 12:09:53 +00001432 * Initialize for prepended IV for block cipher in TLS v1.1 and up
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001433 */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001434 if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001435 {
Hanno Beckerd96a6522019-07-10 13:55:25 +01001436 /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001437 memcpy( transform->iv_dec, data, transform->ivlen );
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001438
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001439 data += transform->ivlen;
1440 rec->data_offset += transform->ivlen;
1441 rec->data_len -= transform->ivlen;
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001442 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001444
Hanno Beckerd96a6522019-07-10 13:55:25 +01001445 /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
1446
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001447 if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
1448 transform->iv_dec, transform->ivlen,
1449 data, rec->data_len, data, &olen ) ) != 0 )
Paul Bakker45125bc2013-09-04 16:47:11 +02001450 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
Paul Bakkercca5b812013-08-31 17:40:26 +02001452 return( ret );
1453 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001454
Hanno Beckerd96a6522019-07-10 13:55:25 +01001455 /* Double-check that length hasn't changed during decryption. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001456 if( rec->data_len != olen )
Paul Bakkercca5b812013-08-31 17:40:26 +02001457 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001458 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1459 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakkercca5b812013-08-31 17:40:26 +02001460 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001463 if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
Paul Bakkercca5b812013-08-31 17:40:26 +02001464 {
1465 /*
Hanno Beckerd96a6522019-07-10 13:55:25 +01001466 * Save IV in SSL3 and TLS1, where CBC decryption of consecutive
1467 * records is equivalent to CBC decryption of the concatenation
1468 * of the records; in other words, IVs are maintained across
1469 * record decryptions.
Paul Bakkercca5b812013-08-31 17:40:26 +02001470 */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001471 memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
1472 transform->ivlen );
Paul Bakker5121ce52009-01-03 21:22:43 +00001473 }
Paul Bakkercca5b812013-08-31 17:40:26 +02001474#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001475
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001476 /* Safe since data_len >= minlen + maclen + 1, so after having
1477 * subtracted at most minlen and maclen up to this point,
Hanno Beckerd96a6522019-07-10 13:55:25 +01001478 * data_len > 0 (because of data_len % ivlen == 0, it's actually
1479 * >= ivlen ). */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001480 padlen = data[rec->data_len - 1];
Paul Bakker45829992013-01-03 14:52:21 +01001481
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001482 if( auth_done == 1 )
1483 {
Gabor Mezei18a44942021-10-20 11:59:27 +02001484 const size_t mask = mbedtls_ct_size_mask_ge(
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001485 rec->data_len,
1486 padlen + 1 );
1487 correct &= mask;
1488 padlen &= mask;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001489 }
1490 else
Paul Bakker45829992013-01-03 14:52:21 +01001491 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#if defined(MBEDTLS_SSL_DEBUG_ALL)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001493 if( rec->data_len < transform->maclen + padlen + 1 )
1494 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001495 MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
1496 ") < maclen (%" MBEDTLS_PRINTF_SIZET
1497 ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001498 rec->data_len,
1499 transform->maclen,
1500 padlen + 1 ) );
1501 }
Paul Bakkerd66f0702013-01-31 16:57:45 +01001502#endif
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001503
Gabor Mezei18a44942021-10-20 11:59:27 +02001504 const size_t mask = mbedtls_ct_size_mask_ge(
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001505 rec->data_len,
1506 transform->maclen + padlen + 1 );
1507 correct &= mask;
1508 padlen &= mask;
Paul Bakker45829992013-01-03 14:52:21 +01001509 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001510
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001511 padlen++;
1512
1513 /* Regardless of the validity of the padding,
1514 * we have data_len >= padlen here. */
1515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516#if defined(MBEDTLS_SSL_PROTO_SSL3)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001517 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 {
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001519 /* This is the SSL 3.0 path, we don't have to worry about Lucky
1520 * 13, because there's a strictly worse padding attack built in
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +02001521 * the protocol (known as part of POODLE), so we don't care if the
1522 * code is not constant-time, in particular branches are OK. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001523 if( padlen > transform->ivlen )
Paul Bakker5121ce52009-01-03 21:22:43 +00001524 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_SSL_DEBUG_ALL)
Paul Elliottd48d5c62021-01-07 14:47:05 +00001526 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %" MBEDTLS_PRINTF_SIZET ", "
1527 "should be no more than %" MBEDTLS_PRINTF_SIZET,
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001528 padlen, transform->ivlen ) );
Paul Bakkerd66f0702013-01-31 16:57:45 +01001529#endif
Paul Bakker45829992013-01-03 14:52:21 +01001530 correct = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 }
1532 }
1533 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#endif /* MBEDTLS_SSL_PROTO_SSL3 */
1535#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1536 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001537 if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 {
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001539 /* The padding check involves a series of up to 256
1540 * consecutive memory reads at the end of the record
1541 * plaintext buffer. In order to hide the length and
1542 * validity of the padding, always perform exactly
1543 * `min(256,plaintext_len)` reads (but take into account
1544 * only the last `padlen` bytes for the padding check). */
1545 size_t pad_count = 0;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001546 volatile unsigned char* const check = data;
Paul Bakkere47b34b2013-02-27 14:48:00 +01001547
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001548 /* Index of first padding byte; it has been ensured above
1549 * that the subtraction is safe. */
1550 size_t const padding_idx = rec->data_len - padlen;
1551 size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
1552 size_t const start_idx = rec->data_len - num_checks;
1553 size_t idx;
Paul Bakker956c9e02013-12-19 14:42:28 +01001554
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001555 for( idx = start_idx; idx < rec->data_len; idx++ )
Paul Bakkerca9c87e2013-09-25 18:52:37 +02001556 {
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001557 /* pad_count += (idx >= padding_idx) &&
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +02001558 * (check[idx] == padlen - 1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001559 */
Gabor Mezei18a44942021-10-20 11:59:27 +02001560 const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx );
1561 const size_t equal = mbedtls_ct_size_bool_eq( check[idx],
gabor-mezei-arme41e3e82021-09-28 16:14:47 +02001562 padlen - 1 );
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001563 pad_count += mask & equal;
Paul Bakkerca9c87e2013-09-25 18:52:37 +02001564 }
Gabor Mezei18a44942021-10-20 11:59:27 +02001565 correct &= mbedtls_ct_size_bool_eq( pad_count, padlen );
Paul Bakkere47b34b2013-02-27 14:48:00 +01001566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001567#if defined(MBEDTLS_SSL_DEBUG_ALL)
Paul Bakker66d5d072014-06-17 16:39:18 +02001568 if( padlen > 0 && correct == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
Paul Bakkerd66f0702013-01-31 16:57:45 +01001570#endif
Gabor Mezei18a44942021-10-20 11:59:27 +02001571 padlen &= mbedtls_ct_size_mask( correct );
Paul Bakker5121ce52009-01-03 21:22:43 +00001572 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02001573 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001574#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
1575 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02001576 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1578 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02001579 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001580
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001581 /* If the padding was found to be invalid, padlen == 0
1582 * and the subtraction is safe. If the padding was found valid,
1583 * padlen hasn't been changed and the previous assertion
1584 * data_len >= padlen still holds. */
1585 rec->data_len -= padlen;
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 }
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001587 else
Manuel Pégourié-Gonnard2df1f1f2020-07-09 12:11:39 +02001588#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001589 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001590 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1591 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001592 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
Manuel Pégourié-Gonnard6a25cfa2018-07-10 11:15:36 +02001594#if defined(MBEDTLS_SSL_DEBUG_ALL)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595 MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001596 data, rec->data_len );
Manuel Pégourié-Gonnard6a25cfa2018-07-10 11:15:36 +02001597#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001598
1599 /*
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001600 * Authenticate if not done yet.
1601 * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
Paul Bakker5121ce52009-01-03 21:22:43 +00001602 */
Hanno Becker52344c22018-01-03 15:24:20 +00001603#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001604 if( auth_done == 0 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001605 {
Paul Elliottb8300282022-05-19 18:31:35 +01001606 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
1607 unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
Paul Bakker1e5369c2013-12-19 16:40:57 +01001608
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001609 /* If the initial value of padlen was such that
1610 * data_len < maclen + padlen + 1, then padlen
1611 * got reset to 1, and the initial check
1612 * data_len >= minlen + maclen + 1
1613 * guarantees that at this point we still
1614 * have at least data_len >= maclen.
1615 *
1616 * If the initial value of padlen was such that
1617 * data_len >= maclen + padlen + 1, then we have
1618 * subtracted either padlen + 1 (if the padding was correct)
1619 * or 0 (if the padding was incorrect) since then,
1620 * hence data_len >= maclen in any case.
1621 */
1622 rec->data_len -= transform->maclen;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +01001623 ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
1624 transform->minor_ver );
Paul Bakker5121ce52009-01-03 21:22:43 +00001625
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001626#if defined(MBEDTLS_SSL_PROTO_SSL3)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001627 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001628 {
Gilles Peskine2b3f21d2021-12-10 21:35:10 +01001629 ret = ssl_mac( &transform->md_ctx_dec,
1630 transform->mac_dec,
1631 data, rec->data_len,
1632 rec->ctr, rec->type,
1633 mac_expect );
1634 if( ret != 0 )
1635 {
1636 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
1637 goto hmac_failed_etm_disabled;
1638 }
Manuel Pégourié-Gonnard3c31afa2020-08-13 12:08:54 +02001639 memcpy( mac_peer, data + rec->data_len, transform->maclen );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001640 }
1641 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001642#endif /* MBEDTLS_SSL_PROTO_SSL3 */
1643#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
1644 defined(MBEDTLS_SSL_PROTO_TLS1_2)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001645 if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001646 {
1647 /*
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001648 * The next two sizes are the minimum and maximum values of
Manuel Pégourié-Gonnard7fe2c5f2020-08-18 12:02:54 +02001649 * data_len over all padlen values.
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001650 *
1651 * They're independent of padlen, since we previously did
Hanno Beckerd96a6522019-07-10 13:55:25 +01001652 * data_len -= padlen.
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001653 *
1654 * Note that max_len + maclen is never more than the buffer
1655 * length, as we previously did in_msglen -= maclen too.
1656 */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001657 const size_t max_len = rec->data_len + padlen;
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001658 const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
1659
Gabor Mezei18a44942021-10-20 11:59:27 +02001660 ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
gabor-mezei-arme41e3e82021-09-28 16:14:47 +02001661 add_data, add_data_len,
1662 data, rec->data_len, min_len, max_len,
1663 mac_expect );
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001664 if( ret != 0 )
Gilles Peskine20b44082018-05-29 14:06:49 +02001665 {
Gabor Mezei2dcccbf2021-11-16 13:34:05 +01001666 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
Gilles Peskined8e2e832021-12-10 21:33:21 +01001667 goto hmac_failed_etm_disabled;
Gilles Peskine20b44082018-05-29 14:06:49 +02001668 }
Paul Bakkere47b34b2013-02-27 14:48:00 +01001669
Gabor Mezei18a44942021-10-20 11:59:27 +02001670 mbedtls_ct_memcpy_offset( mac_peer, data,
gabor-mezei-arme41e3e82021-09-28 16:14:47 +02001671 rec->data_len,
1672 min_len, max_len,
1673 transform->maclen );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001674 }
1675 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001676#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
1677 MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001678 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001679 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1680 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001681 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001682
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001683#if defined(MBEDTLS_SSL_DEBUG_ALL)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001684 MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
Manuel Pégourié-Gonnard3c31afa2020-08-13 12:08:54 +02001685 MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, transform->maclen );
Manuel Pégourié-Gonnard7b420302018-06-28 10:38:35 +02001686#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001687
Gabor Mezei18a44942021-10-20 11:59:27 +02001688 if( mbedtls_ct_memcmp( mac_peer, mac_expect,
gabor-mezei-arm378e7eb2021-07-19 15:19:19 +02001689 transform->maclen ) != 0 )
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001690 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691#if defined(MBEDTLS_SSL_DEBUG_ALL)
1692 MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
Paul Bakkere47b34b2013-02-27 14:48:00 +01001693#endif
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001694 correct = 0;
1695 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001696 auth_done++;
Gilles Peskined8e2e832021-12-10 21:33:21 +01001697
1698 hmac_failed_etm_disabled:
1699 mbedtls_platform_zeroize( mac_peer, transform->maclen );
1700 mbedtls_platform_zeroize( mac_expect, transform->maclen );
1701 if( ret != 0 )
1702 return( ret );
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001703 }
Hanno Beckerdd3ab132018-10-17 14:43:14 +01001704
1705 /*
1706 * Finally check the correct flag
1707 */
1708 if( correct == 0 )
1709 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Hanno Becker52344c22018-01-03 15:24:20 +00001710#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001711
1712 /* Make extra sure authentication was performed, exactly once */
1713 if( auth_done != 1 )
1714 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001715 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1716 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001717 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001718
Hanno Beckerccc13d02020-05-04 12:30:04 +01001719#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
1720 if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
1721 {
1722 /* Remove inner padding and infer true content type. */
1723 ret = ssl_parse_inner_plaintext( data, &rec->data_len,
1724 &rec->type );
1725
1726 if( ret != 0 )
1727 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
1728 }
1729#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
1730
Hanno Beckera0e20d02019-05-15 14:03:01 +01001731#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker8b3eb5a2019-04-29 17:31:37 +01001732 if( rec->cid_len != 0 )
1733 {
Hanno Becker581bc1b2020-05-04 12:20:03 +01001734 ret = ssl_parse_inner_plaintext( data, &rec->data_len,
1735 &rec->type );
Hanno Becker8b3eb5a2019-04-29 17:31:37 +01001736 if( ret != 0 )
1737 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
1738 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01001739#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker8b3eb5a2019-04-29 17:31:37 +01001740
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001741 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001742
1743 return( 0 );
1744}
1745
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +01001746#undef MAC_NONE
1747#undef MAC_PLAINTEXT
1748#undef MAC_CIPHERTEXT
1749
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001750#if defined(MBEDTLS_ZLIB_SUPPORT)
Paul Bakker2770fbd2012-07-03 13:30:23 +00001751/*
1752 * Compression/decompression functions
1753 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001754MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001755static int ssl_compress_buf( mbedtls_ssl_context *ssl )
Paul Bakker2770fbd2012-07-03 13:30:23 +00001756{
Janos Follath865b3eb2019-12-16 11:46:15 +00001757 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001758 unsigned char *msg_post = ssl->out_msg;
Andrzej Kurek5462e022018-04-20 07:58:53 -04001759 ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001760 size_t len_pre = ssl->out_msglen;
Paul Bakker16770332013-10-11 09:59:44 +02001761 unsigned char *msg_pre = ssl->compress_buf;
Darryl Greenb33cc762019-11-28 14:29:44 +00001762#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1763 size_t out_buf_len = ssl->out_buf_len;
1764#else
1765 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
1766#endif
Paul Bakker2770fbd2012-07-03 13:30:23 +00001767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001768 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001769
Paul Bakkerabf2f8f2013-06-30 14:57:46 +02001770 if( len_pre == 0 )
1771 return( 0 );
1772
Paul Bakker2770fbd2012-07-03 13:30:23 +00001773 memcpy( msg_pre, ssl->out_msg, len_pre );
1774
Paul Elliottd48d5c62021-01-07 14:47:05 +00001775 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001776 ssl->out_msglen ) );
1777
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001778 MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001779 ssl->out_msg, ssl->out_msglen );
1780
Paul Bakker48916f92012-09-16 19:57:18 +00001781 ssl->transform_out->ctx_deflate.next_in = msg_pre;
1782 ssl->transform_out->ctx_deflate.avail_in = len_pre;
1783 ssl->transform_out->ctx_deflate.next_out = msg_post;
Darryl Greenb33cc762019-11-28 14:29:44 +00001784 ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001785
Paul Bakker48916f92012-09-16 19:57:18 +00001786 ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001787 if( ret != Z_OK )
1788 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001789 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
1790 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001791 }
1792
Darryl Greenb33cc762019-11-28 14:29:44 +00001793 ssl->out_msglen = out_buf_len -
Andrzej Kurek5462e022018-04-20 07:58:53 -04001794 ssl->transform_out->ctx_deflate.avail_out - bytes_written;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001795
Paul Elliottd48d5c62021-01-07 14:47:05 +00001796 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001797 ssl->out_msglen ) );
1798
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001800 ssl->out_msg, ssl->out_msglen );
1801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001802 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001803
1804 return( 0 );
1805}
1806
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02001807MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001808static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
Paul Bakker2770fbd2012-07-03 13:30:23 +00001809{
Janos Follath865b3eb2019-12-16 11:46:15 +00001810 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001811 unsigned char *msg_post = ssl->in_msg;
Andrzej Kureka9ceef82018-04-24 06:32:44 -04001812 ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001813 size_t len_pre = ssl->in_msglen;
Paul Bakker16770332013-10-11 09:59:44 +02001814 unsigned char *msg_pre = ssl->compress_buf;
Darryl Greenb33cc762019-11-28 14:29:44 +00001815#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1816 size_t in_buf_len = ssl->in_buf_len;
1817#else
1818 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
1819#endif
Paul Bakker2770fbd2012-07-03 13:30:23 +00001820
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001821 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001822
Paul Bakkerabf2f8f2013-06-30 14:57:46 +02001823 if( len_pre == 0 )
1824 return( 0 );
1825
Paul Bakker2770fbd2012-07-03 13:30:23 +00001826 memcpy( msg_pre, ssl->in_msg, len_pre );
1827
Paul Elliottd48d5c62021-01-07 14:47:05 +00001828 MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001829 ssl->in_msglen ) );
1830
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831 MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001832 ssl->in_msg, ssl->in_msglen );
1833
Paul Bakker48916f92012-09-16 19:57:18 +00001834 ssl->transform_in->ctx_inflate.next_in = msg_pre;
1835 ssl->transform_in->ctx_inflate.avail_in = len_pre;
1836 ssl->transform_in->ctx_inflate.next_out = msg_post;
Darryl Greenb33cc762019-11-28 14:29:44 +00001837 ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001838
Paul Bakker48916f92012-09-16 19:57:18 +00001839 ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001840 if( ret != Z_OK )
1841 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
1843 return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001844 }
1845
Darryl Greenb33cc762019-11-28 14:29:44 +00001846 ssl->in_msglen = in_buf_len -
Andrzej Kureka9ceef82018-04-24 06:32:44 -04001847 ssl->transform_in->ctx_inflate.avail_out - header_bytes;
Paul Bakker2770fbd2012-07-03 13:30:23 +00001848
Paul Elliottd48d5c62021-01-07 14:47:05 +00001849 MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001850 ssl->in_msglen ) );
1851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001852 MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
Paul Bakker2770fbd2012-07-03 13:30:23 +00001853 ssl->in_msg, ssl->in_msglen );
1854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
Paul Bakker2770fbd2012-07-03 13:30:23 +00001856
1857 return( 0 );
1858}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001859#endif /* MBEDTLS_ZLIB_SUPPORT */
Paul Bakker2770fbd2012-07-03 13:30:23 +00001860
Paul Bakker5121ce52009-01-03 21:22:43 +00001861/*
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001862 * Fill the input message buffer by appending data to it.
1863 * The amount of data already fetched is in ssl->in_left.
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001864 *
1865 * If we return 0, is it guaranteed that (at least) nb_want bytes are
1866 * available (from this read and/or a previous one). Otherwise, an error code
1867 * is returned (possibly EOF or WANT_READ).
1868 *
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001869 * With stream transport (TLS) on success ssl->in_left == nb_want, but
1870 * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
1871 * since we always read a whole datagram at once.
1872 *
Manuel Pégourié-Gonnard64dffc52014-09-02 13:39:16 +02001873 * For DTLS, it is up to the caller to set ssl->next_record_offset when
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001874 * they're done reading a record.
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001876int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
Paul Bakker5121ce52009-01-03 21:22:43 +00001877{
Janos Follath865b3eb2019-12-16 11:46:15 +00001878 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001879 size_t len;
Darryl Greenb33cc762019-11-28 14:29:44 +00001880#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
1881 size_t in_buf_len = ssl->in_buf_len;
1882#else
1883 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
1884#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001887
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02001888 if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
1889 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001890 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
Manuel Pégourié-Gonnard1b511f92015-05-06 15:54:23 +01001891 "or mbedtls_ssl_set_bio()" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001892 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02001893 }
1894
Darryl Greenb33cc762019-11-28 14:29:44 +00001895 if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
Paul Bakker1a1fbba2014-04-30 14:38:05 +02001896 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001897 MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
1898 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker1a1fbba2014-04-30 14:38:05 +02001899 }
1900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001902 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02001904 uint32_t timeout;
1905
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001906 /*
1907 * The point is, we need to always read a full datagram at once, so we
1908 * sometimes read more then requested, and handle the additional data.
1909 * It could be the rest of the current record (while fetching the
1910 * header) and/or some other records in the same datagram.
1911 */
1912
1913 /*
1914 * Move to the next record in the already read datagram if applicable
1915 */
1916 if( ssl->next_record_offset != 0 )
1917 {
1918 if( ssl->in_left < ssl->next_record_offset )
1919 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001920 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1921 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001922 }
1923
1924 ssl->in_left -= ssl->next_record_offset;
1925
1926 if( ssl->in_left != 0 )
1927 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00001928 MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %"
1929 MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001930 ssl->next_record_offset ) );
1931 memmove( ssl->in_hdr,
1932 ssl->in_hdr + ssl->next_record_offset,
1933 ssl->in_left );
1934 }
1935
1936 ssl->next_record_offset = 0;
1937 }
1938
Paul Elliottd48d5c62021-01-07 14:47:05 +00001939 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
1940 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 ssl->in_left, nb_want ) );
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001942
1943 /*
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001944 * Done if we already have enough data.
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001945 */
1946 if( nb_want <= ssl->in_left)
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02001947 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001948 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001949 return( 0 );
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02001950 }
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001951
1952 /*
Antonin Décimo36e89b52019-01-23 15:24:37 +01001953 * A record can't be split across datagrams. If we need to read but
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001954 * are not at the beginning of a new record, the caller did something
1955 * wrong.
1956 */
1957 if( ssl->in_left != 0 )
1958 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001959 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
1960 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001961 }
1962
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001963 /*
1964 * Don't even try to read if time's out already.
1965 * This avoids by-passing the timer when repeatedly receiving messages
1966 * that will end up being dropped.
1967 */
Hanno Becker7876d122020-02-05 10:39:31 +00001968 if( mbedtls_ssl_check_timer( ssl ) != 0 )
Hanno Beckere65ce782017-05-22 14:47:48 +01001969 {
1970 MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01001971 ret = MBEDTLS_ERR_SSL_TIMEOUT;
Hanno Beckere65ce782017-05-22 14:47:48 +01001972 }
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02001973 else
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02001974 {
Darryl Greenb33cc762019-11-28 14:29:44 +00001975 len = in_buf_len - ( ssl->in_hdr - ssl->in_buf );
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001978 timeout = ssl->handshake->retransmit_timeout;
1979 else
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001980 timeout = ssl->conf->read_timeout;
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001981
Paul Elliott9f352112020-12-09 14:55:45 +00001982 MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %lu ms", (unsigned long) timeout ) );
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001983
Manuel Pégourié-Gonnard07617332015-06-24 23:00:03 +02001984 if( ssl->f_recv_timeout != NULL )
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001985 ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
1986 timeout );
1987 else
1988 ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
1989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001990 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001991
1992 if( ret == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993 return( MBEDTLS_ERR_SSL_CONN_EOF );
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001994 }
1995
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01001996 if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001997 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998 MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
Hanno Becker0f57a652020-02-05 10:37:26 +00001999 mbedtls_ssl_set_timer( ssl, 0 );
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02002000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +02002002 {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02002003 if( ssl_double_retransmit_timeout( ssl ) != 0 )
2004 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002005 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002006 return( MBEDTLS_ERR_SSL_TIMEOUT );
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02002007 }
2008
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02002010 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002011 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02002012 return( ret );
2013 }
2014
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002015 return( MBEDTLS_ERR_SSL_WANT_READ );
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +02002016 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002018 else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002020 {
Hanno Becker786300f2020-02-05 10:46:40 +00002021 if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002022 {
Hanno Becker786300f2020-02-05 10:46:40 +00002023 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
2024 ret );
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002025 return( ret );
2026 }
2027
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002028 return( MBEDTLS_ERR_SSL_WANT_READ );
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02002029 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002030#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02002031 }
2032
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 if( ret < 0 )
2034 return( ret );
2035
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002036 ssl->in_left = ret;
2037 }
2038 else
2039#endif
2040 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00002041 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
2042 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02002043 ssl->in_left, nb_want ) );
2044
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002045 while( ssl->in_left < nb_want )
2046 {
2047 len = nb_want - ssl->in_left;
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02002048
Hanno Becker7876d122020-02-05 10:39:31 +00002049 if( mbedtls_ssl_check_timer( ssl ) != 0 )
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02002050 ret = MBEDTLS_ERR_SSL_TIMEOUT;
2051 else
Manuel Pégourié-Gonnard07617332015-06-24 23:00:03 +02002052 {
2053 if( ssl->f_recv_timeout != NULL )
2054 {
2055 ret = ssl->f_recv_timeout( ssl->p_bio,
2056 ssl->in_hdr + ssl->in_left, len,
2057 ssl->conf->read_timeout );
2058 }
2059 else
2060 {
2061 ret = ssl->f_recv( ssl->p_bio,
2062 ssl->in_hdr + ssl->in_left, len );
2063 }
2064 }
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002065
Paul Elliottd48d5c62021-01-07 14:47:05 +00002066 MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
2067 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnard07617332015-06-24 23:00:03 +02002068 ssl->in_left, nb_want ) );
2069 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002070
2071 if( ret == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002072 return( MBEDTLS_ERR_SSL_CONN_EOF );
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002073
2074 if( ret < 0 )
2075 return( ret );
2076
makise-homuraaf9513b2020-08-24 18:26:27 +03002077 if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
mohammad16035bd15cb2018-02-28 04:30:59 -08002078 {
Darryl Green11999bb2018-03-13 15:22:58 +00002079 MBEDTLS_SSL_DEBUG_MSG( 1,
Paul Elliottd48d5c62021-01-07 14:47:05 +00002080 ( "f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " were requested",
Paul Elliott9f352112020-12-09 14:55:45 +00002081 ret, len ) );
mohammad16035bd15cb2018-02-28 04:30:59 -08002082 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2083 }
2084
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01002085 ssl->in_left += ret;
2086 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002087 }
2088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
2091 return( 0 );
2092}
2093
2094/*
2095 * Flush any data not yet written
2096 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002098{
Janos Follath865b3eb2019-12-16 11:46:15 +00002099 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker04484622018-08-06 09:49:38 +01002100 unsigned char *buf;
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002102 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002103
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02002104 if( ssl->f_send == NULL )
2105 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002106 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
Manuel Pégourié-Gonnard1b511f92015-05-06 15:54:23 +01002107 "or mbedtls_ssl_set_bio()" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002108 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02002109 }
2110
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01002111 /* Avoid incrementing counter if data is flushed */
2112 if( ssl->out_left == 0 )
2113 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002114 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01002115 return( 0 );
2116 }
2117
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 while( ssl->out_left > 0 )
2119 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00002120 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %" MBEDTLS_PRINTF_SIZET
2121 ", out_left: %" MBEDTLS_PRINTF_SIZET,
Hanno Becker5903de42019-05-03 14:46:38 +01002122 mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002123
Hanno Becker2b1e3542018-08-06 11:19:13 +01002124 buf = ssl->out_hdr - ssl->out_left;
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02002125 ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
Paul Bakker186751d2012-05-08 13:16:14 +00002126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002127 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128
2129 if( ret <= 0 )
2130 return( ret );
2131
makise-homuraaf9513b2020-08-24 18:26:27 +03002132 if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX ) )
mohammad16034bbaeb42018-02-22 04:29:04 -08002133 {
Darryl Green11999bb2018-03-13 15:22:58 +00002134 MBEDTLS_SSL_DEBUG_MSG( 1,
Paul Elliottd48d5c62021-01-07 14:47:05 +00002135 ( "f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET " bytes were sent",
Paul Elliott9f352112020-12-09 14:55:45 +00002136 ret, ssl->out_left ) );
mohammad16034bbaeb42018-02-22 04:29:04 -08002137 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2138 }
2139
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 ssl->out_left -= ret;
2141 }
2142
Hanno Becker2b1e3542018-08-06 11:19:13 +01002143#if defined(MBEDTLS_SSL_PROTO_DTLS)
2144 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01002145 {
Hanno Becker2b1e3542018-08-06 11:19:13 +01002146 ssl->out_hdr = ssl->out_buf;
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01002147 }
Hanno Becker2b1e3542018-08-06 11:19:13 +01002148 else
2149#endif
2150 {
2151 ssl->out_hdr = ssl->out_buf + 8;
2152 }
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00002153 mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01002154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002156
2157 return( 0 );
2158}
2159
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002160/*
2161 * Functions to handle the DTLS retransmission state machine
2162 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002163#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002164/*
2165 * Append current handshake message to current outgoing flight
2166 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002167MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168static int ssl_flight_append( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002169{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002170 mbedtls_ssl_flight_item *msg;
Hanno Becker3b235902018-08-06 09:54:53 +01002171 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
2172 MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
2173 ssl->out_msg, ssl->out_msglen );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002174
2175 /* Allocate space for current message */
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02002176 if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002177 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00002178 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179 sizeof( mbedtls_ssl_flight_item ) ) );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02002180 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002181 }
2182
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02002183 if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002184 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00002185 MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
2186 ssl->out_msglen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187 mbedtls_free( msg );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +02002188 return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002189 }
2190
2191 /* Copy current handshake message with headers */
2192 memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
2193 msg->len = ssl->out_msglen;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002194 msg->type = ssl->out_msgtype;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002195 msg->next = NULL;
2196
2197 /* Append to the current flight */
2198 if( ssl->handshake->flight == NULL )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002199 ssl->handshake->flight = msg;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002200 else
2201 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002202 mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002203 while( cur->next != NULL )
2204 cur = cur->next;
2205 cur->next = msg;
2206 }
2207
Hanno Becker3b235902018-08-06 09:54:53 +01002208 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002209 return( 0 );
2210}
2211
2212/*
2213 * Free the current flight of handshake messages
2214 */
Hanno Becker533ab5f2020-02-05 10:49:13 +00002215void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002216{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002217 mbedtls_ssl_flight_item *cur = flight;
2218 mbedtls_ssl_flight_item *next;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002219
2220 while( cur != NULL )
2221 {
2222 next = cur->next;
2223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002224 mbedtls_free( cur->p );
2225 mbedtls_free( cur );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002226
2227 cur = next;
2228 }
2229}
2230
2231/*
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002232 * Swap transform_out and out_ctr with the alternative ones
2233 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002234MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002235static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002236{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002237 mbedtls_ssl_transform *tmp_transform;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002238 unsigned char tmp_out_ctr[8];
2239
2240 if( ssl->transform_out == ssl->handshake->alt_transform_out )
2241 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242 MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002243 return( 0 );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002244 }
2245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246 MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002247
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002248 /* Swap transforms */
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002249 tmp_transform = ssl->transform_out;
2250 ssl->transform_out = ssl->handshake->alt_transform_out;
2251 ssl->handshake->alt_transform_out = tmp_transform;
2252
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002253 /* Swap epoch + sequence_number */
Hanno Becker19859472018-08-06 09:40:20 +01002254 memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
2255 memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002256 memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002257
2258 /* Adjust to the newly activated transform */
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00002259 mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002261#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
2262 if( mbedtls_ssl_hw_record_activate != NULL )
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002263 {
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002264 int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND );
2265 if( ret != 0 )
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002266 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002267 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
2268 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002269 }
2270 }
2271#endif
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002272
2273 return( 0 );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002274}
2275
2276/*
2277 * Retransmit the current flight of messages.
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002278 */
2279int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
2280{
2281 int ret = 0;
2282
2283 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
2284
2285 ret = mbedtls_ssl_flight_transmit( ssl );
2286
2287 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
2288
2289 return( ret );
2290}
2291
2292/*
2293 * Transmit or retransmit the current flight of messages.
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002294 *
2295 * Need to remember the current message in case flush_output returns
2296 * WANT_WRITE, causing us to exit this function and come back later.
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002297 * This function must be called until state is no longer SENDING.
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002298 */
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002299int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002300{
Janos Follath865b3eb2019-12-16 11:46:15 +00002301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002302 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002303
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002304 if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002305 {
Manuel Pégourié-Gonnard19c62f92018-08-16 10:50:39 +02002306 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002307
2308 ssl->handshake->cur_msg = ssl->handshake->flight;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002309 ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002310 ret = ssl_swap_epochs( ssl );
2311 if( ret != 0 )
2312 return( ret );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002314 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002315 }
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002316
2317 while( ssl->handshake->cur_msg != NULL )
2318 {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002319 size_t max_frag_len;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002320 const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002321
Hanno Beckere1dcb032018-08-17 16:47:58 +01002322 int const is_finished =
2323 ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
2324 cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
2325
Hanno Becker04da1892018-08-14 13:22:10 +01002326 uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
2327 SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
2328
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002329 /* Swap epochs before sending Finished: we can't do it after
2330 * sending ChangeCipherSpec, in case write returns WANT_READ.
2331 * Must be done before copying, may change out_msg pointer */
Hanno Beckere1dcb032018-08-17 16:47:58 +01002332 if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002333 {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002334 MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002335 ret = ssl_swap_epochs( ssl );
2336 if( ret != 0 )
2337 return( ret );
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002338 }
2339
Hanno Becker67bc7c32018-08-06 11:33:50 +01002340 ret = ssl_get_remaining_payload_in_datagram( ssl );
2341 if( ret < 0 )
2342 return( ret );
2343 max_frag_len = (size_t) ret;
2344
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002345 /* CCS is copied as is, while HS messages may need fragmentation */
2346 if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
2347 {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002348 if( max_frag_len == 0 )
2349 {
2350 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2351 return( ret );
2352
2353 continue;
2354 }
2355
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002356 memcpy( ssl->out_msg, cur->p, cur->len );
Hanno Becker67bc7c32018-08-06 11:33:50 +01002357 ssl->out_msglen = cur->len;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002358 ssl->out_msgtype = cur->type;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002359
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002360 /* Update position inside current message */
2361 ssl->handshake->cur_msg_p += cur->len;
2362 }
2363 else
2364 {
2365 const unsigned char * const p = ssl->handshake->cur_msg_p;
2366 const size_t hs_len = cur->len - 12;
2367 const size_t frag_off = p - ( cur->p + 12 );
2368 const size_t rem_len = hs_len - frag_off;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002369 size_t cur_hs_frag_len, max_hs_frag_len;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002370
Hanno Beckere1dcb032018-08-17 16:47:58 +01002371 if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
Manuel Pégourié-Gonnarda1071a52018-08-20 11:56:14 +02002372 {
Hanno Beckere1dcb032018-08-17 16:47:58 +01002373 if( is_finished )
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002374 {
2375 ret = ssl_swap_epochs( ssl );
2376 if( ret != 0 )
2377 return( ret );
2378 }
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002379
Hanno Becker67bc7c32018-08-06 11:33:50 +01002380 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2381 return( ret );
2382
2383 continue;
2384 }
2385 max_hs_frag_len = max_frag_len - 12;
2386
2387 cur_hs_frag_len = rem_len > max_hs_frag_len ?
2388 max_hs_frag_len : rem_len;
2389
2390 if( frag_off == 0 && cur_hs_frag_len != hs_len )
Manuel Pégourié-Gonnard19c62f92018-08-16 10:50:39 +02002391 {
2392 MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
Hanno Becker67bc7c32018-08-06 11:33:50 +01002393 (unsigned) cur_hs_frag_len,
2394 (unsigned) max_hs_frag_len ) );
Manuel Pégourié-Gonnard19c62f92018-08-16 10:50:39 +02002395 }
Manuel Pégourié-Gonnardb747c6c2018-08-12 13:28:53 +02002396
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002397 /* Messages are stored with handshake headers as if not fragmented,
2398 * copy beginning of headers then fill fragmentation fields.
2399 * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
2400 memcpy( ssl->out_msg, cur->p, 6 );
Joe Subbiani61f7d732021-06-24 09:06:23 +01002401
Joe Subbiani2bbafda2021-06-24 13:00:03 +01002402 ssl->out_msg[6] = MBEDTLS_BYTE_2( frag_off );
2403 ssl->out_msg[7] = MBEDTLS_BYTE_1( frag_off );
2404 ssl->out_msg[8] = MBEDTLS_BYTE_0( frag_off );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002405
Joe Subbiani2bbafda2021-06-24 13:00:03 +01002406 ssl->out_msg[ 9] = MBEDTLS_BYTE_2( cur_hs_frag_len );
2407 ssl->out_msg[10] = MBEDTLS_BYTE_1( cur_hs_frag_len );
2408 ssl->out_msg[11] = MBEDTLS_BYTE_0( cur_hs_frag_len );
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002409
2410 MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
2411
Hanno Becker3f7b9732018-08-28 09:53:25 +01002412 /* Copy the handshake message content and set records fields */
Hanno Becker67bc7c32018-08-06 11:33:50 +01002413 memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
2414 ssl->out_msglen = cur_hs_frag_len + 12;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002415 ssl->out_msgtype = cur->type;
2416
2417 /* Update position inside current message */
Hanno Becker67bc7c32018-08-06 11:33:50 +01002418 ssl->handshake->cur_msg_p += cur_hs_frag_len;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002419 }
2420
2421 /* If done with the current message move to the next one if any */
2422 if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
2423 {
2424 if( cur->next != NULL )
2425 {
2426 ssl->handshake->cur_msg = cur->next;
2427 ssl->handshake->cur_msg_p = cur->next->p + 12;
2428 }
2429 else
2430 {
2431 ssl->handshake->cur_msg = NULL;
2432 ssl->handshake->cur_msg_p = NULL;
2433 }
2434 }
2435
2436 /* Actually send the message out */
Hanno Becker04da1892018-08-14 13:22:10 +01002437 if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002438 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002439 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002440 return( ret );
2441 }
2442 }
2443
Hanno Becker67bc7c32018-08-06 11:33:50 +01002444 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
2445 return( ret );
2446
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002447 /* Update state and set timer */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002448 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
2449 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Manuel Pégourié-Gonnard23b7b702014-09-25 13:50:12 +02002450 else
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02002451 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002452 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Hanno Becker0f57a652020-02-05 10:37:26 +00002453 mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02002454 }
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002455
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002456 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002457
2458 return( 0 );
2459}
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002460
2461/*
2462 * To be called when the last message of an incoming flight is received.
2463 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002464void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002465{
2466 /* We won't need to resend that one any more */
Hanno Becker533ab5f2020-02-05 10:49:13 +00002467 mbedtls_ssl_flight_free( ssl->handshake->flight );
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002468 ssl->handshake->flight = NULL;
2469 ssl->handshake->cur_msg = NULL;
2470
2471 /* The next incoming flight will start with this msg_seq */
2472 ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
2473
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01002474 /* We don't want to remember CCS's across flight boundaries. */
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01002475 ssl->handshake->buffering.seen_ccs = 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01002476
Hanno Becker0271f962018-08-16 13:23:47 +01002477 /* Clear future message buffering structure. */
Hanno Becker533ab5f2020-02-05 10:49:13 +00002478 mbedtls_ssl_buffering_free( ssl );
Hanno Becker0271f962018-08-16 13:23:47 +01002479
Manuel Pégourié-Gonnard6c1fa3a2014-10-01 16:58:16 +02002480 /* Cancel timer */
Hanno Becker0f57a652020-02-05 10:37:26 +00002481 mbedtls_ssl_set_timer( ssl, 0 );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002483 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2484 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002485 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002486 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002487 }
2488 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002489 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002490}
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002491
2492/*
2493 * To be called when the last message of an outgoing flight is send.
2494 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002496{
Manuel Pégourié-Gonnard6c1fa3a2014-10-01 16:58:16 +02002497 ssl_reset_retransmit_timeout( ssl );
Hanno Becker0f57a652020-02-05 10:37:26 +00002498 mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002500 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2501 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002502 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002503 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002504 }
2505 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002506 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002507}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002508#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002509
Paul Bakker5121ce52009-01-03 21:22:43 +00002510/*
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002511 * Handshake layer functions
Paul Bakker5121ce52009-01-03 21:22:43 +00002512 */
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002513
2514/*
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002515 * Write (DTLS: or queue) current handshake (including CCS) message.
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002516 *
2517 * - fill in handshake headers
2518 * - update handshake checksum
2519 * - DTLS: save message for resending
2520 * - then pass to the record layer
2521 *
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002522 * DTLS: except for HelloRequest, messages are only queued, and will only be
2523 * actually sent when calling flight_transmit() or resend().
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002524 *
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002525 * Inputs:
2526 * - ssl->out_msglen: 4 + actual handshake message len
2527 * (4 is the size of handshake headers for TLS)
2528 * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
2529 * - ssl->out_msg + 4: the handshake message body
2530 *
Manuel Pégourié-Gonnard065a2a32018-08-20 11:09:26 +02002531 * Outputs, ie state before passing to flight_append() or write_record():
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002532 * - ssl->out_msglen: the length of the record contents
2533 * (including handshake headers but excluding record headers)
2534 * - ssl->out_msg: the record contents (handshake headers + content)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002535 */
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002536int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00002537{
Janos Follath865b3eb2019-12-16 11:46:15 +00002538 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002539 const size_t hs_len = ssl->out_msglen - 4;
2540 const unsigned char hs_type = ssl->out_msg[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00002541
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002542 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
2543
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002544 /*
2545 * Sanity checks
2546 */
Hanno Beckerc83d2b32018-08-22 16:05:47 +01002547 if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002548 ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
2549 {
Hanno Beckerc83d2b32018-08-22 16:05:47 +01002550 /* In SSLv3, the client might send a NoCertificate alert. */
2551#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
2552 if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
2553 ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
2554 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
2555#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
2556 {
2557 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2558 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2559 }
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002560 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002561
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002562 /* Whenever we send anything different from a
2563 * HelloRequest we should be in a handshake - double check. */
2564 if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2565 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002566 ssl->handshake == NULL )
2567 {
2568 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2569 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2570 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002572#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002573 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002574 ssl->handshake != NULL &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002575 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002576 {
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002577 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2578 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002579 }
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002580#endif
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002581
Hanno Beckerb50a2532018-08-06 11:52:54 +01002582 /* Double-check that we did not exceed the bounds
2583 * of the outgoing record buffer.
2584 * This should never fail as the various message
2585 * writing functions must obey the bounds of the
2586 * outgoing record buffer, but better be safe.
2587 *
2588 * Note: We deliberately do not check for the MTU or MFL here.
2589 */
2590 if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
2591 {
2592 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
Paul Elliottd48d5c62021-01-07 14:47:05 +00002593 "size %" MBEDTLS_PRINTF_SIZET
2594 ", maximum %" MBEDTLS_PRINTF_SIZET,
Paul Elliott3891caf2020-12-17 18:42:40 +00002595 ssl->out_msglen,
2596 (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
Hanno Beckerb50a2532018-08-06 11:52:54 +01002597 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2598 }
2599
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002600 /*
2601 * Fill handshake headers
2602 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002603 if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002604 {
Joe Subbianiad1115a2021-07-16 14:27:50 +01002605 ssl->out_msg[1] = MBEDTLS_BYTE_2( hs_len );
2606 ssl->out_msg[2] = MBEDTLS_BYTE_1( hs_len );
2607 ssl->out_msg[3] = MBEDTLS_BYTE_0( hs_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00002608
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002609 /*
2610 * DTLS has additional fields in the Handshake layer,
2611 * between the length field and the actual payload:
2612 * uint16 message_seq;
2613 * uint24 fragment_offset;
2614 * uint24 fragment_length;
2615 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002616#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002617 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002618 {
Manuel Pégourié-Gonnarde89bcf02014-02-18 18:50:02 +01002619 /* Make room for the additional DTLS fields */
Angus Grattond8213d02016-05-25 20:56:48 +10002620 if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
Hanno Becker9648f8b2017-09-18 10:55:54 +01002621 {
2622 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
Paul Elliottd48d5c62021-01-07 14:47:05 +00002623 "size %" MBEDTLS_PRINTF_SIZET ", maximum %" MBEDTLS_PRINTF_SIZET,
Paul Elliott3891caf2020-12-17 18:42:40 +00002624 hs_len,
2625 (size_t) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
Hanno Becker9648f8b2017-09-18 10:55:54 +01002626 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
2627 }
2628
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002629 memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002630 ssl->out_msglen += 8;
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002631
Manuel Pégourié-Gonnardc392b242014-08-19 17:53:11 +02002632 /* Write message_seq and update it, except for HelloRequest */
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002633 if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
Manuel Pégourié-Gonnardc392b242014-08-19 17:53:11 +02002634 {
Joe Subbianic54e9082021-07-19 11:56:54 +01002635 MBEDTLS_PUT_UINT16_BE( ssl->handshake->out_msg_seq, ssl->out_msg, 4 );
Manuel Pégourié-Gonnardd9ba0d92014-09-02 18:30:26 +02002636 ++( ssl->handshake->out_msg_seq );
Manuel Pégourié-Gonnardc392b242014-08-19 17:53:11 +02002637 }
2638 else
2639 {
2640 ssl->out_msg[4] = 0;
2641 ssl->out_msg[5] = 0;
2642 }
Manuel Pégourié-Gonnarde89bcf02014-02-18 18:50:02 +01002643
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002644 /* Handshake hashes are computed without fragmentation,
2645 * so set frag_offset = 0 and frag_len = hs_len for now */
Manuel Pégourié-Gonnarde89bcf02014-02-18 18:50:02 +01002646 memset( ssl->out_msg + 6, 0x00, 3 );
2647 memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002648 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002649#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002650
Hanno Becker0207e532018-08-28 10:28:28 +01002651 /* Update running hashes of handshake messages seen */
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002652 if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
2653 ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
Paul Bakker5121ce52009-01-03 21:22:43 +00002654 }
2655
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002656 /* Either send now, or just save to be sent (and resent) later */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002657#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002658 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002659 ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2660 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002661 {
2662 if( ( ret = ssl_flight_append( ssl ) ) != 0 )
2663 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002664 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002665 return( ret );
2666 }
2667 }
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002668 else
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002669#endif
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002670 {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002671 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002672 {
2673 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
2674 return( ret );
2675 }
2676 }
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002677
2678 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
2679
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002680 return( 0 );
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002681}
2682
2683/*
2684 * Record layer functions
2685 */
2686
2687/*
2688 * Write current record.
2689 *
2690 * Uses:
2691 * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
2692 * - ssl->out_msglen: length of the record content (excl headers)
2693 * - ssl->out_msg: record content
2694 */
Hanno Becker67bc7c32018-08-06 11:33:50 +01002695int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002696{
2697 int ret, done = 0;
2698 size_t len = ssl->out_msglen;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002699 uint8_t flush = force_flush;
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002700
2701 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002702
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002703#if defined(MBEDTLS_ZLIB_SUPPORT)
Paul Bakker48916f92012-09-16 19:57:18 +00002704 if( ssl->transform_out != NULL &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002705 ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
Paul Bakker2770fbd2012-07-03 13:30:23 +00002706 {
2707 if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
2708 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002709 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
Paul Bakker2770fbd2012-07-03 13:30:23 +00002710 return( ret );
2711 }
2712
2713 len = ssl->out_msglen;
2714 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002715#endif /*MBEDTLS_ZLIB_SUPPORT */
Paul Bakker2770fbd2012-07-03 13:30:23 +00002716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002717#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
2718 if( mbedtls_ssl_hw_record_write != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00002719 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002720 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002722 ret = mbedtls_ssl_hw_record_write( ssl );
2723 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
Paul Bakker05ef8352012-05-08 09:17:57 +00002724 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002725 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
2726 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
Paul Bakker05ef8352012-05-08 09:17:57 +00002727 }
Paul Bakkerc7878112012-12-19 14:41:14 +01002728
2729 if( ret == 0 )
2730 done = 1;
Paul Bakker05ef8352012-05-08 09:17:57 +00002731 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002732#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
Paul Bakker05ef8352012-05-08 09:17:57 +00002733 if( !done )
2734 {
Hanno Becker2b1e3542018-08-06 11:19:13 +01002735 unsigned i;
2736 size_t protected_record_size;
Darryl Greenb33cc762019-11-28 14:29:44 +00002737#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2738 size_t out_buf_len = ssl->out_buf_len;
2739#else
2740 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
2741#endif
Hanno Becker6430faf2019-05-08 11:57:13 +01002742 /* Skip writing the record content type to after the encryption,
2743 * as it may change when using the CID extension. */
2744
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002745 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02002746 ssl->conf->transport, ssl->out_hdr + 1 );
Manuel Pégourié-Gonnard507e1e42014-02-13 11:17:34 +01002747
Hanno Becker19859472018-08-06 09:40:20 +01002748 memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
Joe Subbianic54e9082021-07-19 11:56:54 +01002749 MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
Paul Bakker05ef8352012-05-08 09:17:57 +00002750
Paul Bakker48916f92012-09-16 19:57:18 +00002751 if( ssl->transform_out != NULL )
Paul Bakker05ef8352012-05-08 09:17:57 +00002752 {
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002753 mbedtls_record rec;
2754
2755 rec.buf = ssl->out_iv;
Darryl Greenb33cc762019-11-28 14:29:44 +00002756 rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf );
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002757 rec.data_len = ssl->out_msglen;
2758 rec.data_offset = ssl->out_msg - rec.buf;
2759
2760 memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
2761 mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
2762 ssl->conf->transport, rec.ver );
2763 rec.type = ssl->out_msgtype;
2764
Hanno Beckera0e20d02019-05-15 14:03:01 +01002765#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker43c24b82019-05-01 09:45:57 +01002766 /* The CID is set by mbedtls_ssl_encrypt_buf(). */
Hanno Beckercab87e62019-04-29 13:52:53 +01002767 rec.cid_len = 0;
Hanno Beckera0e20d02019-05-15 14:03:01 +01002768#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +01002769
Hanno Beckera18d1322018-01-03 14:27:32 +00002770 if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002771 ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
Paul Bakker05ef8352012-05-08 09:17:57 +00002772 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002773 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
Paul Bakker05ef8352012-05-08 09:17:57 +00002774 return( ret );
2775 }
2776
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002777 if( rec.data_offset != 0 )
2778 {
2779 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
2780 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2781 }
2782
Hanno Becker6430faf2019-05-08 11:57:13 +01002783 /* Update the record content type and CID. */
2784 ssl->out_msgtype = rec.type;
Hanno Beckera0e20d02019-05-15 14:03:01 +01002785#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01002786 memcpy( ssl->out_cid, rec.cid, rec.cid_len );
Hanno Beckera0e20d02019-05-15 14:03:01 +01002787#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker78f839d2019-03-14 12:56:23 +00002788 ssl->out_msglen = len = rec.data_len;
Joe Subbianic54e9082021-07-19 11:56:54 +01002789 MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->out_len, 0 );
Paul Bakker05ef8352012-05-08 09:17:57 +00002790 }
2791
Hanno Becker5903de42019-05-03 14:46:38 +01002792 protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
Hanno Becker2b1e3542018-08-06 11:19:13 +01002793
2794#if defined(MBEDTLS_SSL_PROTO_DTLS)
2795 /* In case of DTLS, double-check that we don't exceed
2796 * the remaining space in the datagram. */
2797 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
2798 {
Hanno Becker554b0af2018-08-22 20:33:41 +01002799 ret = ssl_get_remaining_space_in_datagram( ssl );
Hanno Becker2b1e3542018-08-06 11:19:13 +01002800 if( ret < 0 )
2801 return( ret );
2802
2803 if( protected_record_size > (size_t) ret )
2804 {
2805 /* Should never happen */
2806 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
2807 }
2808 }
2809#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker05ef8352012-05-08 09:17:57 +00002810
Hanno Becker6430faf2019-05-08 11:57:13 +01002811 /* Now write the potentially updated record content type. */
2812 ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
2813
Paul Elliott9f352112020-12-09 14:55:45 +00002814 MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %u, "
Paul Elliottd48d5c62021-01-07 14:47:05 +00002815 "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
Hanno Beckerecbdf1c2018-08-28 09:53:54 +01002816 ssl->out_hdr[0], ssl->out_hdr[1],
2817 ssl->out_hdr[2], len ) );
Paul Bakker05ef8352012-05-08 09:17:57 +00002818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002819 MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
Hanno Beckerecbdf1c2018-08-28 09:53:54 +01002820 ssl->out_hdr, protected_record_size );
Hanno Becker2b1e3542018-08-06 11:19:13 +01002821
2822 ssl->out_left += protected_record_size;
2823 ssl->out_hdr += protected_record_size;
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00002824 mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
Hanno Becker2b1e3542018-08-06 11:19:13 +01002825
Hanno Beckerdd772292020-02-05 10:38:31 +00002826 for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
Hanno Becker04484622018-08-06 09:49:38 +01002827 if( ++ssl->cur_out_ctr[i - 1] != 0 )
2828 break;
2829
2830 /* The loop goes to its end iff the counter is wrapping */
Hanno Beckerdd772292020-02-05 10:38:31 +00002831 if( i == mbedtls_ssl_ep_len( ssl ) )
Hanno Becker04484622018-08-06 09:49:38 +01002832 {
2833 MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
2834 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
2835 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002836 }
2837
Hanno Becker67bc7c32018-08-06 11:33:50 +01002838#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker47db8772018-08-21 13:32:13 +01002839 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2840 flush == SSL_DONT_FORCE_FLUSH )
Hanno Becker67bc7c32018-08-06 11:33:50 +01002841 {
Hanno Becker1f5a15d2018-08-21 13:31:31 +01002842 size_t remaining;
2843 ret = ssl_get_remaining_payload_in_datagram( ssl );
2844 if( ret < 0 )
2845 {
2846 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
2847 ret );
2848 return( ret );
2849 }
2850
2851 remaining = (size_t) ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002852 if( remaining == 0 )
Hanno Beckerf0da6672018-08-28 09:55:10 +01002853 {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002854 flush = SSL_FORCE_FLUSH;
Hanno Beckerf0da6672018-08-28 09:55:10 +01002855 }
Hanno Becker67bc7c32018-08-06 11:33:50 +01002856 else
2857 {
Hanno Becker513815a2018-08-20 11:56:09 +01002858 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
Hanno Becker67bc7c32018-08-06 11:33:50 +01002859 }
2860 }
2861#endif /* MBEDTLS_SSL_PROTO_DTLS */
2862
2863 if( ( flush == SSL_FORCE_FLUSH ) &&
2864 ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002865 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002866 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002867 return( ret );
2868 }
2869
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002870 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002871
2872 return( 0 );
2873}
2874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002875#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Beckere25e3b72018-08-16 09:30:53 +01002876
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002877MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckere25e3b72018-08-16 09:30:53 +01002878static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
2879{
2880 if( ssl->in_msglen < ssl->in_hslen ||
2881 memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
2882 memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
2883 {
2884 return( 1 );
2885 }
2886 return( 0 );
2887}
Hanno Becker44650b72018-08-16 12:51:11 +01002888
Hanno Beckercd9dcda2018-08-28 17:18:56 +01002889static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
Hanno Becker44650b72018-08-16 12:51:11 +01002890{
2891 return( ( ssl->in_msg[9] << 16 ) |
2892 ( ssl->in_msg[10] << 8 ) |
2893 ssl->in_msg[11] );
2894}
2895
Hanno Beckercd9dcda2018-08-28 17:18:56 +01002896static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
Hanno Becker44650b72018-08-16 12:51:11 +01002897{
2898 return( ( ssl->in_msg[6] << 16 ) |
2899 ( ssl->in_msg[7] << 8 ) |
2900 ssl->in_msg[8] );
2901}
2902
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002903MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckercd9dcda2018-08-28 17:18:56 +01002904static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
Hanno Becker44650b72018-08-16 12:51:11 +01002905{
2906 uint32_t msg_len, frag_off, frag_len;
2907
2908 msg_len = ssl_get_hs_total_len( ssl );
2909 frag_off = ssl_get_hs_frag_off( ssl );
2910 frag_len = ssl_get_hs_frag_len( ssl );
2911
2912 if( frag_off > msg_len )
2913 return( -1 );
2914
2915 if( frag_len > msg_len - frag_off )
2916 return( -1 );
2917
2918 if( frag_len + 12 > ssl->in_msglen )
2919 return( -1 );
2920
2921 return( 0 );
2922}
2923
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002924/*
2925 * Mark bits in bitmask (used for DTLS HS reassembly)
2926 */
2927static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
2928{
2929 unsigned int start_bits, end_bits;
2930
2931 start_bits = 8 - ( offset % 8 );
2932 if( start_bits != 8 )
2933 {
2934 size_t first_byte_idx = offset / 8;
2935
Manuel Pégourié-Gonnardac030522014-09-02 14:23:40 +02002936 /* Special case */
2937 if( len <= start_bits )
2938 {
2939 for( ; len != 0; len-- )
2940 mask[first_byte_idx] |= 1 << ( start_bits - len );
2941
2942 /* Avoid potential issues with offset or len becoming invalid */
2943 return;
2944 }
2945
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002946 offset += start_bits; /* Now offset % 8 == 0 */
2947 len -= start_bits;
2948
2949 for( ; start_bits != 0; start_bits-- )
2950 mask[first_byte_idx] |= 1 << ( start_bits - 1 );
2951 }
2952
2953 end_bits = len % 8;
2954 if( end_bits != 0 )
2955 {
2956 size_t last_byte_idx = ( offset + len ) / 8;
2957
2958 len -= end_bits; /* Now len % 8 == 0 */
2959
2960 for( ; end_bits != 0; end_bits-- )
2961 mask[last_byte_idx] |= 1 << ( 8 - end_bits );
2962 }
2963
2964 memset( mask + offset / 8, 0xFF, len / 8 );
2965}
2966
2967/*
2968 * Check that bitmask is full
2969 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02002970MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002971static int ssl_bitmask_check( unsigned char *mask, size_t len )
2972{
2973 size_t i;
2974
2975 for( i = 0; i < len / 8; i++ )
2976 if( mask[i] != 0xFF )
2977 return( -1 );
2978
2979 for( i = 0; i < len % 8; i++ )
2980 if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
2981 return( -1 );
2982
2983 return( 0 );
2984}
2985
Hanno Becker56e205e2018-08-16 09:06:12 +01002986/* msg_len does not include the handshake header */
Hanno Becker65dc8852018-08-23 09:40:49 +01002987static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
Hanno Becker2a97b0e2018-08-21 15:47:49 +01002988 unsigned add_bitmap )
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002989{
Hanno Becker56e205e2018-08-16 09:06:12 +01002990 size_t alloc_len;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002991
Hanno Becker56e205e2018-08-16 09:06:12 +01002992 alloc_len = 12; /* Handshake header */
2993 alloc_len += msg_len; /* Content buffer */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002994
Hanno Beckerd07df862018-08-16 09:14:58 +01002995 if( add_bitmap )
2996 alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002997
Hanno Becker2a97b0e2018-08-21 15:47:49 +01002998 return( alloc_len );
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002999}
Hanno Becker56e205e2018-08-16 09:06:12 +01003000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003001#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003002
Hanno Beckercd9dcda2018-08-28 17:18:56 +01003003static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
Hanno Becker12555c62018-08-16 12:47:53 +01003004{
3005 return( ( ssl->in_msg[1] << 16 ) |
3006 ( ssl->in_msg[2] << 8 ) |
3007 ssl->in_msg[3] );
3008}
Hanno Beckere25e3b72018-08-16 09:30:53 +01003009
Simon Butcher99000142016-10-13 17:21:01 +01003010int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003011{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003012 if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
Manuel Pégourié-Gonnard9d1d7192014-09-03 11:01:14 +02003013 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00003014 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %" MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnard9d1d7192014-09-03 11:01:14 +02003015 ssl->in_msglen ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003016 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Manuel Pégourié-Gonnard9d1d7192014-09-03 11:01:14 +02003017 }
3018
Hanno Becker12555c62018-08-16 12:47:53 +01003019 ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003020
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003021 MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
Paul Elliottd48d5c62021-01-07 14:47:05 +00003022 " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01003023 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003025#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003026 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003027 {
Janos Follath865b3eb2019-12-16 11:46:15 +00003028 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003029 unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003030
Hanno Becker44650b72018-08-16 12:51:11 +01003031 if( ssl_check_hs_header( ssl ) != 0 )
3032 {
3033 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
3034 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3035 }
3036
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003037 if( ssl->handshake != NULL &&
Hanno Beckerc76c6192017-06-06 10:03:17 +01003038 ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
3039 recv_msg_seq != ssl->handshake->in_msg_seq ) ||
3040 ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
3041 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003042 {
Hanno Becker9e1ec222018-08-15 15:54:43 +01003043 if( recv_msg_seq > ssl->handshake->in_msg_seq )
3044 {
3045 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
3046 recv_msg_seq,
3047 ssl->handshake->in_msg_seq ) );
3048 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
3049 }
3050
Manuel Pégourié-Gonnardfc572dd2014-10-09 17:56:57 +02003051 /* Retransmit only on last message from previous flight, to avoid
3052 * too many retransmissions.
3053 * Besides, No sane server ever retransmits HelloVerifyRequest */
3054 if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003055 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02003056 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003057 MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
Paul Elliott9f352112020-12-09 14:55:45 +00003058 "message_seq = %u, start_of_flight = %u",
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02003059 recv_msg_seq,
3060 ssl->handshake->in_flight_start_seq ) );
3061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003062 if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02003063 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003064 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02003065 return( ret );
3066 }
3067 }
3068 else
3069 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003070 MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
Paul Elliott9f352112020-12-09 14:55:45 +00003071 "message_seq = %u, expected = %u",
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02003072 recv_msg_seq,
3073 ssl->handshake->in_msg_seq ) );
3074 }
3075
Hanno Becker90333da2017-10-10 11:27:13 +01003076 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003077 }
3078 /* Wait until message completion to increment in_msg_seq */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003079
Hanno Becker6d97ef52018-08-16 13:09:04 +01003080 /* Message reassembly is handled alongside buffering of future
3081 * messages; the commonality is that both handshake fragments and
Hanno Becker83ab41c2018-08-28 17:19:38 +01003082 * future messages cannot be forwarded immediately to the
Hanno Becker6d97ef52018-08-16 13:09:04 +01003083 * handshake logic layer. */
Hanno Beckere25e3b72018-08-16 09:30:53 +01003084 if( ssl_hs_is_proper_fragment( ssl ) == 1 )
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003085 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003086 MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
Hanno Becker6d97ef52018-08-16 13:09:04 +01003087 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003088 }
3089 }
3090 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003091#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02003092 /* With TLS we don't handle fragmentation (for now) */
3093 if( ssl->in_msglen < ssl->in_hslen )
3094 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003095 MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
3096 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003097 }
3098
Simon Butcher99000142016-10-13 17:21:01 +01003099 return( 0 );
3100}
3101
3102void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
3103{
Hanno Becker0271f962018-08-16 13:23:47 +01003104 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
Simon Butcher99000142016-10-13 17:21:01 +01003105
Hanno Becker0271f962018-08-16 13:23:47 +01003106 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
Manuel Pégourié-Gonnard14bf7062015-06-23 14:07:13 +02003107 {
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003108 ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
Manuel Pégourié-Gonnard14bf7062015-06-23 14:07:13 +02003109 }
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003110
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003111 /* Handshake message is complete, increment counter */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003112#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003113 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003114 ssl->handshake != NULL )
3115 {
Hanno Becker0271f962018-08-16 13:23:47 +01003116 unsigned offset;
3117 mbedtls_ssl_hs_buffer *hs_buf;
Hanno Beckere25e3b72018-08-16 09:30:53 +01003118
Hanno Becker0271f962018-08-16 13:23:47 +01003119 /* Increment handshake sequence number */
3120 hs->in_msg_seq++;
3121
3122 /*
3123 * Clear up handshake buffering and reassembly structure.
3124 */
3125
3126 /* Free first entry */
Hanno Beckere605b192018-08-21 15:59:07 +01003127 ssl_buffering_free_slot( ssl, 0 );
Hanno Becker0271f962018-08-16 13:23:47 +01003128
3129 /* Shift all other entries */
Hanno Beckere605b192018-08-21 15:59:07 +01003130 for( offset = 0, hs_buf = &hs->buffering.hs[0];
3131 offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
Hanno Becker0271f962018-08-16 13:23:47 +01003132 offset++, hs_buf++ )
3133 {
3134 *hs_buf = *(hs_buf + 1);
3135 }
3136
3137 /* Create a fresh last entry */
3138 memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02003139 }
3140#endif
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01003141}
3142
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003143/*
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003144 * DTLS anti-replay: RFC 6347 4.1.2.6
3145 *
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003146 * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
3147 * Bit n is set iff record number in_window_top - n has been seen.
3148 *
3149 * Usually, in_window_top is the last record number seen and the lsb of
3150 * in_window is set. The only exception is the initial state (record number 0
3151 * not seen yet).
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003152 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003153#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Hanno Becker7e8e6a62020-02-05 10:45:48 +00003154void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003155{
3156 ssl->in_window_top = 0;
3157 ssl->in_window = 0;
3158}
3159
3160static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
3161{
3162 return( ( (uint64_t) buf[0] << 40 ) |
3163 ( (uint64_t) buf[1] << 32 ) |
3164 ( (uint64_t) buf[2] << 24 ) |
3165 ( (uint64_t) buf[3] << 16 ) |
3166 ( (uint64_t) buf[4] << 8 ) |
3167 ( (uint64_t) buf[5] ) );
3168}
3169
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003170MBEDTLS_CHECK_RETURN_CRITICAL
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02003171static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
3172{
Janos Follath865b3eb2019-12-16 11:46:15 +00003173 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02003174 unsigned char *original_in_ctr;
3175
3176 // save original in_ctr
3177 original_in_ctr = ssl->in_ctr;
3178
3179 // use counter from record
3180 ssl->in_ctr = record_in_ctr;
3181
3182 ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl );
3183
3184 // restore the counter
3185 ssl->in_ctr = original_in_ctr;
3186
3187 return ret;
3188}
3189
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003190/*
3191 * Return 0 if sequence number is acceptable, -1 otherwise
3192 */
Hanno Becker0183d692019-07-12 08:50:37 +01003193int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl )
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003194{
3195 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
3196 uint64_t bit;
3197
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003198 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02003199 return( 0 );
3200
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003201 if( rec_seqnum > ssl->in_window_top )
3202 return( 0 );
3203
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003204 bit = ssl->in_window_top - rec_seqnum;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003205
3206 if( bit >= 64 )
3207 return( -1 );
3208
3209 if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
3210 return( -1 );
3211
3212 return( 0 );
3213}
3214
3215/*
3216 * Update replay window on new validated record
3217 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003218void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003219{
3220 uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
3221
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003222 if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02003223 return;
3224
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003225 if( rec_seqnum > ssl->in_window_top )
3226 {
3227 /* Update window_top and the contents of the window */
3228 uint64_t shift = rec_seqnum - ssl->in_window_top;
3229
3230 if( shift >= 64 )
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003231 ssl->in_window = 1;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003232 else
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003233 {
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003234 ssl->in_window <<= shift;
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003235 ssl->in_window |= 1;
3236 }
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003237
3238 ssl->in_window_top = rec_seqnum;
3239 }
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003240 else
3241 {
3242 /* Mark that number as seen in the current window */
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02003243 uint64_t bit = ssl->in_window_top - rec_seqnum;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003244
3245 if( bit < 64 ) /* Always true, but be extra sure */
3246 ssl->in_window |= (uint64_t) 1 << bit;
3247 }
3248}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003249#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003250
Manuel Pégourié-Gonnardddfe5d22015-09-09 12:46:16 +02003251#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003252/*
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003253 * Check if a datagram looks like a ClientHello with a valid cookie,
3254 * and if it doesn't, generate a HelloVerifyRequest message.
Simon Butcher0789aed2015-09-11 17:15:17 +01003255 * Both input and output include full DTLS headers.
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003256 *
3257 * - if cookie is valid, return 0
3258 * - if ClientHello looks superficially valid but cookie is not,
3259 * fill obuf and set olen, then
3260 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
3261 * - otherwise return a specific error code
3262 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003263MBEDTLS_CHECK_RETURN_CRITICAL
Andrzej Kurek33f41a82022-06-08 11:47:33 -04003264MBEDTLS_STATIC_TESTABLE
3265int mbedtls_ssl_check_dtls_clihlo_cookie(
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003266 mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003267 const unsigned char *cli_id, size_t cli_id_len,
3268 const unsigned char *in, size_t in_len,
3269 unsigned char *obuf, size_t buf_len, size_t *olen )
3270{
3271 size_t sid_len, cookie_len;
3272 unsigned char *p;
3273
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003274 /*
3275 * Structure of ClientHello with record and handshake headers,
3276 * and expected values. We don't need to check a lot, more checks will be
3277 * done when actually parsing the ClientHello - skipping those checks
3278 * avoids code duplication and does not make cookie forging any easier.
3279 *
3280 * 0-0 ContentType type; copied, must be handshake
3281 * 1-2 ProtocolVersion version; copied
3282 * 3-4 uint16 epoch; copied, must be 0
3283 * 5-10 uint48 sequence_number; copied
3284 * 11-12 uint16 length; (ignored)
3285 *
3286 * 13-13 HandshakeType msg_type; (ignored)
3287 * 14-16 uint24 length; (ignored)
3288 * 17-18 uint16 message_seq; copied
3289 * 19-21 uint24 fragment_offset; copied, must be 0
3290 * 22-24 uint24 fragment_length; (ignored)
3291 *
3292 * 25-26 ProtocolVersion client_version; (ignored)
3293 * 27-58 Random random; (ignored)
3294 * 59-xx SessionID session_id; 1 byte len + sid_len content
3295 * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
3296 * ...
3297 *
3298 * Minimum length is 61 bytes.
3299 */
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003300 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: in_len=%u",
3301 (unsigned) in_len ) );
3302 MBEDTLS_SSL_DEBUG_BUF( 4, "cli_id", cli_id, cli_id_len );
3303 if( in_len < 61 )
3304 {
3305 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: record too short" ) );
3306 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
3307 }
3308 if( in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003309 in[3] != 0 || in[4] != 0 ||
3310 in[19] != 0 || in[20] != 0 || in[21] != 0 )
3311 {
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003312 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: not a good ClientHello" ) );
3313 MBEDTLS_SSL_DEBUG_MSG( 4, ( " type=%u epoch=%u fragment_offset=%u",
3314 in[0],
3315 (unsigned) in[3] << 8 | in[4],
3316 (unsigned) in[19] << 16 | in[20] << 8 | in[21] ) );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003317 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
3318 }
3319
3320 sid_len = in[59];
Andrzej Kureke5af9fa2022-06-06 14:42:41 -04003321 if( 59 + 1 + sid_len + 1 > in_len )
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003322 {
3323 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: sid_len=%u > %u",
3324 (unsigned) sid_len,
3325 (unsigned) in_len - 61 ) );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003326 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003327 }
3328 MBEDTLS_SSL_DEBUG_BUF( 4, "sid received from network",
3329 in + 60, sid_len );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003330
3331 cookie_len = in[60 + sid_len];
Andrzej Kureke5af9fa2022-06-06 14:42:41 -04003332 if( 59 + 1 + sid_len + 1 + cookie_len > in_len )
3333 {
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003334 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: cookie_len=%u > %u",
3335 (unsigned) cookie_len,
Andrzej Kureke5af9fa2022-06-06 14:42:41 -04003336 (unsigned) ( in_len - sid_len - 61 ) ) );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003337 return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003338 }
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003339
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003340 MBEDTLS_SSL_DEBUG_BUF( 4, "cookie received from network",
3341 in + sid_len + 61, cookie_len );
3342 if( ssl->conf->f_cookie_check( ssl->conf->p_cookie,
3343 in + sid_len + 61, cookie_len,
3344 cli_id, cli_id_len ) == 0 )
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003345 {
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003346 MBEDTLS_SSL_DEBUG_MSG( 4, ( "check cookie: valid" ) );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003347 return( 0 );
3348 }
3349
3350 /*
3351 * If we get here, we've got an invalid cookie, let's prepare HVR.
3352 *
3353 * 0-0 ContentType type; copied
3354 * 1-2 ProtocolVersion version; copied
3355 * 3-4 uint16 epoch; copied
3356 * 5-10 uint48 sequence_number; copied
3357 * 11-12 uint16 length; olen - 13
3358 *
3359 * 13-13 HandshakeType msg_type; hello_verify_request
3360 * 14-16 uint24 length; olen - 25
3361 * 17-18 uint16 message_seq; copied
3362 * 19-21 uint24 fragment_offset; copied
3363 * 22-24 uint24 fragment_length; olen - 25
3364 *
3365 * 25-26 ProtocolVersion server_version; 0xfe 0xff
3366 * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
3367 *
3368 * Minimum length is 28.
3369 */
3370 if( buf_len < 28 )
3371 return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
3372
3373 /* Copy most fields and adapt others */
3374 memcpy( obuf, in, 25 );
3375 obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
3376 obuf[25] = 0xfe;
3377 obuf[26] = 0xff;
3378
3379 /* Generate and write actual cookie */
3380 p = obuf + 28;
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003381 if( ssl->conf->f_cookie_write( ssl->conf->p_cookie,
3382 &p, obuf + buf_len,
3383 cli_id, cli_id_len ) != 0 )
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003384 {
3385 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
3386 }
3387
3388 *olen = p - obuf;
3389
3390 /* Go back and fill length fields */
3391 obuf[27] = (unsigned char)( *olen - 28 );
3392
Joe Subbianiad1115a2021-07-16 14:27:50 +01003393 obuf[14] = obuf[22] = MBEDTLS_BYTE_2( *olen - 25 );
3394 obuf[15] = obuf[23] = MBEDTLS_BYTE_1( *olen - 25 );
3395 obuf[16] = obuf[24] = MBEDTLS_BYTE_0( *olen - 25 );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003396
Joe Subbianic54e9082021-07-19 11:56:54 +01003397 MBEDTLS_PUT_UINT16_BE( *olen - 13, obuf, 11 );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003398
3399 return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
3400}
3401
3402/*
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003403 * Handle possible client reconnect with the same UDP quadruplet
3404 * (RFC 6347 Section 4.2.8).
3405 *
3406 * Called by ssl_parse_record_header() in case we receive an epoch 0 record
3407 * that looks like a ClientHello.
3408 *
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003409 * - if the input looks like a ClientHello without cookies,
Manuel Pégourié-Gonnard824655c2020-03-11 12:51:42 +01003410 * send back HelloVerifyRequest, then return 0
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003411 * - if the input looks like a ClientHello with a valid cookie,
3412 * reset the session of the current context, and
Manuel Pégourié-Gonnardbe619c12015-09-08 11:21:21 +02003413 * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003414 * - if anything goes wrong, return a specific error code
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003415 *
Manuel Pégourié-Gonnard824655c2020-03-11 12:51:42 +01003416 * This function is called (through ssl_check_client_reconnect()) when an
3417 * unexpected record is found in ssl_get_next_record(), which will discard the
3418 * record if we return 0, and bubble up the return value otherwise (this
3419 * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
3420 * errors, and is the right thing to do in both cases).
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003421 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003422MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003423static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
3424{
Janos Follath865b3eb2019-12-16 11:46:15 +00003425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003426 size_t len;
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003427
Hanno Becker2fddd372019-07-10 14:37:41 +01003428 if( ssl->conf->f_cookie_write == NULL ||
3429 ssl->conf->f_cookie_check == NULL )
3430 {
3431 /* If we can't use cookies to verify reachability of the peer,
3432 * drop the record. */
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003433 MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, "
3434 "can't check reconnect validity" ) );
Hanno Becker2fddd372019-07-10 14:37:41 +01003435 return( 0 );
3436 }
3437
Andrzej Kurek33f41a82022-06-08 11:47:33 -04003438 ret = mbedtls_ssl_check_dtls_clihlo_cookie(
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003439 ssl,
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003440 ssl->cli_id, ssl->cli_id_len,
3441 ssl->in_buf, ssl->in_left,
Angus Grattond8213d02016-05-25 20:56:48 +10003442 ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003443
Andrzej Kurek33f41a82022-06-08 11:47:33 -04003444 MBEDTLS_SSL_DEBUG_RET( 2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret );
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003445
3446 if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003447 {
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003448 int send_ret;
3449 MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
3450 MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
3451 ssl->out_buf, len );
Brian J Murray1903fb32016-11-06 04:45:15 -08003452 /* Don't check write errors as we can't do anything here.
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003453 * If the error is permanent we'll catch it later,
3454 * if it's not, then hopefully it'll work next time. */
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003455 send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
3456 MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
3457 (void) send_ret;
3458
Manuel Pégourié-Gonnard824655c2020-03-11 12:51:42 +01003459 return( 0 );
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003460 }
3461
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003462 if( ret == 0 )
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003463 {
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003464 MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
Hanno Becker43aefe22020-02-05 10:44:56 +00003465 if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 )
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003466 {
3467 MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
3468 return( ret );
3469 }
3470
3471 return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003472 }
3473
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003474 return( ret );
3475}
Manuel Pégourié-Gonnardddfe5d22015-09-09 12:46:16 +02003476#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003477
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003478MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckerf661c9c2019-05-03 13:25:54 +01003479static int ssl_check_record_type( uint8_t record_type )
3480{
3481 if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
3482 record_type != MBEDTLS_SSL_MSG_ALERT &&
3483 record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
3484 record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
3485 {
3486 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3487 }
3488
3489 return( 0 );
3490}
3491
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003492/*
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003493 * ContentType type;
3494 * ProtocolVersion version;
3495 * uint16 epoch; // DTLS only
3496 * uint48 sequence_number; // DTLS only
3497 * uint16 length;
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003498 *
3499 * Return 0 if header looks sane (and, for DTLS, the record is expected)
Simon Butcher207990d2015-12-16 01:51:30 +00003500 * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003501 * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
3502 *
3503 * With DTLS, mbedtls_ssl_read_record() will:
Simon Butcher207990d2015-12-16 01:51:30 +00003504 * 1. proceed with the record if this function returns 0
3505 * 2. drop only the current record if this function returns UNEXPECTED_RECORD
3506 * 3. return CLIENT_RECONNECT if this function return that value
3507 * 4. drop the whole datagram if this function returns anything else.
3508 * Point 2 is needed when the peer is resending, and we have already received
3509 * the first record from a datagram but are still waiting for the others.
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003510 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003511MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker331de3d2019-07-12 11:10:16 +01003512static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
Hanno Beckere5e7e782019-07-11 12:29:35 +01003513 unsigned char *buf,
3514 size_t len,
3515 mbedtls_record *rec )
Paul Bakker5121ce52009-01-03 21:22:43 +00003516{
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01003517 int major_ver, minor_ver;
Paul Bakker5121ce52009-01-03 21:22:43 +00003518
Hanno Beckere5e7e782019-07-11 12:29:35 +01003519 size_t const rec_hdr_type_offset = 0;
3520 size_t const rec_hdr_type_len = 1;
Manuel Pégourié-Gonnard64dffc52014-09-02 13:39:16 +02003521
Hanno Beckere5e7e782019-07-11 12:29:35 +01003522 size_t const rec_hdr_version_offset = rec_hdr_type_offset +
3523 rec_hdr_type_len;
3524 size_t const rec_hdr_version_len = 2;
Paul Bakker5121ce52009-01-03 21:22:43 +00003525
Hanno Beckere5e7e782019-07-11 12:29:35 +01003526 size_t const rec_hdr_ctr_len = 8;
3527#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Beckerf5466252019-07-25 10:13:02 +01003528 uint32_t rec_epoch;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003529 size_t const rec_hdr_ctr_offset = rec_hdr_version_offset +
3530 rec_hdr_version_len;
3531
Hanno Beckera0e20d02019-05-15 14:03:01 +01003532#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckere5e7e782019-07-11 12:29:35 +01003533 size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset +
3534 rec_hdr_ctr_len;
Hanno Beckerf5466252019-07-25 10:13:02 +01003535 size_t rec_hdr_cid_len = 0;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003536#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3537#endif /* MBEDTLS_SSL_PROTO_DTLS */
3538
3539 size_t rec_hdr_len_offset; /* To be determined */
3540 size_t const rec_hdr_len_len = 2;
3541
3542 /*
3543 * Check minimum lengths for record header.
3544 */
3545
3546#if defined(MBEDTLS_SSL_PROTO_DTLS)
3547 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3548 {
3549 rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
3550 }
3551 else
3552#endif /* MBEDTLS_SSL_PROTO_DTLS */
3553 {
3554 rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
3555 }
3556
3557 if( len < rec_hdr_len_offset + rec_hdr_len_len )
3558 {
3559 MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u",
3560 (unsigned) len,
3561 (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) );
3562 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3563 }
3564
3565 /*
3566 * Parse and validate record content type
3567 */
3568
3569 rec->type = buf[ rec_hdr_type_offset ];
Hanno Beckere5e7e782019-07-11 12:29:35 +01003570
3571 /* Check record content type */
3572#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3573 rec->cid_len = 0;
3574
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003575 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Hanno Beckere5e7e782019-07-11 12:29:35 +01003576 ssl->conf->cid_len != 0 &&
3577 rec->type == MBEDTLS_SSL_MSG_CID )
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003578 {
3579 /* Shift pointers to account for record header including CID
3580 * struct {
3581 * ContentType special_type = tls12_cid;
3582 * ProtocolVersion version;
3583 * uint16 epoch;
3584 * uint48 sequence_number;
Hanno Becker8e55b0f2019-05-23 17:03:19 +01003585 * opaque cid[cid_length]; // Additional field compared to
3586 * // default DTLS record format
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003587 * uint16 length;
3588 * opaque enc_content[DTLSCiphertext.length];
3589 * } DTLSCiphertext;
3590 */
3591
3592 /* So far, we only support static CID lengths
3593 * fixed in the configuration. */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003594 rec_hdr_cid_len = ssl->conf->cid_len;
3595 rec_hdr_len_offset += rec_hdr_cid_len;
Hanno Beckere538d822019-07-10 14:50:10 +01003596
Hanno Beckere5e7e782019-07-11 12:29:35 +01003597 if( len < rec_hdr_len_offset + rec_hdr_len_len )
Hanno Beckere538d822019-07-10 14:50:10 +01003598 {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003599 MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u",
3600 (unsigned) len,
3601 (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) );
Hanno Becker59be60e2019-07-10 14:53:43 +01003602 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Hanno Beckere538d822019-07-10 14:50:10 +01003603 }
Hanno Beckere5e7e782019-07-11 12:29:35 +01003604
Manuel Pégourié-Gonnard7e821b52019-08-02 10:17:15 +02003605 /* configured CID len is guaranteed at most 255, see
3606 * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
3607 rec->cid_len = (uint8_t) rec_hdr_cid_len;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003608 memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len );
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003609 }
3610 else
Hanno Beckera0e20d02019-05-15 14:03:01 +01003611#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Manuel Pégourié-Gonnardedcbe542014-08-11 19:27:24 +02003612 {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003613 if( ssl_check_record_type( rec->type ) )
3614 {
Hanno Becker54229812019-07-12 14:40:00 +01003615 MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u",
3616 (unsigned) rec->type ) );
Hanno Beckere5e7e782019-07-11 12:29:35 +01003617 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3618 }
Manuel Pégourié-Gonnardedcbe542014-08-11 19:27:24 +02003619 }
3620
Hanno Beckere5e7e782019-07-11 12:29:35 +01003621 /*
3622 * Parse and validate record version
3623 */
Hanno Beckerd0b66d02019-07-26 08:07:03 +01003624 rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
3625 rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
Hanno Beckere5e7e782019-07-11 12:29:35 +01003626 mbedtls_ssl_read_version( &major_ver, &minor_ver,
3627 ssl->conf->transport,
Hanno Beckerd0b66d02019-07-26 08:07:03 +01003628 &rec->ver[0] );
Hanno Beckere5e7e782019-07-11 12:29:35 +01003629
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01003630 if( major_ver != ssl->major_ver )
Paul Bakker5121ce52009-01-03 21:22:43 +00003631 {
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003632 MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch: got %u, expected %u",
3633 (unsigned) major_ver,
3634 (unsigned) ssl->major_ver ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003635 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Paul Bakker5121ce52009-01-03 21:22:43 +00003636 }
3637
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003638 if( minor_ver > ssl->conf->max_minor_ver )
Paul Bakker5121ce52009-01-03 21:22:43 +00003639 {
Gilles Peskinef333dfa2022-02-15 23:53:36 +01003640 MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch: got %u, expected max %u",
3641 (unsigned) minor_ver,
3642 (unsigned) ssl->conf->max_minor_ver ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003643 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Paul Bakker5121ce52009-01-03 21:22:43 +00003644 }
Hanno Beckere5e7e782019-07-11 12:29:35 +01003645 /*
3646 * Parse/Copy record sequence number.
3647 */
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003648
Hanno Beckere5e7e782019-07-11 12:29:35 +01003649#if defined(MBEDTLS_SSL_PROTO_DTLS)
3650 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Paul Bakker1a1fbba2014-04-30 14:38:05 +02003651 {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003652 /* Copy explicit record sequence number from input buffer. */
3653 memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset,
3654 rec_hdr_ctr_len );
Paul Bakker1a1fbba2014-04-30 14:38:05 +02003655 }
Hanno Beckere5e7e782019-07-11 12:29:35 +01003656 else
3657#endif /* MBEDTLS_SSL_PROTO_DTLS */
3658 {
3659 /* Copy implicit record sequence number from SSL context structure. */
3660 memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len );
3661 }
Paul Bakker40e46942009-01-03 21:51:57 +00003662
Hanno Beckere5e7e782019-07-11 12:29:35 +01003663 /*
3664 * Parse record length.
3665 */
3666
Hanno Beckere5e7e782019-07-11 12:29:35 +01003667 rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
Hanno Becker9eca2762019-07-25 10:16:37 +01003668 rec->data_len = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) |
3669 ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 );
Hanno Beckere5e7e782019-07-11 12:29:35 +01003670 MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset );
Paul Bakker5121ce52009-01-03 21:22:43 +00003671
Paul Elliott9f352112020-12-09 14:55:45 +00003672 MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %u, "
Paul Elliottd48d5c62021-01-07 14:47:05 +00003673 "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET,
Hanno Beckere5e7e782019-07-11 12:29:35 +01003674 rec->type,
3675 major_ver, minor_ver, rec->data_len ) );
3676
3677 rec->buf = buf;
3678 rec->buf_len = rec->data_offset + rec->data_len;
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003679
Hanno Beckerd417cc92019-07-26 08:20:27 +01003680 if( rec->data_len == 0 )
3681 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Paul Bakker5121ce52009-01-03 21:22:43 +00003682
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003683 /*
Hanno Becker52c6dc62017-05-26 16:07:36 +01003684 * DTLS-related tests.
3685 * Check epoch before checking length constraint because
3686 * the latter varies with the epoch. E.g., if a ChangeCipherSpec
3687 * message gets duplicated before the corresponding Finished message,
3688 * the second ChangeCipherSpec should be discarded because it belongs
3689 * to an old epoch, but not because its length is shorter than
3690 * the minimum record length for packets using the new record transform.
3691 * Note that these two kinds of failures are handled differently,
3692 * as an unexpected record is silently skipped but an invalid
3693 * record leads to the entire datagram being dropped.
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003694 */
3695#if defined(MBEDTLS_SSL_PROTO_DTLS)
3696 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3697 {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003698 rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1];
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003699
Hanno Becker955a5c92019-07-10 17:12:07 +01003700 /* Check that the datagram is large enough to contain a record
3701 * of the advertised length. */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003702 if( len < rec->data_offset + rec->data_len )
Hanno Becker955a5c92019-07-10 17:12:07 +01003703 {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003704 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.",
3705 (unsigned) len,
3706 (unsigned)( rec->data_offset + rec->data_len ) ) );
Hanno Becker955a5c92019-07-10 17:12:07 +01003707 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3708 }
Hanno Becker37cfe732019-07-10 17:20:01 +01003709
Hanno Becker37cfe732019-07-10 17:20:01 +01003710 /* Records from other, non-matching epochs are silently discarded.
3711 * (The case of same-port Client reconnects must be considered in
3712 * the caller). */
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003713 if( rec_epoch != ssl->in_epoch )
3714 {
3715 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
Paul Elliott9f352112020-12-09 14:55:45 +00003716 "expected %u, received %lu",
3717 ssl->in_epoch, (unsigned long) rec_epoch ) );
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003718
Hanno Becker552f7472019-07-19 10:59:12 +01003719 /* Records from the next epoch are considered for buffering
3720 * (concretely: early Finished messages). */
3721 if( rec_epoch == (unsigned) ssl->in_epoch + 1 )
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003722 {
Hanno Becker552f7472019-07-19 10:59:12 +01003723 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
3724 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003725 }
Hanno Becker5f066e72018-08-16 14:56:31 +01003726
Hanno Becker2fddd372019-07-10 14:37:41 +01003727 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003728 }
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003729#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Hanno Becker37cfe732019-07-10 17:20:01 +01003730 /* For records from the correct epoch, check whether their
3731 * sequence number has been seen before. */
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02003732 else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl,
3733 &rec->ctr[0] ) != 0 )
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003734 {
3735 MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
3736 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
3737 }
3738#endif
3739 }
3740#endif /* MBEDTLS_SSL_PROTO_DTLS */
3741
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003742 return( 0 );
3743}
Paul Bakker5121ce52009-01-03 21:22:43 +00003744
Paul Bakker5121ce52009-01-03 21:22:43 +00003745
Hanno Becker2fddd372019-07-10 14:37:41 +01003746#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003747MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker2fddd372019-07-10 14:37:41 +01003748static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
3749{
3750 unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
3751
3752 /*
3753 * Check for an epoch 0 ClientHello. We can't use in_msg here to
3754 * access the first byte of record content (handshake type), as we
3755 * have an active transform (possibly iv_len != 0), so use the
3756 * fact that the record header len is 13 instead.
3757 */
3758 if( rec_epoch == 0 &&
3759 ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
3760 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
3761 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
3762 ssl->in_left > 13 &&
3763 ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
3764 {
3765 MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
3766 "from the same port" ) );
3767 return( ssl_handle_possible_reconnect( ssl ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003768 }
3769
3770 return( 0 );
3771}
Hanno Becker2fddd372019-07-10 14:37:41 +01003772#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00003773
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003774/*
Manuel Pégourié-Gonnardc40b6852020-01-03 12:18:49 +01003775 * If applicable, decrypt record content
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003776 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003777MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckerfdf66042019-07-11 13:07:45 +01003778static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
3779 mbedtls_record *rec )
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003780{
3781 int ret, done = 0;
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02003782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003783 MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
Hanno Beckerfdf66042019-07-11 13:07:45 +01003784 rec->buf, rec->buf_len );
Paul Bakker5121ce52009-01-03 21:22:43 +00003785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003786#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
3787 if( mbedtls_ssl_hw_record_read != NULL )
Paul Bakker05ef8352012-05-08 09:17:57 +00003788 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003789 MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
Paul Bakker05ef8352012-05-08 09:17:57 +00003790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003791 ret = mbedtls_ssl_hw_record_read( ssl );
3792 if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
Paul Bakker05ef8352012-05-08 09:17:57 +00003793 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003794 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
3795 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
Paul Bakker05ef8352012-05-08 09:17:57 +00003796 }
Paul Bakkerc7878112012-12-19 14:41:14 +01003797
3798 if( ret == 0 )
3799 done = 1;
Paul Bakker05ef8352012-05-08 09:17:57 +00003800 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003801#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
Paul Bakker48916f92012-09-16 19:57:18 +00003802 if( !done && ssl->transform_in != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00003803 {
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003804 unsigned char const old_msg_type = rec->type;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003805
Hanno Beckera18d1322018-01-03 14:27:32 +00003806 if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in,
Hanno Beckerfdf66042019-07-11 13:07:45 +01003807 rec ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003808 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003809 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
Hanno Becker8367ccc2019-05-14 11:30:10 +01003810
Hanno Beckera0e20d02019-05-15 14:03:01 +01003811#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker8367ccc2019-05-14 11:30:10 +01003812 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
3813 ssl->conf->ignore_unexpected_cid
3814 == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
3815 {
Hanno Beckere8d6afd2019-05-24 10:11:06 +01003816 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) );
Hanno Becker16ded982019-05-08 13:02:55 +01003817 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
Hanno Becker8367ccc2019-05-14 11:30:10 +01003818 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01003819#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker16ded982019-05-08 13:02:55 +01003820
Paul Bakker5121ce52009-01-03 21:22:43 +00003821 return( ret );
3822 }
3823
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003824 if( old_msg_type != rec->type )
Hanno Becker6430faf2019-05-08 11:57:13 +01003825 {
3826 MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d",
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003827 old_msg_type, rec->type ) );
Hanno Becker6430faf2019-05-08 11:57:13 +01003828 }
3829
Hanno Becker1c0c37f2018-08-07 14:29:29 +01003830 MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003831 rec->buf + rec->data_offset, rec->data_len );
Hanno Becker1c0c37f2018-08-07 14:29:29 +01003832
Hanno Beckera0e20d02019-05-15 14:03:01 +01003833#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker6430faf2019-05-08 11:57:13 +01003834 /* We have already checked the record content type
3835 * in ssl_parse_record_header(), failing or silently
3836 * dropping the record in the case of an unknown type.
3837 *
3838 * Since with the use of CIDs, the record content type
3839 * might change during decryption, re-check the record
3840 * content type, but treat a failure as fatal this time. */
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003841 if( ssl_check_record_type( rec->type ) )
Hanno Becker6430faf2019-05-08 11:57:13 +01003842 {
3843 MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
3844 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3845 }
Hanno Beckera0e20d02019-05-15 14:03:01 +01003846#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker6430faf2019-05-08 11:57:13 +01003847
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003848 if( rec->data_len == 0 )
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003849 {
3850#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3851 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003852 && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003853 {
3854 /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
3855 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
3856 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3857 }
3858#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
3859
3860 ssl->nb_zero++;
3861
3862 /*
3863 * Three or more empty messages may be a DoS attack
3864 * (excessive CPU consumption).
3865 */
3866 if( ssl->nb_zero > 3 )
3867 {
3868 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
Hanno Becker6e7700d2019-05-08 10:38:32 +01003869 "messages, possible DoS attack" ) );
3870 /* Treat the records as if they were not properly authenticated,
3871 * thereby failing the connection if we see more than allowed
3872 * by the configured bad MAC threshold. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003873 return( MBEDTLS_ERR_SSL_INVALID_MAC );
3874 }
3875 }
3876 else
3877 ssl->nb_zero = 0;
3878
3879#if defined(MBEDTLS_SSL_PROTO_DTLS)
3880 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
3881 {
3882 ; /* in_ctr read from peer, not maintained internally */
3883 }
3884 else
3885#endif
3886 {
3887 unsigned i;
Hanno Beckerdd772292020-02-05 10:38:31 +00003888 for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003889 if( ++ssl->in_ctr[i - 1] != 0 )
3890 break;
3891
3892 /* The loop goes to its end iff the counter is wrapping */
Hanno Beckerdd772292020-02-05 10:38:31 +00003893 if( i == mbedtls_ssl_ep_len( ssl ) )
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003894 {
3895 MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
3896 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
3897 }
3898 }
3899
Paul Bakker5121ce52009-01-03 21:22:43 +00003900 }
3901
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003902#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02003903 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02003904 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003905 mbedtls_ssl_dtls_replay_update( ssl );
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02003906 }
3907#endif
3908
Hanno Beckerd96e10b2019-07-09 17:30:02 +01003909 /* Check actual (decrypted) record content length against
3910 * configured maximum. */
Paul Elliott24ed2ca2022-06-10 14:11:31 +01003911 if( rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN )
Hanno Beckerd96e10b2019-07-09 17:30:02 +01003912 {
3913 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
3914 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
3915 }
3916
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003917 return( 0 );
3918}
3919
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02003920/*
3921 * Read a record.
3922 *
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02003923 * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
3924 * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
3925 *
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02003926 */
Hanno Becker1097b342018-08-15 14:09:41 +01003927
3928/* Helper functions for mbedtls_ssl_read_record(). */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003929MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker1097b342018-08-15 14:09:41 +01003930static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003931MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckere74d5562018-08-15 14:26:08 +01003932static int ssl_get_next_record( mbedtls_ssl_context *ssl );
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02003933MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckere74d5562018-08-15 14:26:08 +01003934static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
Hanno Becker4162b112018-08-15 14:05:04 +01003935
Hanno Becker327c93b2018-08-15 13:56:18 +01003936int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
Hanno Becker3a0aad12018-08-20 09:44:02 +01003937 unsigned update_hs_digest )
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003938{
Janos Follath865b3eb2019-12-16 11:46:15 +00003939 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003940
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003941 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003942
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003943 if( ssl->keep_current_message == 0 )
3944 {
3945 do {
Simon Butcher99000142016-10-13 17:21:01 +01003946
Hanno Becker26994592018-08-15 14:14:59 +01003947 ret = ssl_consume_current_message( ssl );
Hanno Becker90333da2017-10-10 11:27:13 +01003948 if( ret != 0 )
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003949 return( ret );
Hanno Becker26994592018-08-15 14:14:59 +01003950
Hanno Beckere74d5562018-08-15 14:26:08 +01003951 if( ssl_record_is_in_progress( ssl ) == 0 )
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003952 {
Hanno Becker40f50842018-08-15 14:48:01 +01003953#if defined(MBEDTLS_SSL_PROTO_DTLS)
3954 int have_buffered = 0;
Hanno Beckere74d5562018-08-15 14:26:08 +01003955
Hanno Becker40f50842018-08-15 14:48:01 +01003956 /* We only check for buffered messages if the
3957 * current datagram is fully consumed. */
3958 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Hanno Beckeref7afdf2018-08-28 17:16:31 +01003959 ssl_next_record_is_in_datagram( ssl ) == 0 )
Hanno Beckere74d5562018-08-15 14:26:08 +01003960 {
Hanno Becker40f50842018-08-15 14:48:01 +01003961 if( ssl_load_buffered_message( ssl ) == 0 )
3962 have_buffered = 1;
3963 }
3964
3965 if( have_buffered == 0 )
3966#endif /* MBEDTLS_SSL_PROTO_DTLS */
3967 {
3968 ret = ssl_get_next_record( ssl );
3969 if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
3970 continue;
3971
3972 if( ret != 0 )
3973 {
Hanno Beckerc573ac32018-08-28 17:15:25 +01003974 MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
Hanno Becker40f50842018-08-15 14:48:01 +01003975 return( ret );
3976 }
Hanno Beckere74d5562018-08-15 14:26:08 +01003977 }
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003978 }
3979
3980 ret = mbedtls_ssl_handle_message_type( ssl );
3981
Hanno Becker40f50842018-08-15 14:48:01 +01003982#if defined(MBEDTLS_SSL_PROTO_DTLS)
3983 if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
3984 {
3985 /* Buffer future message */
3986 ret = ssl_buffer_message( ssl );
3987 if( ret != 0 )
3988 return( ret );
3989
3990 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3991 }
3992#endif /* MBEDTLS_SSL_PROTO_DTLS */
3993
Hanno Becker90333da2017-10-10 11:27:13 +01003994 } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
3995 MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003996
3997 if( 0 != ret )
Simon Butcher99000142016-10-13 17:21:01 +01003998 {
Hanno Becker05c4fc82017-11-09 14:34:06 +00003999 MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
Simon Butcher99000142016-10-13 17:21:01 +01004000 return( ret );
4001 }
4002
Hanno Becker327c93b2018-08-15 13:56:18 +01004003 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
Hanno Becker3a0aad12018-08-20 09:44:02 +01004004 update_hs_digest == 1 )
Hanno Beckeraf0665d2017-05-24 09:16:26 +01004005 {
4006 mbedtls_ssl_update_handshake_status( ssl );
4007 }
Simon Butcher99000142016-10-13 17:21:01 +01004008 }
Hanno Beckeraf0665d2017-05-24 09:16:26 +01004009 else
Simon Butcher99000142016-10-13 17:21:01 +01004010 {
Hanno Becker02f59072018-08-15 14:00:24 +01004011 MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
Hanno Beckeraf0665d2017-05-24 09:16:26 +01004012 ssl->keep_current_message = 0;
Simon Butcher99000142016-10-13 17:21:01 +01004013 }
4014
4015 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
4016
4017 return( 0 );
4018}
4019
Hanno Becker40f50842018-08-15 14:48:01 +01004020#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004021MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckeref7afdf2018-08-28 17:16:31 +01004022static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
Simon Butcher99000142016-10-13 17:21:01 +01004023{
Hanno Becker40f50842018-08-15 14:48:01 +01004024 if( ssl->in_left > ssl->next_record_offset )
4025 return( 1 );
Simon Butcher99000142016-10-13 17:21:01 +01004026
Hanno Becker40f50842018-08-15 14:48:01 +01004027 return( 0 );
4028}
4029
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004030MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker40f50842018-08-15 14:48:01 +01004031static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
4032{
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004033 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
Hanno Becker37f95322018-08-16 13:55:32 +01004034 mbedtls_ssl_hs_buffer * hs_buf;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004035 int ret = 0;
4036
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004037 if( hs == NULL )
4038 return( -1 );
4039
Hanno Beckere00ae372018-08-20 09:39:42 +01004040 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
4041
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004042 if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
4043 ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
4044 {
4045 /* Check if we have seen a ChangeCipherSpec before.
4046 * If yes, synthesize a CCS record. */
Hanno Becker4422bbb2018-08-20 09:40:19 +01004047 if( !hs->buffering.seen_ccs )
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004048 {
4049 MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
4050 ret = -1;
Hanno Becker0d4b3762018-08-20 09:36:59 +01004051 goto exit;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004052 }
4053
Hanno Becker39b8bc92018-08-28 17:17:13 +01004054 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004055 ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
4056 ssl->in_msglen = 1;
4057 ssl->in_msg[0] = 1;
4058
4059 /* As long as they are equal, the exact value doesn't matter. */
4060 ssl->in_left = 0;
4061 ssl->next_record_offset = 0;
4062
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01004063 hs->buffering.seen_ccs = 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004064 goto exit;
4065 }
Hanno Becker37f95322018-08-16 13:55:32 +01004066
Hanno Beckerb8f50142018-08-28 10:01:34 +01004067#if defined(MBEDTLS_DEBUG_C)
Hanno Becker37f95322018-08-16 13:55:32 +01004068 /* Debug only */
4069 {
4070 unsigned offset;
4071 for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
4072 {
4073 hs_buf = &hs->buffering.hs[offset];
4074 if( hs_buf->is_valid == 1 )
4075 {
4076 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
4077 hs->in_msg_seq + offset,
Hanno Beckera591c482018-08-28 17:20:00 +01004078 hs_buf->is_complete ? "fully" : "partially" ) );
Hanno Becker37f95322018-08-16 13:55:32 +01004079 }
4080 }
4081 }
Hanno Beckerb8f50142018-08-28 10:01:34 +01004082#endif /* MBEDTLS_DEBUG_C */
Hanno Becker37f95322018-08-16 13:55:32 +01004083
4084 /* Check if we have buffered and/or fully reassembled the
4085 * next handshake message. */
4086 hs_buf = &hs->buffering.hs[0];
4087 if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
4088 {
4089 /* Synthesize a record containing the buffered HS message. */
4090 size_t msg_len = ( hs_buf->data[1] << 16 ) |
4091 ( hs_buf->data[2] << 8 ) |
4092 hs_buf->data[3];
4093
4094 /* Double-check that we haven't accidentally buffered
4095 * a message that doesn't fit into the input buffer. */
4096 if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
4097 {
4098 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4099 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4100 }
4101
4102 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
4103 MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
4104 hs_buf->data, msg_len + 12 );
4105
4106 ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
4107 ssl->in_hslen = msg_len + 12;
4108 ssl->in_msglen = msg_len + 12;
4109 memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
4110
4111 ret = 0;
4112 goto exit;
4113 }
4114 else
4115 {
4116 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
4117 hs->in_msg_seq ) );
4118 }
4119
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004120 ret = -1;
4121
4122exit:
4123
4124 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
4125 return( ret );
Hanno Becker40f50842018-08-15 14:48:01 +01004126}
4127
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004128MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckera02b0b42018-08-21 17:20:27 +01004129static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
4130 size_t desired )
4131{
4132 int offset;
4133 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
Hanno Becker6e12c1e2018-08-24 14:39:15 +01004134 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
4135 (unsigned) desired ) );
Hanno Beckera02b0b42018-08-21 17:20:27 +01004136
Hanno Becker01315ea2018-08-21 17:22:17 +01004137 /* Get rid of future records epoch first, if such exist. */
4138 ssl_free_buffered_record( ssl );
4139
4140 /* Check if we have enough space available now. */
4141 if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4142 hs->buffering.total_bytes_buffered ) )
4143 {
Hanno Becker6e12c1e2018-08-24 14:39:15 +01004144 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
Hanno Becker01315ea2018-08-21 17:22:17 +01004145 return( 0 );
4146 }
Hanno Beckera02b0b42018-08-21 17:20:27 +01004147
Hanno Becker4f432ad2018-08-28 10:02:32 +01004148 /* We don't have enough space to buffer the next expected handshake
4149 * message. Remove buffers used for future messages to gain space,
4150 * starting with the most distant one. */
Hanno Beckera02b0b42018-08-21 17:20:27 +01004151 for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
4152 offset >= 0; offset-- )
4153 {
4154 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
4155 offset ) );
4156
Hanno Beckerb309b922018-08-23 13:18:05 +01004157 ssl_buffering_free_slot( ssl, (uint8_t) offset );
Hanno Beckera02b0b42018-08-21 17:20:27 +01004158
4159 /* Check if we have enough space available now. */
4160 if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4161 hs->buffering.total_bytes_buffered ) )
4162 {
Hanno Becker6e12c1e2018-08-24 14:39:15 +01004163 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
Hanno Beckera02b0b42018-08-21 17:20:27 +01004164 return( 0 );
4165 }
4166 }
4167
4168 return( -1 );
4169}
4170
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004171MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker40f50842018-08-15 14:48:01 +01004172static int ssl_buffer_message( mbedtls_ssl_context *ssl )
4173{
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004174 int ret = 0;
4175 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4176
4177 if( hs == NULL )
4178 return( 0 );
4179
4180 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
4181
4182 switch( ssl->in_msgtype )
4183 {
4184 case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
4185 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
Hanno Beckere678eaa2018-08-21 14:57:46 +01004186
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01004187 hs->buffering.seen_ccs = 1;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004188 break;
4189
4190 case MBEDTLS_SSL_MSG_HANDSHAKE:
Hanno Becker37f95322018-08-16 13:55:32 +01004191 {
4192 unsigned recv_msg_seq_offset;
4193 unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
4194 mbedtls_ssl_hs_buffer *hs_buf;
4195 size_t msg_len = ssl->in_hslen - 12;
4196
4197 /* We should never receive an old handshake
4198 * message - double-check nonetheless. */
4199 if( recv_msg_seq < ssl->handshake->in_msg_seq )
4200 {
4201 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4202 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4203 }
4204
4205 recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
4206 if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
4207 {
4208 /* Silently ignore -- message too far in the future */
4209 MBEDTLS_SSL_DEBUG_MSG( 2,
4210 ( "Ignore future HS message with sequence number %u, "
4211 "buffering window %u - %u",
4212 recv_msg_seq, ssl->handshake->in_msg_seq,
4213 ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
4214
4215 goto exit;
4216 }
4217
4218 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
4219 recv_msg_seq, recv_msg_seq_offset ) );
4220
4221 hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
4222
4223 /* Check if the buffering for this seq nr has already commenced. */
Hanno Becker4422bbb2018-08-20 09:40:19 +01004224 if( !hs_buf->is_valid )
Hanno Becker37f95322018-08-16 13:55:32 +01004225 {
Hanno Becker2a97b0e2018-08-21 15:47:49 +01004226 size_t reassembly_buf_sz;
4227
Hanno Becker37f95322018-08-16 13:55:32 +01004228 hs_buf->is_fragmented =
4229 ( ssl_hs_is_proper_fragment( ssl ) == 1 );
4230
4231 /* We copy the message back into the input buffer
4232 * after reassembly, so check that it's not too large.
4233 * This is an implementation-specific limitation
4234 * and not one from the standard, hence it is not
4235 * checked in ssl_check_hs_header(). */
Hanno Becker96a6c692018-08-21 15:56:03 +01004236 if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
Hanno Becker37f95322018-08-16 13:55:32 +01004237 {
4238 /* Ignore message */
4239 goto exit;
4240 }
4241
Hanno Beckere0b150f2018-08-21 15:51:03 +01004242 /* Check if we have enough space to buffer the message. */
4243 if( hs->buffering.total_bytes_buffered >
4244 MBEDTLS_SSL_DTLS_MAX_BUFFERING )
4245 {
4246 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4247 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4248 }
4249
Hanno Becker2a97b0e2018-08-21 15:47:49 +01004250 reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
4251 hs_buf->is_fragmented );
Hanno Beckere0b150f2018-08-21 15:51:03 +01004252
4253 if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4254 hs->buffering.total_bytes_buffered ) )
4255 {
4256 if( recv_msg_seq_offset > 0 )
4257 {
4258 /* If we can't buffer a future message because
4259 * of space limitations -- ignore. */
Paul Elliottd48d5c62021-01-07 14:47:05 +00004260 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
4261 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
4262 " (already %" MBEDTLS_PRINTF_SIZET
4263 " bytes buffered) -- ignore\n",
Paul Elliott3891caf2020-12-17 18:42:40 +00004264 msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
Paul Elliott9f352112020-12-09 14:55:45 +00004265 hs->buffering.total_bytes_buffered ) );
Hanno Beckere0b150f2018-08-21 15:51:03 +01004266 goto exit;
4267 }
Hanno Beckere1801392018-08-21 16:51:05 +01004268 else
4269 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00004270 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
4271 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
4272 " (already %" MBEDTLS_PRINTF_SIZET
4273 " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
Paul Elliott3891caf2020-12-17 18:42:40 +00004274 msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
Paul Elliott9f352112020-12-09 14:55:45 +00004275 hs->buffering.total_bytes_buffered ) );
Hanno Beckere1801392018-08-21 16:51:05 +01004276 }
Hanno Beckere0b150f2018-08-21 15:51:03 +01004277
Hanno Beckera02b0b42018-08-21 17:20:27 +01004278 if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
Hanno Becker55e9e2a2018-08-21 16:07:55 +01004279 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00004280 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET
4281 " (%" MBEDTLS_PRINTF_SIZET " with bitmap) would exceed"
4282 " the compile-time limit %" MBEDTLS_PRINTF_SIZET
4283 " (already %" MBEDTLS_PRINTF_SIZET
4284 " bytes buffered) -- fail\n",
Paul Elliott9f352112020-12-09 14:55:45 +00004285 msg_len,
4286 reassembly_buf_sz,
Paul Elliott3891caf2020-12-17 18:42:40 +00004287 (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
Paul Elliott9f352112020-12-09 14:55:45 +00004288 hs->buffering.total_bytes_buffered ) );
Hanno Becker55e9e2a2018-08-21 16:07:55 +01004289 ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
4290 goto exit;
4291 }
Hanno Beckere0b150f2018-08-21 15:51:03 +01004292 }
4293
Paul Elliottd48d5c62021-01-07 14:47:05 +00004294 MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET,
Hanno Beckere0b150f2018-08-21 15:51:03 +01004295 msg_len ) );
4296
Hanno Becker2a97b0e2018-08-21 15:47:49 +01004297 hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
4298 if( hs_buf->data == NULL )
Hanno Becker37f95322018-08-16 13:55:32 +01004299 {
Hanno Beckere0b150f2018-08-21 15:51:03 +01004300 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
Hanno Becker37f95322018-08-16 13:55:32 +01004301 goto exit;
4302 }
Hanno Beckere0b150f2018-08-21 15:51:03 +01004303 hs_buf->data_len = reassembly_buf_sz;
Hanno Becker37f95322018-08-16 13:55:32 +01004304
4305 /* Prepare final header: copy msg_type, length and message_seq,
4306 * then add standardised fragment_offset and fragment_length */
4307 memcpy( hs_buf->data, ssl->in_msg, 6 );
4308 memset( hs_buf->data + 6, 0, 3 );
4309 memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
4310
4311 hs_buf->is_valid = 1;
Hanno Beckere0b150f2018-08-21 15:51:03 +01004312
4313 hs->buffering.total_bytes_buffered += reassembly_buf_sz;
Hanno Becker37f95322018-08-16 13:55:32 +01004314 }
4315 else
4316 {
4317 /* Make sure msg_type and length are consistent */
4318 if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
4319 {
4320 MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
4321 /* Ignore */
4322 goto exit;
4323 }
4324 }
4325
Hanno Becker4422bbb2018-08-20 09:40:19 +01004326 if( !hs_buf->is_complete )
Hanno Becker37f95322018-08-16 13:55:32 +01004327 {
4328 size_t frag_len, frag_off;
4329 unsigned char * const msg = hs_buf->data + 12;
4330
4331 /*
4332 * Check and copy current fragment
4333 */
4334
4335 /* Validation of header fields already done in
4336 * mbedtls_ssl_prepare_handshake_record(). */
4337 frag_off = ssl_get_hs_frag_off( ssl );
4338 frag_len = ssl_get_hs_frag_len( ssl );
4339
Paul Elliottd48d5c62021-01-07 14:47:05 +00004340 MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
4341 ", length = %" MBEDTLS_PRINTF_SIZET,
Hanno Becker37f95322018-08-16 13:55:32 +01004342 frag_off, frag_len ) );
4343 memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
4344
4345 if( hs_buf->is_fragmented )
4346 {
4347 unsigned char * const bitmask = msg + msg_len;
4348 ssl_bitmask_set( bitmask, frag_off, frag_len );
4349 hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
4350 msg_len ) == 0 );
4351 }
4352 else
4353 {
4354 hs_buf->is_complete = 1;
4355 }
4356
4357 MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
4358 hs_buf->is_complete ? "" : "not yet " ) );
4359 }
4360
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004361 break;
Hanno Becker37f95322018-08-16 13:55:32 +01004362 }
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004363
4364 default:
Hanno Becker360bef32018-08-28 10:04:33 +01004365 /* We don't buffer other types of messages. */
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004366 break;
4367 }
4368
4369exit:
4370
4371 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
4372 return( ret );
Hanno Becker40f50842018-08-15 14:48:01 +01004373}
4374#endif /* MBEDTLS_SSL_PROTO_DTLS */
4375
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004376MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker1097b342018-08-15 14:09:41 +01004377static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004378{
Hanno Becker4a810fb2017-05-24 16:27:30 +01004379 /*
Hanno Becker4a810fb2017-05-24 16:27:30 +01004380 * Consume last content-layer message and potentially
4381 * update in_msglen which keeps track of the contents'
4382 * consumption state.
4383 *
4384 * (1) Handshake messages:
4385 * Remove last handshake message, move content
4386 * and adapt in_msglen.
4387 *
4388 * (2) Alert messages:
4389 * Consume whole record content, in_msglen = 0.
4390 *
Hanno Becker4a810fb2017-05-24 16:27:30 +01004391 * (3) Change cipher spec:
4392 * Consume whole record content, in_msglen = 0.
4393 *
4394 * (4) Application data:
4395 * Don't do anything - the record layer provides
4396 * the application data as a stream transport
4397 * and consumes through mbedtls_ssl_read only.
4398 *
4399 */
4400
4401 /* Case (1): Handshake messages */
4402 if( ssl->in_hslen != 0 )
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004403 {
Hanno Beckerbb9dd0c2017-06-08 11:55:34 +01004404 /* Hard assertion to be sure that no application data
4405 * is in flight, as corrupting ssl->in_msglen during
4406 * ssl->in_offt != NULL is fatal. */
4407 if( ssl->in_offt != NULL )
4408 {
4409 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4410 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4411 }
4412
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004413 /*
4414 * Get next Handshake message in the current record
4415 */
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004416
Hanno Becker4a810fb2017-05-24 16:27:30 +01004417 /* Notes:
Hanno Beckere72489d2017-10-23 13:23:50 +01004418 * (1) in_hslen is not necessarily the size of the
Hanno Becker4a810fb2017-05-24 16:27:30 +01004419 * current handshake content: If DTLS handshake
4420 * fragmentation is used, that's the fragment
4421 * size instead. Using the total handshake message
Hanno Beckere72489d2017-10-23 13:23:50 +01004422 * size here is faulty and should be changed at
4423 * some point.
Hanno Becker4a810fb2017-05-24 16:27:30 +01004424 * (2) While it doesn't seem to cause problems, one
4425 * has to be very careful not to assume that in_hslen
4426 * is always <= in_msglen in a sensible communication.
4427 * Again, it's wrong for DTLS handshake fragmentation.
4428 * The following check is therefore mandatory, and
4429 * should not be treated as a silently corrected assertion.
Hanno Beckerbb9dd0c2017-06-08 11:55:34 +01004430 * Additionally, ssl->in_hslen might be arbitrarily out of
4431 * bounds after handling a DTLS message with an unexpected
4432 * sequence number, see mbedtls_ssl_prepare_handshake_record.
Hanno Becker4a810fb2017-05-24 16:27:30 +01004433 */
4434 if( ssl->in_hslen < ssl->in_msglen )
4435 {
4436 ssl->in_msglen -= ssl->in_hslen;
4437 memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
4438 ssl->in_msglen );
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004439
Hanno Becker4a810fb2017-05-24 16:27:30 +01004440 MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
4441 ssl->in_msg, ssl->in_msglen );
4442 }
4443 else
4444 {
4445 ssl->in_msglen = 0;
4446 }
Manuel Pégourié-Gonnard4a175362014-09-09 17:45:31 +02004447
Hanno Becker4a810fb2017-05-24 16:27:30 +01004448 ssl->in_hslen = 0;
4449 }
4450 /* Case (4): Application data */
4451 else if( ssl->in_offt != NULL )
4452 {
4453 return( 0 );
4454 }
4455 /* Everything else (CCS & Alerts) */
4456 else
4457 {
4458 ssl->in_msglen = 0;
4459 }
4460
Hanno Becker1097b342018-08-15 14:09:41 +01004461 return( 0 );
4462}
Hanno Becker4a810fb2017-05-24 16:27:30 +01004463
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004464MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckere74d5562018-08-15 14:26:08 +01004465static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
4466{
Hanno Becker4a810fb2017-05-24 16:27:30 +01004467 if( ssl->in_msglen > 0 )
Hanno Beckere74d5562018-08-15 14:26:08 +01004468 return( 1 );
4469
4470 return( 0 );
4471}
4472
Hanno Becker5f066e72018-08-16 14:56:31 +01004473#if defined(MBEDTLS_SSL_PROTO_DTLS)
4474
4475static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
4476{
4477 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4478 if( hs == NULL )
4479 return;
4480
Hanno Becker01315ea2018-08-21 17:22:17 +01004481 if( hs->buffering.future_record.data != NULL )
Hanno Becker4a810fb2017-05-24 16:27:30 +01004482 {
Hanno Becker01315ea2018-08-21 17:22:17 +01004483 hs->buffering.total_bytes_buffered -=
4484 hs->buffering.future_record.len;
4485
4486 mbedtls_free( hs->buffering.future_record.data );
4487 hs->buffering.future_record.data = NULL;
4488 }
Hanno Becker5f066e72018-08-16 14:56:31 +01004489}
4490
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004491MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker5f066e72018-08-16 14:56:31 +01004492static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
4493{
4494 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4495 unsigned char * rec;
4496 size_t rec_len;
4497 unsigned rec_epoch;
Darryl Greenb33cc762019-11-28 14:29:44 +00004498#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
4499 size_t in_buf_len = ssl->in_buf_len;
4500#else
4501 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
4502#endif
Hanno Becker5f066e72018-08-16 14:56:31 +01004503 if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4504 return( 0 );
4505
4506 if( hs == NULL )
4507 return( 0 );
4508
Hanno Becker5f066e72018-08-16 14:56:31 +01004509 rec = hs->buffering.future_record.data;
4510 rec_len = hs->buffering.future_record.len;
4511 rec_epoch = hs->buffering.future_record.epoch;
4512
4513 if( rec == NULL )
4514 return( 0 );
4515
Hanno Becker4cb782d2018-08-20 11:19:05 +01004516 /* Only consider loading future records if the
4517 * input buffer is empty. */
Hanno Beckeref7afdf2018-08-28 17:16:31 +01004518 if( ssl_next_record_is_in_datagram( ssl ) == 1 )
Hanno Becker4cb782d2018-08-20 11:19:05 +01004519 return( 0 );
4520
Hanno Becker5f066e72018-08-16 14:56:31 +01004521 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
4522
4523 if( rec_epoch != ssl->in_epoch )
4524 {
4525 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
4526 goto exit;
4527 }
4528
4529 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
4530
4531 /* Double-check that the record is not too large */
Darryl Greenb33cc762019-11-28 14:29:44 +00004532 if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
Hanno Becker5f066e72018-08-16 14:56:31 +01004533 {
4534 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
4535 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
4536 }
4537
4538 memcpy( ssl->in_hdr, rec, rec_len );
4539 ssl->in_left = rec_len;
4540 ssl->next_record_offset = 0;
4541
4542 ssl_free_buffered_record( ssl );
4543
4544exit:
4545 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
4546 return( 0 );
4547}
4548
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004549MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Becker519f15d2019-07-11 12:43:20 +01004550static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
4551 mbedtls_record const *rec )
Hanno Becker5f066e72018-08-16 14:56:31 +01004552{
4553 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
Hanno Becker5f066e72018-08-16 14:56:31 +01004554
4555 /* Don't buffer future records outside handshakes. */
4556 if( hs == NULL )
4557 return( 0 );
4558
4559 /* Only buffer handshake records (we are only interested
4560 * in Finished messages). */
Hanno Becker519f15d2019-07-11 12:43:20 +01004561 if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE )
Hanno Becker5f066e72018-08-16 14:56:31 +01004562 return( 0 );
4563
4564 /* Don't buffer more than one future epoch record. */
4565 if( hs->buffering.future_record.data != NULL )
4566 return( 0 );
4567
Hanno Becker01315ea2018-08-21 17:22:17 +01004568 /* Don't buffer record if there's not enough buffering space remaining. */
Hanno Becker519f15d2019-07-11 12:43:20 +01004569 if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
Hanno Becker01315ea2018-08-21 17:22:17 +01004570 hs->buffering.total_bytes_buffered ) )
4571 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00004572 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
4573 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
4574 " (already %" MBEDTLS_PRINTF_SIZET
4575 " bytes buffered) -- ignore\n",
Paul Elliott3891caf2020-12-17 18:42:40 +00004576 rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
Paul Elliott9f352112020-12-09 14:55:45 +00004577 hs->buffering.total_bytes_buffered ) );
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004578 return( 0 );
4579 }
4580
Hanno Becker5f066e72018-08-16 14:56:31 +01004581 /* Buffer record */
4582 MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
Paul Elliott9f352112020-12-09 14:55:45 +00004583 ssl->in_epoch + 1U ) );
Hanno Becker519f15d2019-07-11 12:43:20 +01004584 MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len );
Hanno Becker5f066e72018-08-16 14:56:31 +01004585
4586 /* ssl_parse_record_header() only considers records
4587 * of the next epoch as candidates for buffering. */
4588 hs->buffering.future_record.epoch = ssl->in_epoch + 1;
Hanno Becker519f15d2019-07-11 12:43:20 +01004589 hs->buffering.future_record.len = rec->buf_len;
Hanno Becker5f066e72018-08-16 14:56:31 +01004590
4591 hs->buffering.future_record.data =
4592 mbedtls_calloc( 1, hs->buffering.future_record.len );
4593 if( hs->buffering.future_record.data == NULL )
4594 {
4595 /* If we run out of RAM trying to buffer a
4596 * record from the next epoch, just ignore. */
4597 return( 0 );
4598 }
4599
Hanno Becker519f15d2019-07-11 12:43:20 +01004600 memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len );
Hanno Becker5f066e72018-08-16 14:56:31 +01004601
Hanno Becker519f15d2019-07-11 12:43:20 +01004602 hs->buffering.total_bytes_buffered += rec->buf_len;
Hanno Becker5f066e72018-08-16 14:56:31 +01004603 return( 0 );
4604}
4605
4606#endif /* MBEDTLS_SSL_PROTO_DTLS */
4607
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02004608MBEDTLS_CHECK_RETURN_CRITICAL
Hanno Beckere74d5562018-08-15 14:26:08 +01004609static int ssl_get_next_record( mbedtls_ssl_context *ssl )
Hanno Becker1097b342018-08-15 14:09:41 +01004610{
Janos Follath865b3eb2019-12-16 11:46:15 +00004611 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckere5e7e782019-07-11 12:29:35 +01004612 mbedtls_record rec;
Hanno Becker1097b342018-08-15 14:09:41 +01004613
Hanno Becker5f066e72018-08-16 14:56:31 +01004614#if defined(MBEDTLS_SSL_PROTO_DTLS)
4615 /* We might have buffered a future record; if so,
4616 * and if the epoch matches now, load it.
4617 * On success, this call will set ssl->in_left to
4618 * the length of the buffered record, so that
4619 * the calls to ssl_fetch_input() below will
4620 * essentially be no-ops. */
4621 ret = ssl_load_buffered_record( ssl );
4622 if( ret != 0 )
4623 return( ret );
4624#endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker4a810fb2017-05-24 16:27:30 +01004625
Hanno Beckerca59c2b2019-05-08 12:03:28 +01004626 /* Ensure that we have enough space available for the default form
4627 * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
4628 * with no space for CIDs counted in). */
4629 ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
4630 if( ret != 0 )
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004631 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004632 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004633 return( ret );
4634 }
4635
Hanno Beckere5e7e782019-07-11 12:29:35 +01004636 ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec );
4637 if( ret != 0 )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004638 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004639#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2fddd372019-07-10 14:37:41 +01004640 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004641 {
Hanno Becker5f066e72018-08-16 14:56:31 +01004642 if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
4643 {
Hanno Becker519f15d2019-07-11 12:43:20 +01004644 ret = ssl_buffer_future_record( ssl, &rec );
Hanno Becker5f066e72018-08-16 14:56:31 +01004645 if( ret != 0 )
4646 return( ret );
4647
4648 /* Fall through to handling of unexpected records */
4649 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
4650 }
4651
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004652 if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
4653 {
Hanno Becker2fddd372019-07-10 14:37:41 +01004654#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
Hanno Beckerd8bf8ce2019-07-12 09:23:47 +01004655 /* Reset in pointers to default state for TLS/DTLS records,
4656 * assuming no CID and no offset between record content and
4657 * record plaintext. */
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00004658 mbedtls_ssl_update_in_pointers( ssl );
Hanno Beckerd8bf8ce2019-07-12 09:23:47 +01004659
Hanno Becker7ae20e02019-07-12 08:33:49 +01004660 /* Setup internal message pointers from record structure. */
4661 ssl->in_msgtype = rec.type;
4662#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4663 ssl->in_len = ssl->in_cid + rec.cid_len;
4664#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4665 ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
4666 ssl->in_msglen = rec.data_len;
4667
Hanno Becker2fddd372019-07-10 14:37:41 +01004668 ret = ssl_check_client_reconnect( ssl );
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02004669 MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret );
Hanno Becker2fddd372019-07-10 14:37:41 +01004670 if( ret != 0 )
4671 return( ret );
4672#endif
4673
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004674 /* Skip unexpected record (but not whole datagram) */
Hanno Becker4acada32019-07-11 12:48:53 +01004675 ssl->next_record_offset = rec.buf_len;
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004676
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004677 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
4678 "(header)" ) );
4679 }
4680 else
4681 {
4682 /* Skip invalid record and the rest of the datagram */
4683 ssl->next_record_offset = 0;
4684 ssl->in_left = 0;
4685
4686 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
4687 "(header)" ) );
4688 }
4689
4690 /* Get next record */
Hanno Becker90333da2017-10-10 11:27:13 +01004691 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004692 }
Hanno Becker2fddd372019-07-10 14:37:41 +01004693 else
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004694#endif
Hanno Becker2fddd372019-07-10 14:37:41 +01004695 {
4696 return( ret );
4697 }
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004698 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004700#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02004701 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Hanno Beckere65ce782017-05-22 14:47:48 +01004702 {
Hanno Beckera8814792019-07-10 15:01:45 +01004703 /* Remember offset of next record within datagram. */
Hanno Beckerf50da502019-07-11 12:50:10 +01004704 ssl->next_record_offset = rec.buf_len;
Hanno Beckere65ce782017-05-22 14:47:48 +01004705 if( ssl->next_record_offset < ssl->in_left )
4706 {
4707 MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
4708 }
4709 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004710 else
4711#endif
Hanno Beckera8814792019-07-10 15:01:45 +01004712 {
Hanno Becker955a5c92019-07-10 17:12:07 +01004713 /*
4714 * Fetch record contents from underlying transport.
4715 */
Hanno Beckera3175662019-07-11 12:50:29 +01004716 ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len );
Hanno Beckera8814792019-07-10 15:01:45 +01004717 if( ret != 0 )
4718 {
4719 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
4720 return( ret );
4721 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004722
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004723 ssl->in_left = 0;
Hanno Beckera8814792019-07-10 15:01:45 +01004724 }
4725
4726 /*
4727 * Decrypt record contents.
4728 */
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004729
Hanno Beckerfdf66042019-07-11 13:07:45 +01004730 if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004731 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004732#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02004733 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004734 {
4735 /* Silently discard invalid records */
Hanno Becker82e2a392019-05-03 16:36:59 +01004736 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004737 {
Manuel Pégourié-Gonnard0a885742015-08-04 12:08:35 +02004738 /* Except when waiting for Finished as a bad mac here
4739 * probably means something went wrong in the handshake
4740 * (eg wrong psk used, mitm downgrade attempt, etc.) */
4741 if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
4742 ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
4743 {
4744#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4745 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
4746 {
4747 mbedtls_ssl_send_alert_message( ssl,
4748 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4749 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
4750 }
4751#endif
4752 return( ret );
4753 }
4754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004755#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02004756 if( ssl->conf->badmac_limit != 0 &&
4757 ++ssl->badmac_seen >= ssl->conf->badmac_limit )
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004758 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004759 MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
4760 return( MBEDTLS_ERR_SSL_INVALID_MAC );
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004761 }
4762#endif
4763
Hanno Becker4a810fb2017-05-24 16:27:30 +01004764 /* As above, invalid records cause
4765 * dismissal of the whole datagram. */
4766
4767 ssl->next_record_offset = 0;
4768 ssl->in_left = 0;
4769
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004770 MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
Hanno Becker90333da2017-10-10 11:27:13 +01004771 return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004772 }
4773
4774 return( ret );
4775 }
4776 else
4777#endif
4778 {
4779 /* Error out (and send alert) on invalid records */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004780#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4781 if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004782 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004783 mbedtls_ssl_send_alert_message( ssl,
4784 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4785 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004786 }
4787#endif
4788 return( ret );
4789 }
4790 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004791
Hanno Becker44d89b22019-07-12 09:40:44 +01004792
4793 /* Reset in pointers to default state for TLS/DTLS records,
4794 * assuming no CID and no offset between record content and
4795 * record plaintext. */
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00004796 mbedtls_ssl_update_in_pointers( ssl );
Hanno Becker44d89b22019-07-12 09:40:44 +01004797#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4798 ssl->in_len = ssl->in_cid + rec.cid_len;
4799#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
irwir89af51f2019-09-26 21:04:56 +03004800 ssl->in_iv = ssl->in_len + 2;
Hanno Becker44d89b22019-07-12 09:40:44 +01004801
Hanno Becker8685c822019-07-12 09:37:30 +01004802 /* The record content type may change during decryption,
4803 * so re-read it. */
4804 ssl->in_msgtype = rec.type;
4805 /* Also update the input buffer, because unfortunately
4806 * the server-side ssl_parse_client_hello() reparses the
4807 * record header when receiving a ClientHello initiating
4808 * a renegotiation. */
4809 ssl->in_hdr[0] = rec.type;
4810 ssl->in_msg = rec.buf + rec.data_offset;
4811 ssl->in_msglen = rec.data_len;
Joe Subbianic54e9082021-07-19 11:56:54 +01004812 MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->in_len, 0 );
Hanno Becker8685c822019-07-12 09:37:30 +01004813
Manuel Pégourié-Gonnardc40b6852020-01-03 12:18:49 +01004814#if defined(MBEDTLS_ZLIB_SUPPORT)
4815 if( ssl->transform_in != NULL &&
4816 ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
4817 {
4818 if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
4819 {
4820 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
4821 return( ret );
4822 }
4823
4824 /* Check actual (decompress) record content length against
4825 * configured maximum. */
4826 if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
4827 {
4828 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
4829 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4830 }
4831 }
4832#endif /* MBEDTLS_ZLIB_SUPPORT */
4833
Simon Butcher99000142016-10-13 17:21:01 +01004834 return( 0 );
4835}
4836
4837int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
4838{
Janos Follath865b3eb2019-12-16 11:46:15 +00004839 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher99000142016-10-13 17:21:01 +01004840
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02004841 /*
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004842 * Handle particular types of records
4843 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004844 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker5121ce52009-01-03 21:22:43 +00004845 {
Simon Butcher99000142016-10-13 17:21:01 +01004846 if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
4847 {
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01004848 return( ret );
Simon Butcher99000142016-10-13 17:21:01 +01004849 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004850 }
4851
Hanno Beckere678eaa2018-08-21 14:57:46 +01004852 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004853 {
Hanno Beckere678eaa2018-08-21 14:57:46 +01004854 if( ssl->in_msglen != 1 )
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004855 {
Paul Elliottd48d5c62021-01-07 14:47:05 +00004856 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
Hanno Beckere678eaa2018-08-21 14:57:46 +01004857 ssl->in_msglen ) );
4858 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004859 }
4860
Hanno Beckere678eaa2018-08-21 14:57:46 +01004861 if( ssl->in_msg[0] != 1 )
4862 {
4863 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
4864 ssl->in_msg[0] ) );
4865 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4866 }
4867
4868#if defined(MBEDTLS_SSL_PROTO_DTLS)
4869 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4870 ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
4871 ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
4872 {
4873 if( ssl->handshake == NULL )
4874 {
4875 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
4876 return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
4877 }
4878
4879 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
4880 return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
4881 }
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004882#endif
Hanno Beckere678eaa2018-08-21 14:57:46 +01004883 }
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004885 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
Paul Bakker5121ce52009-01-03 21:22:43 +00004886 {
Angus Gratton1a7a17e2018-06-20 15:43:50 +10004887 if( ssl->in_msglen != 2 )
4888 {
4889 /* Note: Standard allows for more than one 2 byte alert
4890 to be packed in a single message, but Mbed TLS doesn't
4891 currently support this. */
Paul Elliottd48d5c62021-01-07 14:47:05 +00004892 MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
Angus Gratton1a7a17e2018-06-20 15:43:50 +10004893 ssl->in_msglen ) );
4894 return( MBEDTLS_ERR_SSL_INVALID_RECORD );
4895 }
4896
Paul Elliott9f352112020-12-09 14:55:45 +00004897 MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%u:%u]",
Paul Bakker5121ce52009-01-03 21:22:43 +00004898 ssl->in_msg[0], ssl->in_msg[1] ) );
4899
4900 /*
Simon Butcher459a9502015-10-27 16:09:03 +00004901 * Ignore non-fatal alerts, except close_notify and no_renegotiation
Paul Bakker5121ce52009-01-03 21:22:43 +00004902 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004903 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
Paul Bakker5121ce52009-01-03 21:22:43 +00004904 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004905 MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
Paul Bakker2770fbd2012-07-03 13:30:23 +00004906 ssl->in_msg[1] ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004907 return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00004908 }
4909
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004910 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4911 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
Paul Bakker5121ce52009-01-03 21:22:43 +00004912 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004913 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
4914 return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
Paul Bakker5121ce52009-01-03 21:22:43 +00004915 }
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004916
4917#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
4918 if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4919 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
4920 {
Hanno Becker90333da2017-10-10 11:27:13 +01004921 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004922 /* Will be handled when trying to parse ServerHello */
4923 return( 0 );
4924 }
4925#endif
4926
4927#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
4928 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
4929 ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
4930 ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4931 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
4932 {
4933 MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
4934 /* Will be handled in mbedtls_ssl_parse_certificate() */
4935 return( 0 );
4936 }
4937#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
4938
4939 /* Silently ignore: fetch new message */
Simon Butcher99000142016-10-13 17:21:01 +01004940 return MBEDTLS_ERR_SSL_NON_FATAL;
Paul Bakker5121ce52009-01-03 21:22:43 +00004941 }
4942
Hanno Beckerc76c6192017-06-06 10:03:17 +01004943#if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker37ae9522019-05-03 16:54:26 +01004944 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Hanno Beckerc76c6192017-06-06 10:03:17 +01004945 {
Hanno Becker37ae9522019-05-03 16:54:26 +01004946 /* Drop unexpected ApplicationData records,
4947 * except at the beginning of renegotiations */
4948 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
4949 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
4950#if defined(MBEDTLS_SSL_RENEGOTIATION)
4951 && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
4952 ssl->state == MBEDTLS_SSL_SERVER_HELLO )
Hanno Beckerc76c6192017-06-06 10:03:17 +01004953#endif
Hanno Becker37ae9522019-05-03 16:54:26 +01004954 )
4955 {
4956 MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
4957 return( MBEDTLS_ERR_SSL_NON_FATAL );
4958 }
4959
4960 if( ssl->handshake != NULL &&
4961 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
4962 {
Hanno Beckerce5f5fd2020-02-05 10:47:44 +00004963 mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
Hanno Becker37ae9522019-05-03 16:54:26 +01004964 }
4965 }
Hanno Becker4a4af9f2019-05-08 16:26:21 +01004966#endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Beckerc76c6192017-06-06 10:03:17 +01004967
Paul Bakker5121ce52009-01-03 21:22:43 +00004968 return( 0 );
4969}
4970
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004971int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00004972{
irwir6c0da642019-09-26 21:07:41 +03004973 return( mbedtls_ssl_send_alert_message( ssl,
4974 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4975 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00004976}
4977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004978int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
Paul Bakker0a925182012-04-16 06:46:41 +00004979 unsigned char level,
4980 unsigned char message )
4981{
Janos Follath865b3eb2019-12-16 11:46:15 +00004982 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker0a925182012-04-16 06:46:41 +00004983
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02004984 if( ssl == NULL || ssl->conf == NULL )
4985 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
4986
Hanno Beckerd9c66c02018-08-06 11:35:16 +01004987 if( ssl->out_left != 0 )
4988 return( mbedtls_ssl_flush_output( ssl ) );
4989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004990 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
Gilles Peskine1cc8e342017-05-03 16:28:34 +02004991 MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
Paul Bakker0a925182012-04-16 06:46:41 +00004992
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004993 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
Paul Bakker0a925182012-04-16 06:46:41 +00004994 ssl->out_msglen = 2;
4995 ssl->out_msg[0] = level;
4996 ssl->out_msg[1] = message;
4997
Hanno Becker67bc7c32018-08-06 11:33:50 +01004998 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
Paul Bakker0a925182012-04-16 06:46:41 +00004999 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005000 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker0a925182012-04-16 06:46:41 +00005001 return( ret );
5002 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005003 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
Paul Bakker0a925182012-04-16 06:46:41 +00005004
5005 return( 0 );
5006}
5007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005008int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00005009{
Janos Follath865b3eb2019-12-16 11:46:15 +00005010 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00005011
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005012 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005014 ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
Paul Bakker5121ce52009-01-03 21:22:43 +00005015 ssl->out_msglen = 1;
5016 ssl->out_msg[0] = 1;
5017
Paul Bakker5121ce52009-01-03 21:22:43 +00005018 ssl->state++;
5019
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02005020 if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005021 {
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02005022 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005023 return( ret );
5024 }
5025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005026 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005027
5028 return( 0 );
5029}
5030
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005031int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00005032{
Janos Follath865b3eb2019-12-16 11:46:15 +00005033 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00005034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005035 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005036
Hanno Becker327c93b2018-08-15 13:56:18 +01005037 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005038 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005039 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005040 return( ret );
5041 }
5042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005043 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
Paul Bakker5121ce52009-01-03 21:22:43 +00005044 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005045 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
Gilles Peskine1cc8e342017-05-03 16:28:34 +02005046 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5047 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005048 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00005049 }
5050
Hanno Beckere678eaa2018-08-21 14:57:46 +01005051 /* CCS records are only accepted if they have length 1 and content '1',
5052 * so we don't need to check this here. */
Paul Bakker5121ce52009-01-03 21:22:43 +00005053
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005054 /*
5055 * Switch to our negotiated transform and session parameters for inbound
5056 * data.
5057 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005058 MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005059 ssl->transform_in = ssl->transform_negotiate;
5060 ssl->session_in = ssl->session_negotiate;
5061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005062#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005063 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005064 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005065#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Hanno Becker7e8e6a62020-02-05 10:45:48 +00005066 mbedtls_ssl_dtls_replay_reset( ssl );
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005067#endif
5068
5069 /* Increment epoch */
5070 if( ++ssl->in_epoch == 0 )
5071 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005072 MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
Gilles Peskine1cc8e342017-05-03 16:28:34 +02005073 /* This is highly unlikely to happen for legitimate reasons, so
5074 treat it as an attack and don't send an alert. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005075 return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005076 }
5077 }
5078 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005079#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005080 memset( ssl->in_ctr, 0, 8 );
5081
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00005082 mbedtls_ssl_update_in_pointers( ssl );
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005084#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
5085 if( mbedtls_ssl_hw_record_activate != NULL )
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005086 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005087 if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005088 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005089 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
Gilles Peskine1cc8e342017-05-03 16:28:34 +02005090 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5091 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005092 return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02005093 }
5094 }
5095#endif
5096
Paul Bakker5121ce52009-01-03 21:22:43 +00005097 ssl->state++;
5098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005099 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005100
5101 return( 0 );
5102}
5103
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005104/* Once ssl->out_hdr as the address of the beginning of the
5105 * next outgoing record is set, deduce the other pointers.
5106 *
5107 * Note: For TLS, we save the implicit record sequence number
5108 * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
5109 * and the caller has to make sure there's space for this.
5110 */
5111
Hanno Beckerc0eefa82020-05-28 07:17:36 +01005112static size_t ssl_transform_get_explicit_iv_len(
5113 mbedtls_ssl_transform const *transform )
5114{
5115 if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
5116 return( 0 );
5117
5118 return( transform->ivlen - transform->fixed_ivlen );
5119}
5120
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00005121void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
5122 mbedtls_ssl_transform *transform )
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005123{
5124#if defined(MBEDTLS_SSL_PROTO_DTLS)
5125 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5126 {
5127 ssl->out_ctr = ssl->out_hdr + 3;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005128#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005129 ssl->out_cid = ssl->out_ctr + 8;
5130 ssl->out_len = ssl->out_cid;
5131 if( transform != NULL )
5132 ssl->out_len += transform->out_cid_len;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005133#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005134 ssl->out_len = ssl->out_ctr + 8;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005135#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005136 ssl->out_iv = ssl->out_len + 2;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005137 }
5138 else
5139#endif
5140 {
5141 ssl->out_ctr = ssl->out_hdr - 8;
5142 ssl->out_len = ssl->out_hdr + 3;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005143#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4c3eb7c2019-05-08 16:43:21 +01005144 ssl->out_cid = ssl->out_len;
5145#endif
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005146 ssl->out_iv = ssl->out_hdr + 5;
5147 }
5148
Hanno Beckerc0eefa82020-05-28 07:17:36 +01005149 ssl->out_msg = ssl->out_iv;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005150 /* Adjust out_msg to make space for explicit IV, if used. */
Hanno Beckerc0eefa82020-05-28 07:17:36 +01005151 if( transform != NULL )
5152 ssl->out_msg += ssl_transform_get_explicit_iv_len( transform );
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005153}
5154
5155/* Once ssl->in_hdr as the address of the beginning of the
5156 * next incoming record is set, deduce the other pointers.
5157 *
5158 * Note: For TLS, we save the implicit record sequence number
5159 * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
5160 * and the caller has to make sure there's space for this.
5161 */
5162
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00005163void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl )
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005164{
Hanno Becker79594fd2019-05-08 09:38:41 +01005165 /* This function sets the pointers to match the case
5166 * of unprotected TLS/DTLS records, with both ssl->in_iv
5167 * and ssl->in_msg pointing to the beginning of the record
5168 * content.
5169 *
5170 * When decrypting a protected record, ssl->in_msg
5171 * will be shifted to point to the beginning of the
5172 * record plaintext.
5173 */
5174
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005175#if defined(MBEDTLS_SSL_PROTO_DTLS)
5176 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5177 {
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005178 /* This sets the header pointers to match records
5179 * without CID. When we receive a record containing
5180 * a CID, the fields are shifted accordingly in
5181 * ssl_parse_record_header(). */
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005182 ssl->in_ctr = ssl->in_hdr + 3;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005183#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005184 ssl->in_cid = ssl->in_ctr + 8;
5185 ssl->in_len = ssl->in_cid; /* Default: no CID */
Hanno Beckera0e20d02019-05-15 14:03:01 +01005186#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005187 ssl->in_len = ssl->in_ctr + 8;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005188#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01005189 ssl->in_iv = ssl->in_len + 2;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005190 }
5191 else
5192#endif
5193 {
5194 ssl->in_ctr = ssl->in_hdr - 8;
5195 ssl->in_len = ssl->in_hdr + 3;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005196#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4c3eb7c2019-05-08 16:43:21 +01005197 ssl->in_cid = ssl->in_len;
5198#endif
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005199 ssl->in_iv = ssl->in_hdr + 5;
5200 }
5201
Hanno Becker79594fd2019-05-08 09:38:41 +01005202 /* This will be adjusted at record decryption time. */
5203 ssl->in_msg = ssl->in_iv;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01005204}
5205
Paul Bakker5121ce52009-01-03 21:22:43 +00005206/*
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02005207 * Setup an SSL context
5208 */
Hanno Becker2a43f6f2018-08-10 11:12:52 +01005209
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00005210void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
Hanno Becker2a43f6f2018-08-10 11:12:52 +01005211{
5212 /* Set the incoming and outgoing record pointers. */
5213#if defined(MBEDTLS_SSL_PROTO_DTLS)
5214 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
5215 {
5216 ssl->out_hdr = ssl->out_buf;
5217 ssl->in_hdr = ssl->in_buf;
5218 }
5219 else
5220#endif /* MBEDTLS_SSL_PROTO_DTLS */
5221 {
5222 ssl->out_hdr = ssl->out_buf + 8;
5223 ssl->in_hdr = ssl->in_buf + 8;
5224 }
5225
5226 /* Derive other internal pointers. */
Hanno Becker3e6f8ab2020-02-05 10:40:57 +00005227 mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
5228 mbedtls_ssl_update_in_pointers ( ssl );
Hanno Becker2a43f6f2018-08-10 11:12:52 +01005229}
5230
Paul Bakker5121ce52009-01-03 21:22:43 +00005231/*
5232 * SSL get accessors
5233 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005234size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00005235{
5236 return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
5237}
5238
Hanno Becker8b170a02017-10-10 11:51:19 +01005239int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
5240{
5241 /*
5242 * Case A: We're currently holding back
5243 * a message for further processing.
5244 */
5245
5246 if( ssl->keep_current_message == 1 )
5247 {
Hanno Beckera6fb0892017-10-23 13:17:48 +01005248 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
Hanno Becker8b170a02017-10-10 11:51:19 +01005249 return( 1 );
5250 }
5251
5252 /*
5253 * Case B: Further records are pending in the current datagram.
5254 */
5255
5256#if defined(MBEDTLS_SSL_PROTO_DTLS)
5257 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5258 ssl->in_left > ssl->next_record_offset )
5259 {
Hanno Beckera6fb0892017-10-23 13:17:48 +01005260 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
Hanno Becker8b170a02017-10-10 11:51:19 +01005261 return( 1 );
5262 }
5263#endif /* MBEDTLS_SSL_PROTO_DTLS */
5264
5265 /*
5266 * Case C: A handshake message is being processed.
5267 */
5268
Hanno Becker8b170a02017-10-10 11:51:19 +01005269 if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
5270 {
Hanno Beckera6fb0892017-10-23 13:17:48 +01005271 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
Hanno Becker8b170a02017-10-10 11:51:19 +01005272 return( 1 );
5273 }
5274
5275 /*
5276 * Case D: An application data message is being processed
5277 */
5278 if( ssl->in_offt != NULL )
5279 {
Hanno Beckera6fb0892017-10-23 13:17:48 +01005280 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
Hanno Becker8b170a02017-10-10 11:51:19 +01005281 return( 1 );
5282 }
5283
5284 /*
5285 * In all other cases, the rest of the message can be dropped.
Hanno Beckerc573ac32018-08-28 17:15:25 +01005286 * As in ssl_get_next_record, this needs to be adapted if
Hanno Becker8b170a02017-10-10 11:51:19 +01005287 * we implement support for multiple alerts in single records.
5288 */
5289
5290 MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
5291 return( 0 );
5292}
5293
Paul Bakker43ca69c2011-01-15 17:35:19 +00005294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005295int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005296{
Hanno Becker3136ede2018-08-17 15:28:19 +01005297 size_t transform_expansion = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005298 const mbedtls_ssl_transform *transform = ssl->transform_out;
Hanno Becker5b559ac2018-08-03 09:40:07 +01005299 unsigned block_size;
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005300
Hanno Becker5903de42019-05-03 14:46:38 +01005301 size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl );
5302
Hanno Becker78640902018-08-13 16:35:15 +01005303 if( transform == NULL )
Hanno Becker5903de42019-05-03 14:46:38 +01005304 return( (int) out_hdr_len );
Hanno Becker78640902018-08-13 16:35:15 +01005305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005306#if defined(MBEDTLS_ZLIB_SUPPORT)
5307 if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
5308 return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005309#endif
5310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005311 switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005312 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005313 case MBEDTLS_MODE_GCM:
5314 case MBEDTLS_MODE_CCM:
Hanno Becker5b559ac2018-08-03 09:40:07 +01005315 case MBEDTLS_MODE_CHACHAPOLY:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005316 case MBEDTLS_MODE_STREAM:
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005317 transform_expansion = transform->minlen;
5318 break;
5319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005320 case MBEDTLS_MODE_CBC:
Hanno Becker5b559ac2018-08-03 09:40:07 +01005321
5322 block_size = mbedtls_cipher_get_block_size(
5323 &transform->cipher_ctx_enc );
5324
Hanno Becker3136ede2018-08-17 15:28:19 +01005325 /* Expansion due to the addition of the MAC. */
5326 transform_expansion += transform->maclen;
5327
5328 /* Expansion due to the addition of CBC padding;
5329 * Theoretically up to 256 bytes, but we never use
5330 * more than the block size of the underlying cipher. */
5331 transform_expansion += block_size;
5332
5333 /* For TLS 1.1 or higher, an explicit IV is added
5334 * after the record header. */
Hanno Becker5b559ac2018-08-03 09:40:07 +01005335#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
5336 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
Hanno Becker3136ede2018-08-17 15:28:19 +01005337 transform_expansion += block_size;
Hanno Becker5b559ac2018-08-03 09:40:07 +01005338#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Becker3136ede2018-08-17 15:28:19 +01005339
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005340 break;
5341
5342 default:
Manuel Pégourié-Gonnardcb0d2122015-07-22 11:52:11 +02005343 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005344 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005345 }
5346
Hanno Beckera0e20d02019-05-15 14:03:01 +01005347#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker6cbad552019-05-08 15:40:11 +01005348 if( transform->out_cid_len != 0 )
5349 transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
Hanno Beckera0e20d02019-05-15 14:03:01 +01005350#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker6cbad552019-05-08 15:40:11 +01005351
Hanno Becker5903de42019-05-03 14:46:38 +01005352 return( (int)( out_hdr_len + transform_expansion ) );
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02005353}
5354
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005355#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01005356/*
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005357 * Check record counters and renegotiate if they're above the limit.
5358 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005359MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005360static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005361{
Hanno Beckerdd772292020-02-05 10:38:31 +00005362 size_t ep_len = mbedtls_ssl_ep_len( ssl );
Andres AG2196c7f2016-12-15 17:01:16 +00005363 int in_ctr_cmp;
5364 int out_ctr_cmp;
5365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005366 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
5367 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005368 ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005369 {
5370 return( 0 );
5371 }
5372
Andres AG2196c7f2016-12-15 17:01:16 +00005373 in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
5374 ssl->conf->renego_period + ep_len, 8 - ep_len );
Hanno Becker19859472018-08-06 09:40:20 +01005375 out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
Andres AG2196c7f2016-12-15 17:01:16 +00005376 ssl->conf->renego_period + ep_len, 8 - ep_len );
5377
5378 if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005379 {
5380 return( 0 );
5381 }
5382
Manuel Pégourié-Gonnardcb0d2122015-07-22 11:52:11 +02005383 MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005384 return( mbedtls_ssl_renegotiate( ssl ) );
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005385}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005386#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakker48916f92012-09-16 19:57:18 +00005387
5388/*
Paul Bakker5121ce52009-01-03 21:22:43 +00005389 * Receive application data decrypted from the SSL layer
5390 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005391int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
Paul Bakker5121ce52009-01-03 21:22:43 +00005392{
Janos Follath865b3eb2019-12-16 11:46:15 +00005393 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00005394 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +00005395
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005396 if( ssl == NULL || ssl->conf == NULL )
5397 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5398
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005399 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005401#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005402 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02005403 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005404 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02005405 return( ret );
5406
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005407 if( ssl->handshake != NULL &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005408 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005409 {
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02005410 if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005411 return( ret );
5412 }
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02005413 }
5414#endif
5415
Hanno Becker4a810fb2017-05-24 16:27:30 +01005416 /*
5417 * Check if renegotiation is necessary and/or handshake is
5418 * in process. If yes, perform/continue, and fall through
5419 * if an unexpected packet is received while the client
5420 * is waiting for the ServerHello.
5421 *
5422 * (There is no equivalent to the last condition on
5423 * the server-side as it is not treated as within
5424 * a handshake while waiting for the ClientHello
5425 * after a renegotiation request.)
5426 */
5427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005428#if defined(MBEDTLS_SSL_RENEGOTIATION)
Hanno Becker4a810fb2017-05-24 16:27:30 +01005429 ret = ssl_check_ctr_renegotiate( ssl );
5430 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5431 ret != 0 )
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005432 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005433 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01005434 return( ret );
5435 }
5436#endif
5437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005438 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
Paul Bakker5121ce52009-01-03 21:22:43 +00005439 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005440 ret = mbedtls_ssl_handshake( ssl );
Hanno Becker4a810fb2017-05-24 16:27:30 +01005441 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5442 ret != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005443 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005444 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005445 return( ret );
5446 }
5447 }
5448
Hanno Beckere41158b2017-10-23 13:30:32 +01005449 /* Loop as long as no application data record is available */
Hanno Becker90333da2017-10-10 11:27:13 +01005450 while( ssl->in_offt == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +00005451 {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02005452 /* Start timer if not already running */
Manuel Pégourié-Gonnard545102e2015-05-13 17:28:43 +02005453 if( ssl->f_get_timer != NULL &&
5454 ssl->f_get_timer( ssl->p_timer ) == -1 )
5455 {
Hanno Becker0f57a652020-02-05 10:37:26 +00005456 mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout );
Manuel Pégourié-Gonnard545102e2015-05-13 17:28:43 +02005457 }
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02005458
Hanno Becker327c93b2018-08-15 13:56:18 +01005459 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005460 {
Hanno Becker4a810fb2017-05-24 16:27:30 +01005461 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
5462 return( 0 );
Paul Bakker831a7552011-05-18 13:32:51 +00005463
Hanno Becker4a810fb2017-05-24 16:27:30 +01005464 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
5465 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005466 }
5467
5468 if( ssl->in_msglen == 0 &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005469 ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
Paul Bakker5121ce52009-01-03 21:22:43 +00005470 {
5471 /*
5472 * OpenSSL sends empty messages to randomize the IV
5473 */
Hanno Becker327c93b2018-08-15 13:56:18 +01005474 if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005475 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005476 if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
Paul Bakker831a7552011-05-18 13:32:51 +00005477 return( 0 );
5478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005479 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005480 return( ret );
5481 }
5482 }
5483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005484 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
Paul Bakker48916f92012-09-16 19:57:18 +00005485 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005486 MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
Paul Bakker48916f92012-09-16 19:57:18 +00005487
Hanno Becker4a810fb2017-05-24 16:27:30 +01005488 /*
5489 * - For client-side, expect SERVER_HELLO_REQUEST.
5490 * - For server-side, expect CLIENT_HELLO.
5491 * - Fail (TLS) or silently drop record (DTLS) in other cases.
5492 */
5493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005494#if defined(MBEDTLS_SSL_CLI_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005495 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005496 ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
Hanno Becker4a810fb2017-05-24 16:27:30 +01005497 ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
Paul Bakker48916f92012-09-16 19:57:18 +00005498 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005499 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005500
5501 /* With DTLS, drop the packet (probably from last handshake) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005502#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005503 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Hanno Becker90333da2017-10-10 11:27:13 +01005504 {
5505 continue;
5506 }
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005507#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005508 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005509 }
Hanno Becker4a810fb2017-05-24 16:27:30 +01005510#endif /* MBEDTLS_SSL_CLI_C */
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005511
Hanno Becker4a810fb2017-05-24 16:27:30 +01005512#if defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005513 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005514 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005515 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005516 MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005517
5518 /* With DTLS, drop the packet (probably from last handshake) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005519#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005520 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Hanno Becker90333da2017-10-10 11:27:13 +01005521 {
5522 continue;
5523 }
Manuel Pégourié-Gonnard990f9e42014-09-06 12:27:02 +02005524#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005525 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker48916f92012-09-16 19:57:18 +00005526 }
Hanno Becker4a810fb2017-05-24 16:27:30 +01005527#endif /* MBEDTLS_SSL_SRV_C */
5528
Hanno Becker21df7f92017-10-17 11:03:26 +01005529#if defined(MBEDTLS_SSL_RENEGOTIATION)
Hanno Becker4a810fb2017-05-24 16:27:30 +01005530 /* Determine whether renegotiation attempt should be accepted */
Hanno Beckerb4ff0aa2017-10-17 11:03:04 +01005531 if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
5532 ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
5533 ssl->conf->allow_legacy_renegotiation ==
5534 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
5535 {
5536 /*
5537 * Accept renegotiation request
5538 */
Paul Bakker48916f92012-09-16 19:57:18 +00005539
Hanno Beckerb4ff0aa2017-10-17 11:03:04 +01005540 /* DTLS clients need to know renego is server-initiated */
5541#if defined(MBEDTLS_SSL_PROTO_DTLS)
5542 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5543 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
5544 {
5545 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
5546 }
5547#endif
Hanno Becker40cdaa12020-02-05 10:48:27 +00005548 ret = mbedtls_ssl_start_renegotiation( ssl );
Hanno Beckerb4ff0aa2017-10-17 11:03:04 +01005549 if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5550 ret != 0 )
5551 {
Hanno Becker40cdaa12020-02-05 10:48:27 +00005552 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation",
5553 ret );
Hanno Beckerb4ff0aa2017-10-17 11:03:04 +01005554 return( ret );
5555 }
5556 }
5557 else
Hanno Becker21df7f92017-10-17 11:03:26 +01005558#endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakker48916f92012-09-16 19:57:18 +00005559 {
Hanno Becker4a810fb2017-05-24 16:27:30 +01005560 /*
5561 * Refuse renegotiation
5562 */
5563
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005564 MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
Paul Bakker48916f92012-09-16 19:57:18 +00005565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005566#if defined(MBEDTLS_SSL_PROTO_SSL3)
5567 if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
Paul Bakker48916f92012-09-16 19:57:18 +00005568 {
Gilles Peskine92e44262017-05-10 17:27:49 +02005569 /* SSLv3 does not have a "no_renegotiation" warning, so
5570 we send a fatal alert and abort the connection. */
5571 mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5572 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
5573 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00005574 }
5575 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005576#endif /* MBEDTLS_SSL_PROTO_SSL3 */
5577#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
5578 defined(MBEDTLS_SSL_PROTO_TLS1_2)
5579 if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00005580 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005581 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
5582 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5583 MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00005584 {
5585 return( ret );
5586 }
Paul Bakker48916f92012-09-16 19:57:18 +00005587 }
Paul Bakkerd2f068e2013-08-27 21:19:20 +02005588 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005589#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
5590 MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker577e0062013-08-28 11:57:20 +02005591 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005592 MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
5593 return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
Paul Bakker577e0062013-08-28 11:57:20 +02005594 }
Paul Bakker48916f92012-09-16 19:57:18 +00005595 }
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02005596
Hanno Becker90333da2017-10-10 11:27:13 +01005597 /* At this point, we don't know whether the renegotiation has been
5598 * completed or not. The cases to consider are the following:
5599 * 1) The renegotiation is complete. In this case, no new record
5600 * has been read yet.
5601 * 2) The renegotiation is incomplete because the client received
5602 * an application data record while awaiting the ServerHello.
5603 * 3) The renegotiation is incomplete because the client received
5604 * a non-handshake, non-application data message while awaiting
5605 * the ServerHello.
5606 * In each of these case, looping will be the proper action:
5607 * - For 1), the next iteration will read a new record and check
5608 * if it's application data.
5609 * - For 2), the loop condition isn't satisfied as application data
5610 * is present, hence continue is the same as break
5611 * - For 3), the loop condition is satisfied and read_record
5612 * will re-deliver the message that was held back by the client
5613 * when expecting the ServerHello.
5614 */
5615 continue;
Paul Bakker48916f92012-09-16 19:57:18 +00005616 }
Hanno Becker21df7f92017-10-17 11:03:26 +01005617#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005618 else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
Manuel Pégourié-Gonnard6d8404d2013-10-30 16:41:45 +01005619 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005620 if( ssl->conf->renego_max_records >= 0 )
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02005621 {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005622 if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02005623 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005624 MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02005625 "but not honored by client" ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005626 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02005627 }
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02005628 }
Manuel Pégourié-Gonnard6d8404d2013-10-30 16:41:45 +01005629 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005630#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02005631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005632 /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
5633 if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02005634 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005635 MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01005636 return( MBEDTLS_ERR_SSL_WANT_READ );
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02005637 }
5638
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005639 if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
Paul Bakker5121ce52009-01-03 21:22:43 +00005640 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005641 MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
5642 return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +00005643 }
5644
5645 ssl->in_offt = ssl->in_msg;
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02005646
Manuel Pégourié-Gonnardba958b82014-10-09 16:13:44 +02005647 /* We're going to return something now, cancel timer,
5648 * except if handshake (renegotiation) is in progress */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005649 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
Hanno Becker0f57a652020-02-05 10:37:26 +00005650 mbedtls_ssl_set_timer( ssl, 0 );
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005651
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02005652#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005653 /* If we requested renego but received AppData, resend HelloRequest.
5654 * Do it now, after setting in_offt, to avoid taking this branch
5655 * again if ssl_write_hello_request() returns WANT_WRITE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005656#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005657 if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005658 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005659 {
Hanno Becker786300f2020-02-05 10:46:40 +00005660 if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005661 {
Hanno Becker786300f2020-02-05 10:46:40 +00005662 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
5663 ret );
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005664 return( ret );
5665 }
5666 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005667#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
Hanno Becker4a810fb2017-05-24 16:27:30 +01005668#endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00005669 }
5670
5671 n = ( len < ssl->in_msglen )
5672 ? len : ssl->in_msglen;
5673
5674 memcpy( buf, ssl->in_offt, n );
5675 ssl->in_msglen -= n;
5676
gabor-mezei-arma3214132020-07-15 10:55:00 +02005677 /* Zeroising the plaintext buffer to erase unused application data
5678 from the memory. */
5679 mbedtls_platform_zeroize( ssl->in_offt, n );
5680
Paul Bakker5121ce52009-01-03 21:22:43 +00005681 if( ssl->in_msglen == 0 )
Hanno Becker4a810fb2017-05-24 16:27:30 +01005682 {
5683 /* all bytes consumed */
Paul Bakker5121ce52009-01-03 21:22:43 +00005684 ssl->in_offt = NULL;
Hanno Beckerbdf39052017-06-09 10:42:03 +01005685 ssl->keep_current_message = 0;
Hanno Becker4a810fb2017-05-24 16:27:30 +01005686 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005687 else
Hanno Becker4a810fb2017-05-24 16:27:30 +01005688 {
Paul Bakker5121ce52009-01-03 21:22:43 +00005689 /* more data available */
5690 ssl->in_offt += n;
Hanno Becker4a810fb2017-05-24 16:27:30 +01005691 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005693 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005694
Paul Bakker23986e52011-04-24 08:57:21 +00005695 return( (int) n );
Paul Bakker5121ce52009-01-03 21:22:43 +00005696}
5697
5698/*
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005699 * Send application data to be encrypted by the SSL layer, taking care of max
5700 * fragment length and buffer size.
5701 *
5702 * According to RFC 5246 Section 6.2.1:
5703 *
5704 * Zero-length fragments of Application data MAY be sent as they are
5705 * potentially useful as a traffic analysis countermeasure.
5706 *
5707 * Therefore, it is possible that the input message length is 0 and the
5708 * corresponding return code is 0 on success.
Paul Bakker5121ce52009-01-03 21:22:43 +00005709 */
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005710MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005711static int ssl_write_real( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005712 const unsigned char *buf, size_t len )
Paul Bakker5121ce52009-01-03 21:22:43 +00005713{
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005714 int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
5715 const size_t max_len = (size_t) ret;
5716
5717 if( ret < 0 )
5718 {
5719 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
5720 return( ret );
5721 }
5722
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005723 if( len > max_len )
5724 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005725#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02005726 if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005727 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005728 MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
Paul Elliottd48d5c62021-01-07 14:47:05 +00005729 "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
5730 " > %" MBEDTLS_PRINTF_SIZET,
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005731 len, max_len ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005732 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005733 }
5734 else
5735#endif
5736 len = max_len;
5737 }
Paul Bakker887bd502011-06-08 13:10:54 +00005738
Paul Bakker5121ce52009-01-03 21:22:43 +00005739 if( ssl->out_left != 0 )
5740 {
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005741 /*
5742 * The user has previously tried to send the data and
5743 * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
5744 * written. In this case, we expect the high-level write function
5745 * (e.g. mbedtls_ssl_write()) to be called with the same parameters
5746 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005747 if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005748 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005749 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005750 return( ret );
5751 }
5752 }
Paul Bakker887bd502011-06-08 13:10:54 +00005753 else
Paul Bakker1fd00bf2011-03-14 20:50:15 +00005754 {
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005755 /*
5756 * The user is trying to send a message the first time, so we need to
5757 * copy the data into the internal buffers and setup the data structure
5758 * to keep track of partial writes
5759 */
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005760 ssl->out_msglen = len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005761 ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005762 memcpy( ssl->out_msg, buf, len );
Paul Bakker887bd502011-06-08 13:10:54 +00005763
Hanno Becker67bc7c32018-08-06 11:33:50 +01005764 if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
Paul Bakker887bd502011-06-08 13:10:54 +00005765 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005766 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
Paul Bakker887bd502011-06-08 13:10:54 +00005767 return( ret );
5768 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005769 }
5770
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005771 return( (int) len );
Paul Bakker5121ce52009-01-03 21:22:43 +00005772}
5773
5774/*
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005775 * Write application data, doing 1/n-1 splitting if necessary.
5776 *
5777 * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01005778 * then the caller will call us again with the same arguments, so
Hanno Becker2b187c42017-09-18 14:58:11 +01005779 * remember whether we already did the split or not.
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005780 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005781#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Manuel Pégourié-Gonnardd904d662022-06-17 10:24:00 +02005782MBEDTLS_CHECK_RETURN_CRITICAL
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005783static int ssl_write_split( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005784 const unsigned char *buf, size_t len )
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005785{
Janos Follath865b3eb2019-12-16 11:46:15 +00005786 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005787
Manuel Pégourié-Gonnard17eab2b2015-05-05 16:34:53 +01005788 if( ssl->conf->cbc_record_splitting ==
5789 MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
Manuel Pégourié-Gonnardcfa477e2015-01-07 14:50:54 +01005790 len <= 1 ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005791 ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
5792 mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
5793 != MBEDTLS_MODE_CBC )
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005794 {
5795 return( ssl_write_real( ssl, buf, len ) );
5796 }
5797
5798 if( ssl->split_done == 0 )
5799 {
Manuel Pégourié-Gonnarda852cf42015-01-13 20:56:15 +01005800 if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005801 return( ret );
Manuel Pégourié-Gonnarda852cf42015-01-13 20:56:15 +01005802 ssl->split_done = 1;
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005803 }
5804
Manuel Pégourié-Gonnarda852cf42015-01-13 20:56:15 +01005805 if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
5806 return( ret );
5807 ssl->split_done = 0;
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005808
5809 return( ret + 1 );
5810}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005811#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
Manuel Pégourié-Gonnardd76314c2015-01-07 12:39:44 +01005812
5813/*
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005814 * Write application data (public-facing wrapper)
5815 */
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005816int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005817{
Janos Follath865b3eb2019-12-16 11:46:15 +00005818 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005819
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005820 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005821
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005822 if( ssl == NULL || ssl->conf == NULL )
5823 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5824
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005825#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005826 if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
5827 {
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005828 MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005829 return( ret );
5830 }
5831#endif
5832
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005833 if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005834 {
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005835 if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005836 {
Manuel Pégourié-Gonnard151dc772015-05-14 13:55:51 +02005837 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005838 return( ret );
5839 }
5840 }
5841
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005842#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005843 ret = ssl_write_split( ssl, buf, len );
5844#else
5845 ret = ssl_write_real( ssl, buf, len );
5846#endif
5847
Manuel Pégourié-Gonnard144bc222015-04-17 20:39:07 +02005848 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005849
5850 return( ret );
5851}
5852
5853/*
Paul Bakker5121ce52009-01-03 21:22:43 +00005854 * Notify the peer that the connection is being closed
5855 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005856int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
Paul Bakker5121ce52009-01-03 21:22:43 +00005857{
Janos Follath865b3eb2019-12-16 11:46:15 +00005858 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00005859
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005860 if( ssl == NULL || ssl->conf == NULL )
5861 return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
5862
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005863 MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005865 if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
Paul Bakker5121ce52009-01-03 21:22:43 +00005866 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005867 if( ( ret = mbedtls_ssl_send_alert_message( ssl,
5868 MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5869 MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00005870 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005871 MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00005872 return( ret );
5873 }
5874 }
5875
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005876 MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00005877
Manuel Pégourié-Gonnarda13500f2014-08-19 16:14:04 +02005878 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00005879}
5880
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005881void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
Paul Bakker48916f92012-09-16 19:57:18 +00005882{
Paul Bakkeraccaffe2014-06-26 13:37:14 +02005883 if( transform == NULL )
5884 return;
5885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005886#if defined(MBEDTLS_ZLIB_SUPPORT)
Paul Bakker48916f92012-09-16 19:57:18 +00005887 deflateEnd( &transform->ctx_deflate );
5888 inflateEnd( &transform->ctx_inflate );
5889#endif
5890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005891 mbedtls_cipher_free( &transform->cipher_ctx_enc );
5892 mbedtls_cipher_free( &transform->cipher_ctx_dec );
Manuel Pégourié-Gonnardf71e5872013-09-23 17:12:43 +02005893
Hanno Beckerd56ed242018-01-03 15:32:51 +00005894#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005895 mbedtls_md_free( &transform->md_ctx_enc );
5896 mbedtls_md_free( &transform->md_ctx_dec );
Hanno Beckerd56ed242018-01-03 15:32:51 +00005897#endif
Paul Bakker61d113b2013-07-04 11:51:43 +02005898
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -05005899 mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
Paul Bakker48916f92012-09-16 19:57:18 +00005900}
5901
Hanno Becker0271f962018-08-16 13:23:47 +01005902#if defined(MBEDTLS_SSL_PROTO_DTLS)
5903
Hanno Becker533ab5f2020-02-05 10:49:13 +00005904void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
Hanno Becker0271f962018-08-16 13:23:47 +01005905{
5906 unsigned offset;
5907 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
5908
5909 if( hs == NULL )
5910 return;
5911
Hanno Becker283f5ef2018-08-24 09:34:47 +01005912 ssl_free_buffered_record( ssl );
5913
Hanno Becker0271f962018-08-16 13:23:47 +01005914 for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
Hanno Beckere605b192018-08-21 15:59:07 +01005915 ssl_buffering_free_slot( ssl, offset );
5916}
5917
5918static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
5919 uint8_t slot )
5920{
5921 mbedtls_ssl_handshake_params * const hs = ssl->handshake;
5922 mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
Hanno Beckerb309b922018-08-23 13:18:05 +01005923
5924 if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
5925 return;
5926
Hanno Beckere605b192018-08-21 15:59:07 +01005927 if( hs_buf->is_valid == 1 )
Hanno Becker0271f962018-08-16 13:23:47 +01005928 {
Hanno Beckere605b192018-08-21 15:59:07 +01005929 hs->buffering.total_bytes_buffered -= hs_buf->data_len;
Hanno Becker805f2e12018-10-12 16:31:41 +01005930 mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
Hanno Beckere605b192018-08-21 15:59:07 +01005931 mbedtls_free( hs_buf->data );
5932 memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
Hanno Becker0271f962018-08-16 13:23:47 +01005933 }
5934}
5935
5936#endif /* MBEDTLS_SSL_PROTO_DTLS */
5937
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005938/*
5939 * Convert version numbers to/from wire format
5940 * and, for DTLS, to/from TLS equivalent.
5941 *
5942 * For TLS this is the identity.
Brian J Murray1903fb32016-11-06 04:45:15 -08005943 * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005944 * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
5945 * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
5946 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005947void mbedtls_ssl_write_version( int major, int minor, int transport,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005948 unsigned char ver[2] )
5949{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005950#if defined(MBEDTLS_SSL_PROTO_DTLS)
5951 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005952 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005953 if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005954 --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
5955
5956 ver[0] = (unsigned char)( 255 - ( major - 2 ) );
5957 ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
5958 }
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005959 else
5960#else
5961 ((void) transport);
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005962#endif
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005963 {
5964 ver[0] = (unsigned char) major;
5965 ver[1] = (unsigned char) minor;
5966 }
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005967}
5968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005969void mbedtls_ssl_read_version( int *major, int *minor, int transport,
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005970 const unsigned char ver[2] )
5971{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005972#if defined(MBEDTLS_SSL_PROTO_DTLS)
5973 if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005974 {
5975 *major = 255 - ver[0] + 2;
5976 *minor = 255 - ver[1] + 1;
5977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005978 if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005979 ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
5980 }
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005981 else
5982#else
5983 ((void) transport);
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005984#endif
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005985 {
5986 *major = ver[0];
5987 *minor = ver[1];
5988 }
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005989}
5990
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005991#endif /* MBEDTLS_SSL_TLS_C */