blob: ae9ed937c21d8a1b09831edac44fd1dd59b1d932 [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/*
Paul Bakker5121ce52009-01-03 21:22:43 +000021 * http://www.ietf.org/rfc/rfc2246.txt
22 * http://www.ietf.org/rfc/rfc4346.txt
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_SSL_TLS_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# if defined(MBEDTLS_PLATFORM_C)
30# include "mbedtls/platform.h"
31# else
32# include <stdlib.h>
33# define mbedtls_calloc calloc
34# define mbedtls_free free
35# endif
SimonBd5800b72016-04-26 07:43:27 +010036
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020037# include "mbedtls/ssl.h"
38# include "ssl_misc.h"
39# include "mbedtls/debug.h"
40# include "mbedtls/error.h"
41# include "mbedtls/platform_util.h"
42# include "mbedtls/version.h"
Paul Bakker0be444a2013-08-27 21:55:01 +020043
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020044# include "ssl_invasive.h"
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +020045
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020046# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000047
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020048# if defined(MBEDTLS_USE_PSA_CRYPTO)
49# include "mbedtls/psa_util.h"
50# include "psa/crypto.h"
51# endif
Andrzej Kurekd6db9be2019-01-10 05:27:10 -050052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020053# if defined(MBEDTLS_X509_CRT_PARSE_C)
54# include "mbedtls/oid.h"
55# endif
Manuel Pégourié-Gonnard0408fd12014-04-11 11:06:22 +020056
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020057static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
Hanno Becker2a43f6f2018-08-10 11:12:52 +010058
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020059/*
60 * Start a timer.
61 * Passing millisecs = 0 cancels a running timer.
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020062 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020063void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs)
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020064{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020065 if (ssl->f_set_timer == NULL)
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +020066 return;
67
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020068 MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int)millisecs));
69 ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs);
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020070}
71
72/*
73 * Return -1 is timer is expired, 0 if it isn't.
74 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020076{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020077 if (ssl->f_get_timer == NULL)
78 return 0;
Manuel Pégourié-Gonnard2e012912015-05-12 20:55:41 +020079
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 if (ssl->f_get_timer(ssl->p_timer) == 2) {
81 MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired"));
82 return -1;
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +020083 }
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020084
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 return 0;
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020086}
Manuel Pégourié-Gonnarddb2858c2014-09-29 14:04:42 +020087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020088static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
89 unsigned char *buf,
90 size_t len,
91 mbedtls_record *rec);
TRodziewicz4ca18aa2021-05-20 14:46:20 +020092
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020093int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl,
94 unsigned char *buf,
95 size_t buflen)
TRodziewicz4ca18aa2021-05-20 14:46:20 +020096{
97 int ret = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020098 MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record"));
99 MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen);
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200100
101 /* We don't support record checking in TLS because
TRodziewicz2abf03c2021-06-25 14:40:09 +0200102 * there doesn't seem to be a usecase for it.
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200103 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200105 ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
106 goto exit;
107 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108# if defined(MBEDTLS_SSL_PROTO_DTLS)
109 else {
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200110 mbedtls_record rec;
111
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200112 ret = ssl_parse_record_header(ssl, buf, buflen, &rec);
113 if (ret != 0) {
114 MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret);
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200115 goto exit;
116 }
117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200118 if (ssl->transform_in != NULL) {
119 ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec);
120 if (ret != 0) {
121 MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret);
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200122 goto exit;
123 }
124 }
125 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126# endif /* MBEDTLS_SSL_PROTO_DTLS */
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200127
128exit:
129 /* On success, we have decrypted the buffer in-place, so make
130 * sure we don't leak any plaintext data. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200131 mbedtls_platform_zeroize(buf, buflen);
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200132
133 /* For the purpose of this API, treat messages with unexpected CID
134 * as well as such from future epochs as unexpected. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
136 ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200137 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
138 }
139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140 MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record"));
141 return ret;
TRodziewicz4ca18aa2021-05-20 14:46:20 +0200142}
143
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200144# define SSL_DONT_FORCE_FLUSH 0
145# define SSL_FORCE_FLUSH 1
Hanno Becker67bc7c32018-08-06 11:33:50 +0100146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2b1e3542018-08-06 11:19:13 +0100148
Hanno Beckerd5847772018-08-28 10:09:23 +0100149/* Forward declarations for functions related to message buffering. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200150static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, uint8_t slot);
151static void ssl_free_buffered_record(mbedtls_ssl_context *ssl);
152static int ssl_load_buffered_message(mbedtls_ssl_context *ssl);
153static int ssl_load_buffered_record(mbedtls_ssl_context *ssl);
154static int ssl_buffer_message(mbedtls_ssl_context *ssl);
155static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
156 mbedtls_record const *rec);
157static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl);
Hanno Beckerd5847772018-08-28 10:09:23 +0100158
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200159static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl)
Hanno Becker2b1e3542018-08-06 11:19:13 +0100160{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161 size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
162# if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Darryl Greenb33cc762019-11-28 14:29:44 +0000163 size_t out_buf_len = ssl->out_buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200164# else
Darryl Greenb33cc762019-11-28 14:29:44 +0000165 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200166# endif
Hanno Becker2b1e3542018-08-06 11:19:13 +0100167
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 if (mtu != 0 && mtu < out_buf_len)
169 return mtu;
Hanno Becker2b1e3542018-08-06 11:19:13 +0100170
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200171 return out_buf_len;
Hanno Becker2b1e3542018-08-06 11:19:13 +0100172}
173
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200174static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl)
Hanno Becker67bc7c32018-08-06 11:33:50 +0100175{
Hanno Becker11682cc2018-08-22 14:41:02 +0100176 size_t const bytes_written = ssl->out_left;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200177 size_t const mtu = ssl_get_maximum_datagram_size(ssl);
Hanno Becker67bc7c32018-08-06 11:33:50 +0100178
179 /* Double-check that the write-index hasn't gone
180 * past what we can transmit in a single datagram. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200181 if (bytes_written > mtu) {
Hanno Becker67bc7c32018-08-06 11:33:50 +0100182 /* Should never happen... */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200183 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100184 }
185
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186 return ((int)(mtu - bytes_written));
Hanno Becker67bc7c32018-08-06 11:33:50 +0100187}
188
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200189static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl)
Hanno Becker67bc7c32018-08-06 11:33:50 +0100190{
Janos Follath865b3eb2019-12-16 11:46:15 +0000191 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100192 size_t remaining, expansion;
Andrzej Kurek748face2018-10-11 07:20:19 -0400193 size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195# if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
196 const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
Hanno Becker67bc7c32018-08-06 11:33:50 +0100197
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200198 if (max_len > mfl)
Hanno Becker67bc7c32018-08-06 11:33:50 +0100199 max_len = mfl;
Hanno Beckerf4b010e2018-08-24 10:47:29 +0100200
201 /* By the standard (RFC 6066 Sect. 4), the MFL extension
202 * only limits the maximum record payload size, so in theory
203 * we would be allowed to pack multiple records of payload size
204 * MFL into a single datagram. However, this would mean that there's
205 * no way to explicitly communicate MTU restrictions to the peer.
206 *
207 * The following reduction of max_len makes sure that we never
208 * write datagrams larger than MFL + Record Expansion Overhead.
209 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210 if (max_len <= ssl->out_left)
211 return 0;
Hanno Beckerf4b010e2018-08-24 10:47:29 +0100212
213 max_len -= ssl->out_left;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200214# endif
Hanno Becker67bc7c32018-08-06 11:33:50 +0100215
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216 ret = ssl_get_remaining_space_in_datagram(ssl);
217 if (ret < 0)
218 return ret;
219 remaining = (size_t)ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200221 ret = mbedtls_ssl_get_record_expansion(ssl);
222 if (ret < 0)
223 return ret;
224 expansion = (size_t)ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100225
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200226 if (remaining <= expansion)
227 return 0;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100228
229 remaining -= expansion;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200230 if (remaining >= max_len)
Hanno Becker67bc7c32018-08-06 11:33:50 +0100231 remaining = max_len;
232
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200233 return (int)remaining;
Hanno Becker67bc7c32018-08-06 11:33:50 +0100234}
235
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200236/*
237 * Double the retransmit timeout value, within the allowed range,
238 * returning -1 if the maximum value has already been reached.
239 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200240static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200241{
242 uint32_t new_timeout;
243
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200244 if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max)
245 return -1;
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200246
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200247 /* Implement the final paragraph of RFC 6347 section 4.1.1.1
248 * in the following way: after the initial transmission and a first
249 * retransmission, back off to a temporary estimated MTU of 508 bytes.
250 * This value is guaranteed to be deliverable (if not guaranteed to be
251 * delivered) of any compliant IPv4 (and IPv6) network, and should work
252 * on most non-IP stacks too. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200253 if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) {
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200254 ssl->handshake->mtu = 508;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200255 MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes",
256 ssl->handshake->mtu));
Andrzej Kurek6290dae2018-10-05 08:06:01 -0400257 }
Manuel Pégourié-Gonnardb8eec192018-08-20 09:34:02 +0200258
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200259 new_timeout = 2 * ssl->handshake->retransmit_timeout;
260
261 /* Avoid arithmetic overflow and range overflow */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262 if (new_timeout < ssl->handshake->retransmit_timeout ||
263 new_timeout > ssl->conf->hs_timeout_max) {
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200264 new_timeout = ssl->conf->hs_timeout_max;
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200265 }
266
267 ssl->handshake->retransmit_timeout = new_timeout;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 MBEDTLS_SSL_DEBUG_MSG(3,
269 ("update timeout value to %lu millisecs",
270 (unsigned long)ssl->handshake->retransmit_timeout));
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200271
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200272 return 0;
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200273}
274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200276{
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +0200277 ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 MBEDTLS_SSL_DEBUG_MSG(3,
279 ("update timeout value to %lu millisecs",
280 (unsigned long)ssl->handshake->retransmit_timeout));
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200281}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282# endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +0200283
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +0100284/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 * Encryption/decryption functions
Paul Bakkerf7abd422013-04-16 13:15:56 +0200286 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000287
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200288# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \
289 defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
Hanno Becker13996922020-05-28 16:15:19 +0100290
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200291static size_t ssl_compute_padding_length(size_t len, size_t granularity)
Hanno Becker13996922020-05-28 16:15:19 +0100292{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200293 return (granularity - (len + 1) % granularity) % granularity;
Hanno Becker13996922020-05-28 16:15:19 +0100294}
295
Hanno Becker581bc1b2020-05-04 12:20:03 +0100296/* This functions transforms a (D)TLS plaintext fragment and a record content
297 * type into an instance of the (D)TLSInnerPlaintext structure. This is used
298 * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
299 * a record's content type.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100300 *
301 * struct {
302 * opaque content[DTLSPlaintext.length];
303 * ContentType real_type;
304 * uint8 zeros[length_of_padding];
Hanno Becker581bc1b2020-05-04 12:20:03 +0100305 * } (D)TLSInnerPlaintext;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100306 *
307 * Input:
308 * - `content`: The beginning of the buffer holding the
309 * plaintext to be wrapped.
310 * - `*content_size`: The length of the plaintext in Bytes.
311 * - `max_len`: The number of Bytes available starting from
312 * `content`. This must be `>= *content_size`.
313 * - `rec_type`: The desired record content type.
314 *
315 * Output:
Hanno Becker581bc1b2020-05-04 12:20:03 +0100316 * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200317 * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext
318 * structure.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100319 *
320 * Returns:
321 * - `0` on success.
322 * - A negative error code if `max_len` didn't offer enough space
323 * for the expansion.
324 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200325static int ssl_build_inner_plaintext(unsigned char *content,
326 size_t *content_size,
327 size_t remaining,
328 uint8_t rec_type,
329 size_t pad)
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100330{
331 size_t len = *content_size;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100332
333 /* Write real content type */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200334 if (remaining == 0)
335 return -1;
336 content[len] = rec_type;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100337 len++;
338 remaining--;
339
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 if (remaining < pad)
341 return -1;
342 memset(content + len, 0, pad);
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100343 len += pad;
344 remaining -= pad;
345
346 *content_size = len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200347 return 0;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100348}
349
Hanno Becker581bc1b2020-05-04 12:20:03 +0100350/* This function parses a (D)TLSInnerPlaintext structure.
351 * See ssl_build_inner_plaintext() for details. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200352static int ssl_parse_inner_plaintext(unsigned char const *content,
353 size_t *content_size,
354 uint8_t *rec_type)
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100355{
356 size_t remaining = *content_size;
357
358 /* Determine length of padding by skipping zeroes from the back. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200359 do {
360 if (remaining == 0)
361 return -1;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100362 remaining--;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200363 } while (content[remaining] == 0);
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100364
365 *content_size = remaining;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200366 *rec_type = content[remaining];
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100367
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200368 return 0;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100369}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200370# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || \
371 MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100372
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100373/* `add_data` must have size 13 Bytes if the CID extension is disabled,
Hanno Beckerc4a190b2019-05-08 18:15:21 +0100374 * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200375static void ssl_extract_add_data_from_record(unsigned char *add_data,
376 size_t *add_data_len,
377 mbedtls_record *rec,
378 unsigned minor_ver)
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000379{
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100380 /* Quoting RFC 5246 (TLS 1.2):
Hanno Beckercab87e62019-04-29 13:52:53 +0100381 *
382 * additional_data = seq_num + TLSCompressed.type +
383 * TLSCompressed.version + TLSCompressed.length;
384 *
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100385 * For the CID extension, this is extended as follows
386 * (quoting draft-ietf-tls-dtls-connection-id-05,
387 * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
Hanno Beckercab87e62019-04-29 13:52:53 +0100388 *
389 * additional_data = seq_num + DTLSPlaintext.type +
390 * DTLSPlaintext.version +
Hanno Beckerd5aeab12019-05-20 14:50:53 +0100391 * cid +
392 * cid_length +
Hanno Beckercab87e62019-04-29 13:52:53 +0100393 * length_of_DTLSInnerPlaintext;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100394 *
395 * For TLS 1.3, the record sequence number is dropped from the AAD
396 * and encoded within the nonce of the AEAD operation instead.
Hanno Beckercab87e62019-04-29 13:52:53 +0100397 */
398
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100399 unsigned char *cur = add_data;
400
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200401# if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
402 if (minor_ver != MBEDTLS_SSL_MINOR_VERSION_4)
403# endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100404 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405 ((void)minor_ver);
406 memcpy(cur, rec->ctr, sizeof(rec->ctr));
407 cur += sizeof(rec->ctr);
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100408 }
409
410 *cur = rec->type;
411 cur++;
412
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 memcpy(cur, rec->ver, sizeof(rec->ver));
414 cur += sizeof(rec->ver);
Hanno Beckercab87e62019-04-29 13:52:53 +0100415
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200416# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
417 if (rec->cid_len != 0) {
418 memcpy(cur, rec->cid, rec->cid_len);
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100419 cur += rec->cid_len;
420
421 *cur = rec->cid_len;
422 cur++;
423
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200424 cur[0] = (rec->data_len >> 8) & 0xFF;
425 cur[1] = (rec->data_len >> 0) & 0xFF;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100426 cur += 2;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200427 } else
428# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100429 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430 cur[0] = (rec->data_len >> 8) & 0xFF;
431 cur[1] = (rec->data_len >> 0) & 0xFF;
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100432 cur += 2;
Hanno Becker95e4bbc2019-05-09 11:38:24 +0100433 }
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100434
435 *add_data_len = cur - add_data;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000436}
437
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200438# if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || \
439 defined(MBEDTLS_CHACHAPOLY_C)
Hanno Becker17263802020-05-28 07:05:48 +0100440static int ssl_transform_aead_dynamic_iv_is_explicit(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200441 mbedtls_ssl_transform const *transform)
Hanno Beckerdf8be222020-05-21 15:30:57 +0100442{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200443 return transform->ivlen != transform->fixed_ivlen;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100444}
445
Hanno Becker17263802020-05-28 07:05:48 +0100446/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
447 *
448 * Concretely, this occurs in two variants:
449 *
450 * a) Fixed and dynamic IV lengths add up to total IV length, giving
451 * IV = fixed_iv || dynamic_iv
452 *
Hanno Becker15952812020-06-04 13:31:46 +0100453 * This variant is used in TLS 1.2 when used with GCM or CCM.
454 *
Hanno Becker17263802020-05-28 07:05:48 +0100455 * b) Fixed IV lengths matches total IV length, giving
456 * IV = fixed_iv XOR ( 0 || dynamic_iv )
Hanno Becker15952812020-06-04 13:31:46 +0100457 *
458 * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
459 *
460 * See also the documentation of mbedtls_ssl_transform.
Hanno Beckerf486e282020-06-04 13:33:08 +0100461 *
462 * This function has the precondition that
463 *
464 * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
465 *
466 * which has to be ensured by the caller. If this precondition
467 * violated, the behavior of this function is undefined.
Hanno Becker17263802020-05-28 07:05:48 +0100468 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469static void ssl_build_record_nonce(unsigned char *dst_iv,
470 size_t dst_iv_len,
471 unsigned char const *fixed_iv,
472 size_t fixed_iv_len,
473 unsigned char const *dynamic_iv,
474 size_t dynamic_iv_len)
Hanno Becker17263802020-05-28 07:05:48 +0100475{
476 size_t i;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100477
478 /* Start with Fixed IV || 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200479 memset(dst_iv, 0, dst_iv_len);
480 memcpy(dst_iv, fixed_iv, fixed_iv_len);
Hanno Beckerdf8be222020-05-21 15:30:57 +0100481
Hanno Becker17263802020-05-28 07:05:48 +0100482 dst_iv += dst_iv_len - dynamic_iv_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200483 for (i = 0; i < dynamic_iv_len; i++)
Hanno Becker17263802020-05-28 07:05:48 +0100484 dst_iv[i] ^= dynamic_iv[i];
Hanno Beckerdf8be222020-05-21 15:30:57 +0100485}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200486# endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
Hanno Beckerdf8be222020-05-21 15:30:57 +0100487
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200488int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
489 mbedtls_ssl_transform *transform,
490 mbedtls_record *rec,
491 int (*f_rng)(void *, unsigned char *, size_t),
492 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000493{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_cipher_mode_t mode;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100495 int auth_done = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200496 unsigned char *data;
497 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
Hanno Beckercab87e62019-04-29 13:52:53 +0100498 size_t add_data_len;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000499 size_t post_avail;
500
501 /* The SSL context is only used for debugging purposes! */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200502# if !defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +0200503 ssl = NULL; /* make sure we don't use it except for debug */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200504 ((void)ssl);
505# endif
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000506
507 /* The PRNG is used for dynamic IV generation that's used
TRodziewicz0f82ec62021-05-12 17:49:18 +0200508 * for CBC transformations in TLS 1.2. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200509# if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
510 defined(MBEDTLS_SSL_PROTO_TLS1_2))
511 ((void)f_rng);
512 ((void)p_rng);
513# endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200515 MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf"));
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200517 if (transform == NULL) {
518 MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf"));
519 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000520 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200521 if (rec == NULL || rec->buf == NULL || rec->buf_len < rec->data_offset ||
522 rec->buf_len - rec->data_offset < rec->data_len
523# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker43c24b82019-05-01 09:45:57 +0100524 || rec->cid_len != 0
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200525# endif
526 ) {
527 MBEDTLS_SSL_DEBUG_MSG(1,
528 ("bad record structure provided to encrypt_buf"));
529 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100530 }
531
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000532 data = rec->buf + rec->data_offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200533 post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
534 MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload", data,
535 rec->data_len);
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000536
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200537 mode = mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc);
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000538
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200539 if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
540 MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET
541 " too large, maximum %" MBEDTLS_PRINTF_SIZET,
542 rec->data_len,
543 (size_t)MBEDTLS_SSL_OUT_CONTENT_LEN));
544 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000545 }
Manuel Pégourié-Gonnard60346be2014-11-21 11:38:37 +0100546
Hanno Becker92313402020-05-20 13:58:58 +0100547 /* The following two code paths implement the (D)TLSInnerPlaintext
548 * structure present in TLS 1.3 and DTLS 1.2 + CID.
549 *
550 * See ssl_build_inner_plaintext() for more information.
551 *
552 * Note that this changes `rec->data_len`, and hence
553 * `post_avail` needs to be recalculated afterwards.
554 *
555 * Note also that the two code paths cannot occur simultaneously
556 * since they apply to different versions of the protocol. There
557 * is hence no risk of double-addition of the inner plaintext.
558 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200559# if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
560 if (transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4) {
561 size_t padding = ssl_compute_padding_length(
562 rec->data_len, MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
563 if (ssl_build_inner_plaintext(data, &rec->data_len, post_avail,
564 rec->type, padding) != 0) {
565 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Beckerccc13d02020-05-04 12:30:04 +0100566 }
567
568 rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
569 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200570# endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Hanno Beckerccc13d02020-05-04 12:30:04 +0100571
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200572# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckercab87e62019-04-29 13:52:53 +0100573 /*
574 * Add CID information
575 */
576 rec->cid_len = transform->out_cid_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200577 memcpy(rec->cid, transform->out_cid, transform->out_cid_len);
578 MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len);
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100579
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200580 if (rec->cid_len != 0) {
581 size_t padding = ssl_compute_padding_length(
582 rec->data_len, MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100583 /*
Hanno Becker07dc97d2019-05-20 15:08:01 +0100584 * Wrap plaintext into DTLSInnerPlaintext structure.
Hanno Becker581bc1b2020-05-04 12:20:03 +0100585 * See ssl_build_inner_plaintext() for more information.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100586 *
Hanno Becker07dc97d2019-05-20 15:08:01 +0100587 * Note that this changes `rec->data_len`, and hence
588 * `post_avail` needs to be recalculated afterwards.
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100589 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200590 if (ssl_build_inner_plaintext(data, &rec->data_len, post_avail,
591 rec->type, padding) != 0) {
592 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100593 }
594
595 rec->type = MBEDTLS_SSL_MSG_CID;
596 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200597# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +0100598
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599 post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
Hanno Becker8b3eb5a2019-04-29 17:31:37 +0100600
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 /*
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +0100602 * Add MAC before if needed
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200604# if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
605 if (mode == MBEDTLS_MODE_STREAM ||
606 (mode == MBEDTLS_MODE_CBC
607# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
608 && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
609# endif
610 )) {
611 if (post_avail < transform->maclen) {
612 MBEDTLS_SSL_DEBUG_MSG(
613 1, ("Buffer provided for encrypted record not large enough"));
614 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000615 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200616# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
TRodziewicz345165c2021-07-06 13:42:11 +0200617 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
Hanno Becker992b6872017-11-09 18:57:39 +0000618
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200619 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
620 transform->minor_ver);
Hanno Becker992b6872017-11-09 18:57:39 +0000621
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200622 mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data, add_data_len);
623 mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len);
624 mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
625 mbedtls_md_hmac_reset(&transform->md_ctx_enc);
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000626
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200627 memcpy(data + rec->data_len, mac, transform->maclen);
628# endif
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200629
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200630 MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len,
631 transform->maclen);
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200632
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000633 rec->data_len += transform->maclen;
634 post_avail -= transform->maclen;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100635 auth_done++;
Paul Bakker577e0062013-08-28 11:57:20 +0200636 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200637# endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +0200639 /*
640 * Encrypt
641 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200642# if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
643 if (mode == MBEDTLS_MODE_STREAM) {
Janos Follath865b3eb2019-12-16 11:46:15 +0000644 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000645 size_t olen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200646 MBEDTLS_SSL_DEBUG_MSG(
647 3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
648 "including %d bytes of padding",
649 rec->data_len, 0));
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200651 if ((ret = mbedtls_cipher_crypt(
652 &transform->cipher_ctx_enc, transform->iv_enc,
653 transform->ivlen, data, rec->data_len, data, &olen)) != 0) {
654 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
655 return ret;
Paul Bakkerea6ad3f2013-09-02 14:57:01 +0200656 }
657
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200658 if (rec->data_len != olen) {
659 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
660 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakkerea6ad3f2013-09-02 14:57:01 +0200661 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200662 } else
663# endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
Hanno Becker2e24c3b2017-12-27 21:28:58 +0000664
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200665# if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || \
666 defined(MBEDTLS_CHACHAPOLY_C)
667 if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM ||
668 mode == MBEDTLS_MODE_CHACHAPOLY) {
Janos Follath865b3eb2019-12-16 11:46:15 +0000669 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200670 unsigned char iv[12];
Hanno Beckerdf8be222020-05-21 15:30:57 +0100671 unsigned char *dynamic_iv;
672 size_t dynamic_iv_len;
Hanno Becker17263802020-05-28 07:05:48 +0100673 int dynamic_iv_is_explicit =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200674 ssl_transform_aead_dynamic_iv_is_explicit(transform);
Paul Bakkerca4ab492012-04-18 14:23:57 +0000675
Hanno Beckerbd5ed1d2020-05-21 15:26:39 +0100676 /* Check that there's space for the authentication tag. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200677 if (post_avail < transform->taglen) {
678 MBEDTLS_SSL_DEBUG_MSG(
679 1, ("Buffer provided for encrypted record not large enough"));
680 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000681 }
Paul Bakkerca4ab492012-04-18 14:23:57 +0000682
Paul Bakker68884e32013-01-07 18:20:04 +0100683 /*
Hanno Beckerdf8be222020-05-21 15:30:57 +0100684 * Build nonce for AEAD encryption.
685 *
686 * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
687 * part of the IV is prepended to the ciphertext and
688 * can be chosen freely - in particular, it need not
689 * agree with the record sequence number.
690 * However, since ChaChaPoly as well as all AEAD modes
691 * in TLS 1.3 use the record sequence number as the
692 * dynamic part of the nonce, we uniformly use the
693 * record sequence number here in all cases.
Paul Bakker68884e32013-01-07 18:20:04 +0100694 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200695 dynamic_iv = rec->ctr;
696 dynamic_iv_len = sizeof(rec->ctr);
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +0200697
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200698 ssl_build_record_nonce(iv, sizeof(iv), transform->iv_enc,
699 transform->fixed_ivlen, dynamic_iv,
700 dynamic_iv_len);
Manuel Pégourié-Gonnardd056ce02014-10-29 22:29:20 +0100701
Hanno Becker1cb6c2a2020-05-21 15:25:21 +0100702 /*
703 * Build additional data for AEAD encryption.
704 * This depends on the TLS version.
705 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200706 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
707 transform->minor_ver);
Hanno Becker1f10d762019-04-26 13:34:37 +0100708
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200709 MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)", iv, transform->ivlen);
710 MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)", dynamic_iv,
711 dynamic_iv_is_explicit ? dynamic_iv_len : 0);
712 MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", add_data,
713 add_data_len);
714 MBEDTLS_SSL_DEBUG_MSG(
715 3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
716 "including 0 bytes of padding",
717 rec->data_len));
Paul Bakkerca4ab492012-04-18 14:23:57 +0000718
Paul Bakker68884e32013-01-07 18:20:04 +0100719 /*
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +0200720 * Encrypt and authenticate
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +0200721 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000722
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200723 if ((ret = mbedtls_cipher_auth_encrypt_ext(
724 &transform->cipher_ctx_enc, iv, transform->ivlen, add_data,
725 add_data_len, data, rec->data_len, /* src */
726 data, rec->buf_len - (data - rec->buf), /* dst */
727 &rec->data_len, transform->taglen)) != 0) {
728 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret);
729 return ret;
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +0200730 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200731 MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag",
732 data + rec->data_len - transform->taglen,
733 transform->taglen);
Hanno Beckerdf8be222020-05-21 15:30:57 +0100734 /* Account for authentication tag. */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000735 post_avail -= transform->taglen;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100736
737 /*
738 * Prefix record content with dynamic IV in case it is explicit.
739 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200740 if (dynamic_iv_is_explicit != 0) {
741 if (rec->data_offset < dynamic_iv_len) {
742 MBEDTLS_SSL_DEBUG_MSG(
743 1,
744 ("Buffer provided for encrypted record not large enough"));
745 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100746 }
747
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200748 memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len);
Hanno Beckerdf8be222020-05-21 15:30:57 +0100749 rec->data_offset -= dynamic_iv_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200750 rec->data_len += dynamic_iv_len;
Hanno Beckerdf8be222020-05-21 15:30:57 +0100751 }
752
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100753 auth_done++;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200754 } else
755# endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
756# if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
757 if (mode == MBEDTLS_MODE_CBC) {
Janos Follath865b3eb2019-12-16 11:46:15 +0000758 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000759 size_t padlen, i;
760 size_t olen;
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000761
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000762 /* Currently we're always using minimal padding
763 * (up to 255 bytes would be allowed). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200764 padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen;
765 if (padlen == transform->ivlen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 padlen = 0;
767
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000768 /* Check there's enough space in the buffer for the padding. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200769 if (post_avail < padlen + 1) {
770 MBEDTLS_SSL_DEBUG_MSG(
771 1, ("Buffer provided for encrypted record not large enough"));
772 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000773 }
774
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200775 for (i = 0; i <= padlen; i++)
776 data[rec->data_len + i] = (unsigned char)padlen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000777
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000778 rec->data_len += padlen + 1;
779 post_avail -= padlen + 1;
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000780
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200781# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000782 /*
TRodziewicz2d8800e2021-05-13 19:14:19 +0200783 * Prepend per-record IV for block cipher in TLS v1.2 as per
Paul Bakker1ef83d62012-04-11 12:09:53 +0000784 * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000785 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200786 if (f_rng == NULL) {
787 MBEDTLS_SSL_DEBUG_MSG(
788 1, ("No PRNG provided to encrypt_record routine"));
789 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000790 }
TRodziewicz345165c2021-07-06 13:42:11 +0200791
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200792 if (rec->data_offset < transform->ivlen) {
793 MBEDTLS_SSL_DEBUG_MSG(
794 1, ("Buffer provided for encrypted record not large enough"));
795 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
TRodziewicz345165c2021-07-06 13:42:11 +0200796 }
797
798 /*
799 * Generate IV
800 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200801 ret = f_rng(p_rng, transform->iv_enc, transform->ivlen);
802 if (ret != 0)
803 return ret;
TRodziewicz345165c2021-07-06 13:42:11 +0200804
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200805 memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen);
806# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000807
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200808 MBEDTLS_SSL_DEBUG_MSG(
809 3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
810 "including %" MBEDTLS_PRINTF_SIZET
811 " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
812 rec->data_len, transform->ivlen, padlen + 1));
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200814 if ((ret = mbedtls_cipher_crypt(
815 &transform->cipher_ctx_enc, transform->iv_enc,
816 transform->ivlen, data, rec->data_len, data, &olen)) != 0) {
817 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
818 return ret;
Paul Bakkercca5b812013-08-31 17:40:26 +0200819 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +0200820
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200821 if (rec->data_len != olen) {
822 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
823 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakkercca5b812013-08-31 17:40:26 +0200824 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +0200825
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200826 data -= transform->ivlen;
TRodziewicz0f82ec62021-05-12 17:49:18 +0200827 rec->data_offset -= transform->ivlen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200828 rec->data_len += transform->ivlen;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100829
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200830# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
831 if (auth_done == 0) {
Hanno Becker3d8c9072018-01-05 16:24:22 +0000832 unsigned char mac[MBEDTLS_SSL_MAC_ADD];
833
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100834 /*
835 * MAC(MAC_write_key, seq_num +
836 * TLSCipherText.type +
837 * TLSCipherText.version +
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +0100838 * length_of( (IV +) ENC(...) ) +
TRodziewicz2abf03c2021-06-25 14:40:09 +0200839 * IV +
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100840 * ENC(content + padding + padding_length));
841 */
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000842
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200843 if (post_avail < transform->maclen) {
844 MBEDTLS_SSL_DEBUG_MSG(
845 1,
846 ("Buffer provided for encrypted record not large enough"));
847 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000848 }
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100849
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200850 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
851 transform->minor_ver);
Hanno Becker1f10d762019-04-26 13:34:37 +0100852
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200853 MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
854 MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, add_data_len);
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100855
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200856 mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
857 add_data_len);
858 mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len);
859 mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
860 mbedtls_md_hmac_reset(&transform->md_ctx_enc);
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100861
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200862 memcpy(data + rec->data_len, mac, transform->maclen);
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100863
Hanno Becker9eddaeb2017-12-27 21:37:21 +0000864 rec->data_len += transform->maclen;
865 post_avail -= transform->maclen;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100866 auth_done++;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +0100867 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200868# endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
869 } else
870# endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +0200871 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200872 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
873 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +0200874 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100876 /* Make extra sure authentication was performed, exactly once */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200877 if (auth_done != 1) {
878 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
879 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +0100880 }
881
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200882 MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf"));
Paul Bakker5121ce52009-01-03 21:22:43 +0000883
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200884 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000885}
886
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200887# if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +0200888/*
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +0200889 * Turn a bit into a mask:
890 * - if bit == 1, return the all-bits 1 mask, aka (size_t) -1
891 * - if bit == 0, return the all-bits 0 mask, aka 0
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200892 *
893 * This function can be used to write constant-time code by replacing branches
894 * with bit operations using masks.
895 *
896 * This function is implemented without using comparison operators, as those
897 * might be translated to branches by some compilers on some platforms.
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +0200898 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200899static size_t mbedtls_ssl_cf_mask_from_bit(size_t bit)
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +0200900{
901 /* MSVC has a warning about unary minus on unsigned integer types,
902 * but this is well-defined and precisely what we want to do here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200903# if defined(_MSC_VER)
904# pragma warning(push)
905# pragma warning(disable : 4146)
906# endif
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +0200907 return -bit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200908# if defined(_MSC_VER)
909# pragma warning(pop)
910# endif
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +0200911}
912
913/*
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200914 * Constant-flow mask generation for "less than" comparison:
915 * - if x < y, return all bits 1, that is (size_t) -1
916 * - otherwise, return all bits 0, that is 0
917 *
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200918 * This function can be used to write constant-time code by replacing branches
919 * with bit operations using masks.
920 *
921 * This function is implemented without using comparison operators, as those
922 * might be translated to branches by some compilers on some platforms.
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200923 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200924static size_t mbedtls_ssl_cf_mask_lt(size_t x, size_t y)
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200925{
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200926 /* This has the most significant bit set if and only if x < y */
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200927 const size_t sub = x - y;
928
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200929 /* sub1 = (x < y) ? 1 : 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200930 const size_t sub1 = sub >> (sizeof(sub) * 8 - 1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200931
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200932 /* mask = (x < y) ? 0xff... : 0x00... */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200933 const size_t mask = mbedtls_ssl_cf_mask_from_bit(sub1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200934
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200935 return mask;
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200936}
937
938/*
939 * Constant-flow mask generation for "greater or equal" comparison:
940 * - if x >= y, return all bits 1, that is (size_t) -1
941 * - otherwise, return all bits 0, that is 0
942 *
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200943 * This function can be used to write constant-time code by replacing branches
944 * with bit operations using masks.
945 *
946 * This function is implemented without using comparison operators, as those
947 * might be translated to branches by some compilers on some platforms.
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200948 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200949static size_t mbedtls_ssl_cf_mask_ge(size_t x, size_t y)
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200950{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200951 return ~mbedtls_ssl_cf_mask_lt(x, y);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200952}
953
954/*
955 * Constant-flow boolean "equal" comparison:
956 * return x == y
957 *
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200958 * This function can be used to write constant-time code by replacing branches
959 * with bit operations - it can be used in conjunction with
960 * mbedtls_ssl_cf_mask_from_bit().
961 *
962 * This function is implemented without using comparison operators, as those
963 * might be translated to branches by some compilers on some platforms.
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200964 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200965static size_t mbedtls_ssl_cf_bool_eq(size_t x, size_t y)
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200966{
967 /* diff = 0 if x == y, non-zero otherwise */
968 const size_t diff = x ^ y;
969
970 /* MSVC has a warning about unary minus on unsigned integer types,
971 * but this is well-defined and precisely what we want to do here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200972# if defined(_MSC_VER)
973# pragma warning(push)
974# pragma warning(disable : 4146)
975# endif
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200976
977 /* diff_msb's most significant bit is equal to x != y */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200978 const size_t diff_msb = (diff | -diff);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200979
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200980# if defined(_MSC_VER)
981# pragma warning(pop)
982# endif
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200983
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200984 /* diff1 = (x != y) ? 1 : 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200985 const size_t diff1 = diff_msb >> (sizeof(diff_msb) * 8 - 1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200986
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200987 return 1 ^ diff1;
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +0200988}
989
990/*
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +0200991 * Constant-flow conditional memcpy:
992 * - if c1 == c2, equivalent to memcpy(dst, src, len),
993 * - otherwise, a no-op,
994 * but with execution flow independent of the values of c1 and c2.
995 *
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +0200996 * This function is implemented without using comparison operators, as those
997 * might be translated to branches by some compilers on some platforms.
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +0200998 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200999static void mbedtls_ssl_cf_memcpy_if_eq(unsigned char *dst,
1000 const unsigned char *src,
1001 size_t len,
1002 size_t c1,
1003 size_t c2)
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001004{
Manuel Pégourié-Gonnard6e2a9a72020-08-25 10:01:00 +02001005 /* mask = c1 == c2 ? 0xff : 0x00 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001006 const size_t equal = mbedtls_ssl_cf_bool_eq(c1, c2);
1007 const unsigned char mask =
1008 (unsigned char)mbedtls_ssl_cf_mask_from_bit(equal);
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001009
Manuel Pégourié-Gonnard6d6f8a42020-09-25 09:56:53 +02001010 /* dst[i] = c1 == c2 ? src[i] : dst[i] */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001011 for (size_t i = 0; i < len; i++)
1012 dst[i] = (src[i] & mask) | (dst[i] & ~mask);
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001013}
1014
1015/*
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001016 * Compute HMAC of variable-length data with constant flow.
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001017 *
1018 * Only works with MD-5, SHA-1, SHA-256 and SHA-384.
1019 * (Otherwise, computation of block_size needs to be adapted.)
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001020 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001021MBEDTLS_STATIC_TESTABLE int mbedtls_ssl_cf_hmac(mbedtls_md_context_t *ctx,
1022 const unsigned char *add_data,
1023 size_t add_data_len,
1024 const unsigned char *data,
1025 size_t data_len_secret,
1026 size_t min_data_len,
1027 size_t max_data_len,
1028 unsigned char *output)
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001029{
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001030 /*
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001031 * This function breaks the HMAC abstraction and uses the md_clone()
1032 * extension to the MD API in order to get constant-flow behaviour.
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001033 *
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001034 * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
Manuel Pégourié-Gonnardbaccf802020-07-22 10:37:27 +02001035 * concatenation, and okey/ikey are the XOR of the key with some fixed bit
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001036 * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001037 *
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001038 * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
1039 * minlen, then cloning the context, and for each byte up to maxlen
1040 * finishing up the hash computation, keeping only the correct result.
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001041 *
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001042 * Then we only need to compute HASH(okey + inner_hash) and we're done.
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001043 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001044 const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
TRodziewicz2abf03c2021-06-25 14:40:09 +02001045 /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
Manuel Pégourié-Gonnardbaccf802020-07-22 10:37:27 +02001046 * all of which have the same block size except SHA-384. */
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001047 const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001048 const unsigned char *const ikey = ctx->hmac_ctx;
1049 const unsigned char *const okey = ikey + block_size;
1050 const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001051
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001052 unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
1053 mbedtls_md_context_t aux;
1054 size_t offset;
Manuel Pégourié-Gonnarde0765f32020-07-22 12:22:51 +02001055 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001056
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001057 mbedtls_md_init(&aux);
Manuel Pégourié-Gonnard44c9fdd2020-07-22 10:48:47 +02001058
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001059# define MD_CHK(func_call) \
1060 do { \
1061 ret = (func_call); \
1062 if (ret != 0) \
1063 goto cleanup; \
1064 } while (0)
Manuel Pégourié-Gonnard44c9fdd2020-07-22 10:48:47 +02001065
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001066 MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001067
1068 /* After hmac_start() of hmac_reset(), ikey has already been hashed,
1069 * so we can start directly with the message */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001070 MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
1071 MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001072
1073 /* For each possible length, compute the hash up to that point */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001074 for (offset = min_data_len; offset <= max_data_len; offset++) {
1075 MD_CHK(mbedtls_md_clone(&aux, ctx));
1076 MD_CHK(mbedtls_md_finish(&aux, aux_out));
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001077 /* Keep only the correct inner_hash in the output buffer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001078 mbedtls_ssl_cf_memcpy_if_eq(output, aux_out, hash_size, offset,
1079 data_len_secret);
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001080
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001081 if (offset < max_data_len)
1082 MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001083 }
1084
Manuel Pégourié-Gonnard5ca21db2021-05-17 12:28:08 +02001085 /* The context needs to finish() before it starts() again */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001086 MD_CHK(mbedtls_md_finish(ctx, aux_out));
Manuel Pégourié-Gonnard5ca21db2021-05-17 12:28:08 +02001087
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001088 /* Now compute HASH(okey + inner_hash) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001089 MD_CHK(mbedtls_md_starts(ctx));
1090 MD_CHK(mbedtls_md_update(ctx, okey, block_size));
1091 MD_CHK(mbedtls_md_update(ctx, output, hash_size));
1092 MD_CHK(mbedtls_md_finish(ctx, output));
Manuel Pégourié-Gonnard8aa29e32020-07-07 12:30:39 +02001093
Manuel Pégourié-Gonnard7a8b1e62020-07-15 11:52:14 +02001094 /* Done, get ready for next time */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001095 MD_CHK(mbedtls_md_hmac_reset(ctx));
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001096
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001097# undef MD_CHK
Manuel Pégourié-Gonnard44c9fdd2020-07-22 10:48:47 +02001098
1099cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001100 mbedtls_md_free(&aux);
1101 return ret;
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001102}
Manuel Pégourié-Gonnard7fe2c5f2020-08-18 12:02:54 +02001103
1104/*
1105 * Constant-flow memcpy from variable position in buffer.
1106 * - functionally equivalent to memcpy(dst, src + offset_secret, len)
Manuel Pégourié-Gonnardba6fc972020-08-24 12:59:55 +02001107 * - but with execution flow independent from the value of offset_secret.
Manuel Pégourié-Gonnard7fe2c5f2020-08-18 12:02:54 +02001108 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001109MBEDTLS_STATIC_TESTABLE void
1110mbedtls_ssl_cf_memcpy_offset(unsigned char *dst,
1111 const unsigned char *src_base,
1112 size_t offset_secret,
1113 size_t offset_min,
1114 size_t offset_max,
1115 size_t len)
Manuel Pégourié-Gonnard7fe2c5f2020-08-18 12:02:54 +02001116{
Manuel Pégourié-Gonnardde1cf2c52020-08-19 12:35:30 +02001117 size_t offset;
1118
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001119 for (offset = offset_min; offset <= offset_max; offset++) {
1120 mbedtls_ssl_cf_memcpy_if_eq(dst, src_base + offset, len, offset,
1121 offset_secret);
Manuel Pégourié-Gonnardde1cf2c52020-08-19 12:35:30 +02001122 }
Manuel Pégourié-Gonnard7fe2c5f2020-08-18 12:02:54 +02001123}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001124# endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
Manuel Pégourié-Gonnard045f0942020-07-02 11:34:02 +02001125
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001126int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
1127 mbedtls_ssl_transform *transform,
1128 mbedtls_record *rec)
Paul Bakker5121ce52009-01-03 21:22:43 +00001129{
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001130 size_t olen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131 mbedtls_cipher_mode_t mode;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001132 int ret, auth_done = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001133# if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
Paul Bakker1e5369c2013-12-19 16:40:57 +01001134 size_t padlen = 0, correct = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001135# endif
1136 unsigned char *data;
1137 unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX];
Hanno Beckercab87e62019-04-29 13:52:53 +01001138 size_t add_data_len;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001140# if !defined(MBEDTLS_DEBUG_C)
Manuel Pégourié-Gonnarda7505d12019-05-07 10:17:56 +02001141 ssl = NULL; /* make sure we don't use it except for debug */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001142 ((void)ssl);
1143# endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001145 MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf"));
1146 if (rec == NULL || rec->buf == NULL || rec->buf_len < rec->data_offset ||
1147 rec->buf_len - rec->data_offset < rec->data_len) {
1148 MBEDTLS_SSL_DEBUG_MSG(1,
1149 ("bad record structure provided to decrypt_buf"));
1150 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001151 }
1152
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001153 data = rec->buf + rec->data_offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001154 mode = mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001155
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001156# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckercab87e62019-04-29 13:52:53 +01001157 /*
1158 * Match record's CID with incoming CID.
1159 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001160 if (rec->cid_len != transform->in_cid_len ||
1161 memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) {
1162 return MBEDTLS_ERR_SSL_UNEXPECTED_CID;
Hanno Becker938489a2019-05-08 13:02:22 +01001163 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001164# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +01001165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001166# if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
1167 if (mode == MBEDTLS_MODE_STREAM) {
Paul Bakker68884e32013-01-07 18:20:04 +01001168 padlen = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001169 if ((ret = mbedtls_cipher_crypt(
1170 &transform->cipher_ctx_dec, transform->iv_dec,
1171 transform->ivlen, data, rec->data_len, data, &olen)) != 0) {
1172 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
1173 return ret;
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001174 }
1175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001176 if (rec->data_len != olen) {
1177 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1178 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakkerea6ad3f2013-09-02 14:57:01 +02001179 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001180 } else
1181# endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
1182# if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || \
1183 defined(MBEDTLS_CHACHAPOLY_C)
1184 if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM ||
1185 mode == MBEDTLS_MODE_CHACHAPOLY) {
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001186 unsigned char iv[12];
Hanno Beckerdf8be222020-05-21 15:30:57 +01001187 unsigned char *dynamic_iv;
1188 size_t dynamic_iv_len;
Paul Bakkerca4ab492012-04-18 14:23:57 +00001189
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001190 /*
Hanno Beckerdf8be222020-05-21 15:30:57 +01001191 * Extract dynamic part of nonce for AEAD decryption.
1192 *
1193 * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
1194 * part of the IV is prepended to the ciphertext and
1195 * can be chosen freely - in particular, it need not
1196 * agree with the record sequence number.
Manuel Pégourié-Gonnard2e58e8e2018-06-18 11:16:43 +02001197 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001198 dynamic_iv_len = sizeof(rec->ctr);
1199 if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) {
1200 if (rec->data_len < dynamic_iv_len) {
1201 MBEDTLS_SSL_DEBUG_MSG(
1202 1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1203 " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
1204 rec->data_len, dynamic_iv_len));
1205 return MBEDTLS_ERR_SSL_INVALID_MAC;
Hanno Beckerdf8be222020-05-21 15:30:57 +01001206 }
1207 dynamic_iv = data;
1208
1209 data += dynamic_iv_len;
1210 rec->data_offset += dynamic_iv_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001211 rec->data_len -= dynamic_iv_len;
1212 } else {
Hanno Becker17263802020-05-28 07:05:48 +01001213 dynamic_iv = rec->ctr;
1214 }
Hanno Beckerdf8be222020-05-21 15:30:57 +01001215
1216 /* Check that there's space for the authentication tag. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001217 if (rec->data_len < transform->taglen) {
1218 MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1219 ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
1220 rec->data_len, transform->taglen));
1221 return MBEDTLS_ERR_SSL_INVALID_MAC;
Manuel Pégourié-Gonnard0bcc4e12014-06-17 10:54:17 +02001222 }
Hanno Beckerdf8be222020-05-21 15:30:57 +01001223 rec->data_len -= transform->taglen;
Paul Bakker68884e32013-01-07 18:20:04 +01001224
Hanno Beckerdf8be222020-05-21 15:30:57 +01001225 /*
1226 * Prepare nonce from dynamic and static parts.
1227 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001228 ssl_build_record_nonce(iv, sizeof(iv), transform->iv_dec,
1229 transform->fixed_ivlen, dynamic_iv,
1230 dynamic_iv_len);
Paul Bakker68884e32013-01-07 18:20:04 +01001231
Hanno Beckerdf8be222020-05-21 15:30:57 +01001232 /*
1233 * Build additional data for AEAD encryption.
1234 * This depends on the TLS version.
1235 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001236 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1237 transform->minor_ver);
1238 MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD", add_data,
1239 add_data_len);
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001240
Hanno Beckerd96a6522019-07-10 13:55:25 +01001241 /* Because of the check above, we know that there are
1242 * explicit_iv_len Bytes preceeding data, and taglen
1243 * bytes following data + data_len. This justifies
Hanno Becker20016652019-07-10 11:44:13 +01001244 * the debug message and the invocation of
TRodziewicz18efb732021-04-29 23:12:19 +02001245 * mbedtls_cipher_auth_decrypt_ext() below. */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001246
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001247 MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen);
1248 MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len,
1249 transform->taglen);
Paul Bakker68884e32013-01-07 18:20:04 +01001250
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001251 /*
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001252 * Decrypt and authenticate
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001253 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001254 if ((ret = mbedtls_cipher_auth_decrypt_ext(
1255 &transform->cipher_ctx_dec, iv, transform->ivlen, add_data,
1256 add_data_len, data, rec->data_len + transform->taglen, /* src
1257 */
1258 data, rec->buf_len - (data - rec->buf), &olen, /* dst */
1259 transform->taglen)) != 0) {
1260 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret);
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001262 if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED)
1263 return MBEDTLS_ERR_SSL_INVALID_MAC;
Manuel Pégourié-Gonnardde7bb442014-05-13 12:41:10 +02001264
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001265 return ret;
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001266 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001267 auth_done++;
Paul Bakkerca4ab492012-04-18 14:23:57 +00001268
Hanno Beckerd96a6522019-07-10 13:55:25 +01001269 /* Double-check that AEAD decryption doesn't change content length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001270 if (olen != rec->data_len) {
1271 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1272 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardd13a4092013-09-05 16:10:41 +02001273 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001274 } else
1275# endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
1276# if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
1277 if (mode == MBEDTLS_MODE_CBC) {
Paul Bakkere47b34b2013-02-27 14:48:00 +01001278 size_t minlen = 0;
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001279
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 /*
Paul Bakker45829992013-01-03 14:52:21 +01001281 * Check immediate ciphertext sanity
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001283# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
TRodziewicz345165c2021-07-06 13:42:11 +02001284 /* The ciphertext is prefixed with the CBC IV. */
1285 minlen += transform->ivlen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001286# endif
Paul Bakker45829992013-01-03 14:52:21 +01001287
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001288 /* Size considerations:
1289 *
1290 * - The CBC cipher text must not be empty and hence
1291 * at least of size transform->ivlen.
1292 *
1293 * Together with the potential IV-prefix, this explains
1294 * the first of the two checks below.
1295 *
1296 * - The record must contain a MAC, either in plain or
1297 * encrypted, depending on whether Encrypt-then-MAC
1298 * is used or not.
1299 * - If it is, the message contains the IV-prefix,
1300 * the CBC ciphertext, and the MAC.
1301 * - If it is not, the padded plaintext, and hence
1302 * the CBC ciphertext, has at least length maclen + 1
1303 * because there is at least the padding length byte.
1304 *
1305 * As the CBC ciphertext is not empty, both cases give the
1306 * lower bound minlen + maclen + 1 on the record size, which
1307 * we test for in the second check below.
1308 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001309 if (rec->data_len < minlen + transform->ivlen ||
1310 rec->data_len < minlen + transform->maclen + 1) {
1311 MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1312 ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
1313 "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
1314 "+ 1 ) ( + expl IV )",
1315 rec->data_len, transform->ivlen,
1316 transform->maclen));
1317 return MBEDTLS_ERR_SSL_INVALID_MAC;
Paul Bakker45829992013-01-03 14:52:21 +01001318 }
1319
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001320 /*
1321 * Authenticate before decrypt if enabled
1322 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001323# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1324 if (transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) {
Hanno Becker992b6872017-11-09 18:57:39 +00001325 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001326
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001327 MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001328
Hanno Beckerd96a6522019-07-10 13:55:25 +01001329 /* Update data_len in tandem with add_data.
1330 *
1331 * The subtraction is safe because of the previous check
1332 * data_len >= minlen + maclen + 1.
1333 *
1334 * Afterwards, we know that data + data_len is followed by at
1335 * least maclen Bytes, which justifies the call to
1336 * mbedtls_ssl_safer_memcmp() below.
1337 *
1338 * Further, we still know that data_len > minlen */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001339 rec->data_len -= transform->maclen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001340 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1341 transform->minor_ver);
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +01001342
Hanno Beckerd96a6522019-07-10 13:55:25 +01001343 /* Calculate expected MAC. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001344 MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data, add_data_len);
1345 mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data,
1346 add_data_len);
1347 mbedtls_md_hmac_update(&transform->md_ctx_dec, data, rec->data_len);
1348 mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect);
1349 mbedtls_md_hmac_reset(&transform->md_ctx_dec);
Manuel Pégourié-Gonnard08558e52014-11-04 14:40:21 +01001350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001351 MBEDTLS_SSL_DEBUG_BUF(4, "message mac", data + rec->data_len,
1352 transform->maclen);
1353 MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect,
1354 transform->maclen);
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001355
Hanno Beckerd96a6522019-07-10 13:55:25 +01001356 /* Compare expected MAC with MAC at the end of the record. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001357 if (mbedtls_ssl_safer_memcmp(data + rec->data_len, mac_expect,
1358 transform->maclen) != 0) {
1359 MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
1360 return MBEDTLS_ERR_SSL_INVALID_MAC;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001361 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001362 auth_done++;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001363 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001364# endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001365
1366 /*
1367 * Check length sanity
1368 */
Hanno Beckerd96a6522019-07-10 13:55:25 +01001369
1370 /* We know from above that data_len > minlen >= 0,
1371 * so the following check in particular implies that
1372 * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001373 if (rec->data_len % transform->ivlen != 0) {
1374 MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1375 ") %% ivlen (%" MBEDTLS_PRINTF_SIZET
1376 ") != 0",
1377 rec->data_len, transform->ivlen));
1378 return MBEDTLS_ERR_SSL_INVALID_MAC;
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001379 }
1380
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001381# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001382 /*
TRodziewicz0f82ec62021-05-12 17:49:18 +02001383 * Initialize for prepended IV for block cipher in TLS v1.2
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001384 */
TRodziewicz345165c2021-07-06 13:42:11 +02001385 /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001386 memcpy(transform->iv_dec, data, transform->ivlen);
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001387
TRodziewicz345165c2021-07-06 13:42:11 +02001388 data += transform->ivlen;
1389 rec->data_offset += transform->ivlen;
1390 rec->data_len -= transform->ivlen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001391# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker2e11f7d2010-07-25 14:24:53 +00001392
Hanno Beckerd96a6522019-07-10 13:55:25 +01001393 /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
1394
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001395 if ((ret = mbedtls_cipher_crypt(
1396 &transform->cipher_ctx_dec, transform->iv_dec,
1397 transform->ivlen, data, rec->data_len, data, &olen)) != 0) {
1398 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
1399 return ret;
Paul Bakkercca5b812013-08-31 17:40:26 +02001400 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001401
Hanno Beckerd96a6522019-07-10 13:55:25 +01001402 /* Double-check that length hasn't changed during decryption. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001403 if (rec->data_len != olen) {
1404 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1405 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Paul Bakkercca5b812013-08-31 17:40:26 +02001406 }
Paul Bakkerda02a7f2013-08-31 17:25:14 +02001407
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001408 /* Safe since data_len >= minlen + maclen + 1, so after having
1409 * subtracted at most minlen and maclen up to this point,
Hanno Beckerd96a6522019-07-10 13:55:25 +01001410 * data_len > 0 (because of data_len % ivlen == 0, it's actually
1411 * >= ivlen ). */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001412 padlen = data[rec->data_len - 1];
Paul Bakker45829992013-01-03 14:52:21 +01001413
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001414 if (auth_done == 1) {
1415 const size_t mask =
1416 mbedtls_ssl_cf_mask_ge(rec->data_len, padlen + 1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001417 correct &= mask;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001418 padlen &= mask;
1419 } else {
1420# if defined(MBEDTLS_SSL_DEBUG_ALL)
1421 if (rec->data_len < transform->maclen + padlen + 1) {
1422 MBEDTLS_SSL_DEBUG_MSG(
1423 1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1424 ") < maclen (%" MBEDTLS_PRINTF_SIZET
1425 ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
1426 rec->data_len, transform->maclen, padlen + 1));
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001427 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001428# endif
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001429
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001430 const size_t mask = mbedtls_ssl_cf_mask_ge(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001431 rec->data_len, transform->maclen + padlen + 1);
Manuel Pégourié-Gonnard2ddec432020-08-24 12:49:23 +02001432 correct &= mask;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001433 padlen &= mask;
Paul Bakker45829992013-01-03 14:52:21 +01001434 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001435
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001436 padlen++;
1437
1438 /* Regardless of the validity of the padding,
1439 * we have data_len >= padlen here. */
1440
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001441# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001442 /* The padding check involves a series of up to 256
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001443 * consecutive memory reads at the end of the record
1444 * plaintext buffer. In order to hide the length and
1445 * validity of the padding, always perform exactly
1446 * `min(256,plaintext_len)` reads (but take into account
1447 * only the last `padlen` bytes for the padding check). */
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001448 size_t pad_count = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001449 volatile unsigned char *const check = data;
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001450
1451 /* Index of first padding byte; it has been ensured above
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001452 * that the subtraction is safe. */
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001453 size_t const padding_idx = rec->data_len - padlen;
1454 size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
1455 size_t const start_idx = rec->data_len - num_checks;
1456 size_t idx;
1457
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001458 for (idx = start_idx; idx < rec->data_len; idx++) {
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001459 /* pad_count += (idx >= padding_idx) &&
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001460 * (check[idx] == padlen - 1);
1461 */
1462 const size_t mask = mbedtls_ssl_cf_mask_ge(idx, padding_idx);
1463 const size_t equal = mbedtls_ssl_cf_bool_eq(check[idx], padlen - 1);
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001464 pad_count += mask & equal;
1465 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001466 correct &= mbedtls_ssl_cf_bool_eq(pad_count, padlen);
Paul Bakkere47b34b2013-02-27 14:48:00 +01001467
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001468# if defined(MBEDTLS_SSL_DEBUG_ALL)
1469 if (padlen > 0 && correct == 0)
1470 MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
1471# endif
1472 padlen &= mbedtls_ssl_cf_mask_from_bit(correct);
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001473
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001474# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001475
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001476 /* If the padding was found to be invalid, padlen == 0
1477 * and the subtraction is safe. If the padding was found valid,
1478 * padlen hasn't been changed and the previous assertion
1479 * data_len >= padlen still holds. */
1480 rec->data_len -= padlen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001481 } else
1482# endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001483 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001484 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1485 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardf7dc3782013-09-13 14:10:44 +02001486 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001487
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001488# if defined(MBEDTLS_SSL_DEBUG_ALL)
1489 MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption", data,
1490 rec->data_len);
1491# endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001492
1493 /*
Manuel Pégourié-Gonnard313d7962014-10-29 12:07:57 +01001494 * Authenticate if not done yet.
1495 * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
Paul Bakker5121ce52009-01-03 21:22:43 +00001496 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001497# if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
1498 if (auth_done == 0) {
Hanno Becker992b6872017-11-09 18:57:39 +00001499 unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
Manuel Pégourié-Gonnard3c31afa2020-08-13 12:08:54 +02001500 unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
Paul Bakker1e5369c2013-12-19 16:40:57 +01001501
Hanno Becker2e24c3b2017-12-27 21:28:58 +00001502 /* If the initial value of padlen was such that
1503 * data_len < maclen + padlen + 1, then padlen
1504 * got reset to 1, and the initial check
1505 * data_len >= minlen + maclen + 1
1506 * guarantees that at this point we still
1507 * have at least data_len >= maclen.
1508 *
1509 * If the initial value of padlen was such that
1510 * data_len >= maclen + padlen + 1, then we have
1511 * subtracted either padlen + 1 (if the padding was correct)
1512 * or 0 (if the padding was incorrect) since then,
1513 * hence data_len >= maclen in any case.
1514 */
1515 rec->data_len -= transform->maclen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001516 ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1517 transform->minor_ver);
Paul Bakker5121ce52009-01-03 21:22:43 +00001518
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001519# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001520 /*
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001521 * The next two sizes are the minimum and maximum values of
1522 * data_len over all padlen values.
1523 *
1524 * They're independent of padlen, since we previously did
1525 * data_len -= padlen.
1526 *
1527 * Note that max_len + maclen is never more than the buffer
1528 * length, as we previously did in_msglen -= maclen too.
1529 */
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001530 const size_t max_len = rec->data_len + padlen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001531 const size_t min_len = (max_len > 256) ? max_len - 256 : 0;
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001532
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001533 ret = mbedtls_ssl_cf_hmac(&transform->md_ctx_dec, add_data,
1534 add_data_len, data, rec->data_len, min_len,
1535 max_len, mac_expect);
1536 if (ret != 0) {
1537 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_cf_hmac", ret);
1538 return ret;
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001539 }
Mateusz Starzyk06b07fb2021-02-18 13:55:21 +01001540
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001541 mbedtls_ssl_cf_memcpy_offset(mac_peer, data, rec->data_len, min_len,
1542 max_len, transform->maclen);
1543# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001544
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001545# if defined(MBEDTLS_SSL_DEBUG_ALL)
1546 MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen);
1547 MBEDTLS_SSL_DEBUG_BUF(4, "message mac", mac_peer, transform->maclen);
1548# endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001549
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001550 if (mbedtls_ssl_safer_memcmp(mac_peer, mac_expect, transform->maclen) !=
1551 0) {
1552# if defined(MBEDTLS_SSL_DEBUG_ALL)
1553 MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
1554# endif
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001555 correct = 0;
1556 }
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001557 auth_done++;
Manuel Pégourié-Gonnard71096242013-10-25 19:31:25 +02001558 }
Hanno Beckerdd3ab132018-10-17 14:43:14 +01001559
1560 /*
1561 * Finally check the correct flag
1562 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001563 if (correct == 0)
1564 return MBEDTLS_ERR_SSL_INVALID_MAC;
1565# endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001566
1567 /* Make extra sure authentication was performed, exactly once */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001568 if (auth_done != 1) {
1569 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1570 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard352143f2015-01-13 10:59:51 +01001571 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001572
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001573# if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
1574 if (transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4) {
Hanno Beckerccc13d02020-05-04 12:30:04 +01001575 /* Remove inner padding and infer true content type. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001576 ret = ssl_parse_inner_plaintext(data, &rec->data_len, &rec->type);
Hanno Beckerccc13d02020-05-04 12:30:04 +01001577
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001578 if (ret != 0)
1579 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckerccc13d02020-05-04 12:30:04 +01001580 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001581# endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
Hanno Beckerccc13d02020-05-04 12:30:04 +01001582
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001583# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1584 if (rec->cid_len != 0) {
1585 ret = ssl_parse_inner_plaintext(data, &rec->data_len, &rec->type);
1586 if (ret != 0)
1587 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker8b3eb5a2019-04-29 17:31:37 +01001588 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001589# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker8b3eb5a2019-04-29 17:31:37 +01001590
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001591 MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001592
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001593 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001594}
1595
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001596# undef MAC_NONE
1597# undef MAC_PLAINTEXT
1598# undef MAC_CIPHERTEXT
Manuel Pégourié-Gonnard0098e7d2014-10-28 13:08:59 +01001599
Paul Bakker5121ce52009-01-03 21:22:43 +00001600/*
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001601 * Fill the input message buffer by appending data to it.
1602 * The amount of data already fetched is in ssl->in_left.
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001603 *
1604 * If we return 0, is it guaranteed that (at least) nb_want bytes are
1605 * available (from this read and/or a previous one). Otherwise, an error code
1606 * is returned (possibly EOF or WANT_READ).
1607 *
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001608 * With stream transport (TLS) on success ssl->in_left == nb_want, but
1609 * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
1610 * since we always read a whole datagram at once.
1611 *
Manuel Pégourié-Gonnard64dffc52014-09-02 13:39:16 +02001612 * For DTLS, it is up to the caller to set ssl->next_record_offset when
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001613 * they're done reading a record.
Paul Bakker5121ce52009-01-03 21:22:43 +00001614 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001615int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
Paul Bakker5121ce52009-01-03 21:22:43 +00001616{
Janos Follath865b3eb2019-12-16 11:46:15 +00001617 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001618 size_t len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001619# if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Darryl Greenb33cc762019-11-28 14:29:44 +00001620 size_t in_buf_len = ssl->in_buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001621# else
Darryl Greenb33cc762019-11-28 14:29:44 +00001622 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001623# endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001624
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001625 MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001626
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001627 if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) {
1628 MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "
1629 "or mbedtls_ssl_set_bio()"));
1630 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02001631 }
1632
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001633 if (nb_want > in_buf_len - (size_t)(ssl->in_hdr - ssl->in_buf)) {
1634 MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits"));
1635 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Paul Bakker1a1fbba2014-04-30 14:38:05 +02001636 }
1637
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001638# if defined(MBEDTLS_SSL_PROTO_DTLS)
1639 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02001640 uint32_t timeout;
1641
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001642 /*
1643 * The point is, we need to always read a full datagram at once, so we
1644 * sometimes read more then requested, and handle the additional data.
1645 * It could be the rest of the current record (while fetching the
1646 * header) and/or some other records in the same datagram.
1647 */
1648
1649 /*
1650 * Move to the next record in the already read datagram if applicable
1651 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001652 if (ssl->next_record_offset != 0) {
1653 if (ssl->in_left < ssl->next_record_offset) {
1654 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1655 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001656 }
1657
1658 ssl->in_left -= ssl->next_record_offset;
1659
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001660 if (ssl->in_left != 0) {
1661 MBEDTLS_SSL_DEBUG_MSG(
1662 2,
1663 ("next record in same datagram, offset: %" MBEDTLS_PRINTF_SIZET,
1664 ssl->next_record_offset));
1665 memmove(ssl->in_hdr, ssl->in_hdr + ssl->next_record_offset,
1666 ssl->in_left);
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001667 }
1668
1669 ssl->next_record_offset = 0;
1670 }
1671
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001672 MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
1673 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
1674 ssl->in_left, nb_want));
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001675
1676 /*
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001677 * Done if we already have enough data.
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001678 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001679 if (nb_want <= ssl->in_left) {
1680 MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
1681 return 0;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02001682 }
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001683
1684 /*
Antonin Décimo36e89b52019-01-23 15:24:37 +01001685 * A record can't be split across datagrams. If we need to read but
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001686 * are not at the beginning of a new record, the caller did something
1687 * wrong.
1688 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001689 if (ssl->in_left != 0) {
1690 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1691 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001692 }
1693
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001694 /*
1695 * Don't even try to read if time's out already.
1696 * This avoids by-passing the timer when repeatedly receiving messages
1697 * that will end up being dropped.
1698 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001699 if (mbedtls_ssl_check_timer(ssl) != 0) {
1700 MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired"));
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01001701 ret = MBEDTLS_ERR_SSL_TIMEOUT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001702 } else {
1703 len = in_buf_len - (ssl->in_hdr - ssl->in_buf);
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001704
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001705 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER)
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001706 timeout = ssl->handshake->retransmit_timeout;
1707 else
Manuel Pégourié-Gonnard7ca4e4d2015-05-04 10:55:58 +02001708 timeout = ssl->conf->read_timeout;
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001709
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001710 MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms",
1711 (unsigned long)timeout));
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001712
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001713 if (ssl->f_recv_timeout != NULL)
1714 ret =
1715 ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len, timeout);
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001716 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001717 ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len);
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001718
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001719 MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001720
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001721 if (ret == 0)
1722 return MBEDTLS_ERR_SSL_CONN_EOF;
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02001723 }
1724
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001725 if (ret == MBEDTLS_ERR_SSL_TIMEOUT) {
1726 MBEDTLS_SSL_DEBUG_MSG(2, ("timeout"));
1727 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02001728
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001729 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
1730 if (ssl_double_retransmit_timeout(ssl) != 0) {
1731 MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout"));
1732 return MBEDTLS_ERR_SSL_TIMEOUT;
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02001733 }
1734
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001735 if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
1736 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
1737 return ret;
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02001738 }
1739
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001740 return MBEDTLS_ERR_SSL_WANT_READ;
Manuel Pégourié-Gonnard0ac247f2014-09-30 22:21:31 +02001741 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001742# if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
1743 else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
1744 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
1745 if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
1746 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
1747 ret);
1748 return ret;
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02001749 }
1750
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001751 return MBEDTLS_ERR_SSL_WANT_READ;
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02001752 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001753# endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02001754 }
1755
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001756 if (ret < 0)
1757 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001758
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001759 ssl->in_left = ret;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001760 } else
1761# endif
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001762 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001763 MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
1764 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
1765 ssl->in_left, nb_want));
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02001766
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001767 while (ssl->in_left < nb_want) {
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001768 len = nb_want - ssl->in_left;
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02001769
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001770 if (mbedtls_ssl_check_timer(ssl) != 0)
Manuel Pégourié-Gonnard286a1362015-05-13 16:22:05 +02001771 ret = MBEDTLS_ERR_SSL_TIMEOUT;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001772 else {
1773 if (ssl->f_recv_timeout != NULL) {
1774 ret = ssl->f_recv_timeout(ssl->p_bio,
1775 ssl->in_hdr + ssl->in_left, len,
1776 ssl->conf->read_timeout);
1777 } else {
1778 ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr + ssl->in_left,
1779 len);
Manuel Pégourié-Gonnard07617332015-06-24 23:00:03 +02001780 }
1781 }
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001782
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001783 MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
1784 ", nb_want: %" MBEDTLS_PRINTF_SIZET,
1785 ssl->in_left, nb_want));
1786 MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001787
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001788 if (ret == 0)
1789 return MBEDTLS_ERR_SSL_CONN_EOF;
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001790
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001791 if (ret < 0)
1792 return ret;
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001793
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001794 if ((size_t)ret > len ||
1795 (INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX)) {
1796 MBEDTLS_SSL_DEBUG_MSG(
1797 1,
1798 ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
1799 " were requested",
1800 ret, len));
1801 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
mohammad16035bd15cb2018-02-28 04:30:59 -08001802 }
1803
Manuel Pégourié-Gonnardfe98ace2014-03-24 13:13:01 +01001804 ssl->in_left += ret;
1805 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001806 }
1807
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001808 MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001809
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001810 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001811}
1812
1813/*
1814 * Flush any data not yet written
1815 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001816int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00001817{
Janos Follath865b3eb2019-12-16 11:46:15 +00001818 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker04484622018-08-06 09:49:38 +01001819 unsigned char *buf;
Paul Bakker5121ce52009-01-03 21:22:43 +00001820
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001821 MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001822
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001823 if (ssl->f_send == NULL) {
1824 MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "
1825 "or mbedtls_ssl_set_bio()"));
1826 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnarde6bdc442014-09-17 11:34:57 +02001827 }
1828
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01001829 /* Avoid incrementing counter if data is flushed */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001830 if (ssl->out_left == 0) {
1831 MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
1832 return 0;
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01001833 }
1834
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001835 while (ssl->out_left > 0) {
1836 MBEDTLS_SSL_DEBUG_MSG(
1837 2, ("message length: %" MBEDTLS_PRINTF_SIZET
1838 ", out_left: %" MBEDTLS_PRINTF_SIZET,
1839 mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left));
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Hanno Becker2b1e3542018-08-06 11:19:13 +01001841 buf = ssl->out_hdr - ssl->out_left;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001842 ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left);
Paul Bakker186751d2012-05-08 13:16:14 +00001843
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001844 MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret);
Paul Bakker5121ce52009-01-03 21:22:43 +00001845
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001846 if (ret <= 0)
1847 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001849 if ((size_t)ret > ssl->out_left ||
1850 (INT_MAX > SIZE_MAX && ret > (int)SIZE_MAX)) {
1851 MBEDTLS_SSL_DEBUG_MSG(
1852 1, ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
1853 " bytes were sent",
1854 ret, ssl->out_left));
1855 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
mohammad16034bbaeb42018-02-22 04:29:04 -08001856 }
1857
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 ssl->out_left -= ret;
1859 }
1860
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001861# if defined(MBEDTLS_SSL_PROTO_DTLS)
1862 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Becker2b1e3542018-08-06 11:19:13 +01001863 ssl->out_hdr = ssl->out_buf;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001864 } else
1865# endif
Hanno Becker2b1e3542018-08-06 11:19:13 +01001866 {
1867 ssl->out_hdr = ssl->out_buf + 8;
1868 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001869 mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
Manuel Pégourié-Gonnard06193482014-02-14 08:39:32 +01001870
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001871 MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001873 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001874}
1875
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001876/*
1877 * Functions to handle the DTLS retransmission state machine
1878 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001879# if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001880/*
1881 * Append current handshake message to current outgoing flight
1882 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001883static int ssl_flight_append(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001884{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 mbedtls_ssl_flight_item *msg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001886 MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append"));
1887 MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight", ssl->out_msg,
1888 ssl->out_msglen);
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001889
1890 /* Allocate space for current message */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001891 if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) {
1892 MBEDTLS_SSL_DEBUG_MSG(1,
1893 ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
1894 sizeof(mbedtls_ssl_flight_item)));
1895 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001896 }
1897
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001898 if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) {
1899 MBEDTLS_SSL_DEBUG_MSG(1,
1900 ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
1901 ssl->out_msglen));
1902 mbedtls_free(msg);
1903 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001904 }
1905
1906 /* Copy current handshake message with headers */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001907 memcpy(msg->p, ssl->out_msg, ssl->out_msglen);
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001908 msg->len = ssl->out_msglen;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001909 msg->type = ssl->out_msgtype;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001910 msg->next = NULL;
1911
1912 /* Append to the current flight */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001913 if (ssl->handshake->flight == NULL)
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001914 ssl->handshake->flight = msg;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001915 else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001916 mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001917 while (cur->next != NULL)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001918 cur = cur->next;
1919 cur->next = msg;
1920 }
1921
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001922 MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append"));
1923 return 0;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001924}
1925
1926/*
1927 * Free the current flight of handshake messages
1928 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001929void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001930{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931 mbedtls_ssl_flight_item *cur = flight;
1932 mbedtls_ssl_flight_item *next;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001933
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001934 while (cur != NULL) {
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001935 next = cur->next;
1936
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001937 mbedtls_free(cur->p);
1938 mbedtls_free(cur);
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001939
1940 cur = next;
1941 }
1942}
1943
1944/*
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001945 * Swap transform_out and out_ctr with the alternative ones
1946 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001947static int ssl_swap_epochs(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001948{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001949 mbedtls_ssl_transform *tmp_transform;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001950 unsigned char tmp_out_ctr[8];
1951
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001952 if (ssl->transform_out == ssl->handshake->alt_transform_out) {
1953 MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs"));
1954 return 0;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001955 }
1956
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001957 MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs"));
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001958
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02001959 /* Swap transforms */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001960 tmp_transform = ssl->transform_out;
1961 ssl->transform_out = ssl->handshake->alt_transform_out;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001962 ssl->handshake->alt_transform_out = tmp_transform;
1963
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02001964 /* Swap epoch + sequence_number */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001965 memcpy(tmp_out_ctr, ssl->cur_out_ctr, 8);
1966 memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8);
1967 memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr, 8);
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02001968
1969 /* Adjust to the newly activated transform */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001970 mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02001971
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001972 return 0;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001973}
1974
1975/*
1976 * Retransmit the current flight of messages.
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001977 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001978int mbedtls_ssl_resend(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001979{
1980 int ret = 0;
1981
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001982 MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend"));
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001983
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001984 ret = mbedtls_ssl_flight_transmit(ssl);
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001985
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001986 MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend"));
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001987
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001988 return ret;
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02001989}
1990
1991/*
1992 * Transmit or retransmit the current flight of messages.
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001993 *
1994 * Need to remember the current message in case flush_output returns
1995 * WANT_WRITE, causing us to exit this function and come back later.
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02001996 * This function must be called until state is no longer SENDING.
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001997 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001998int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02001999{
Janos Follath865b3eb2019-12-16 11:46:15 +00002000 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002001 MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit"));
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002002
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002003 if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) {
2004 MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission"));
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002005
2006 ssl->handshake->cur_msg = ssl->handshake->flight;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002007 ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002008 ret = ssl_swap_epochs(ssl);
2009 if (ret != 0)
2010 return ret;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002011
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002013 }
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002014
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002015 while (ssl->handshake->cur_msg != NULL) {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002016 size_t max_frag_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002017 const mbedtls_ssl_flight_item *const cur = ssl->handshake->cur_msg;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002018
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002019 int const is_finished = (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
2020 cur->p[0] == MBEDTLS_SSL_HS_FINISHED);
Hanno Beckere1dcb032018-08-17 16:47:58 +01002021
Hanno Becker04da1892018-08-14 13:22:10 +01002022 uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002023 SSL_FORCE_FLUSH :
2024 SSL_DONT_FORCE_FLUSH;
Hanno Becker04da1892018-08-14 13:22:10 +01002025
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002026 /* Swap epochs before sending Finished: we can't do it after
2027 * sending ChangeCipherSpec, in case write returns WANT_READ.
2028 * Must be done before copying, may change out_msg pointer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002029 if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) {
2030 MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message"));
2031 ret = ssl_swap_epochs(ssl);
2032 if (ret != 0)
2033 return ret;
Manuel Pégourié-Gonnardc715aed2014-09-19 21:39:13 +02002034 }
2035
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002036 ret = ssl_get_remaining_payload_in_datagram(ssl);
2037 if (ret < 0)
2038 return ret;
2039 max_frag_len = (size_t)ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002040
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002041 /* CCS is copied as is, while HS messages may need fragmentation */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002042 if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
2043 if (max_frag_len == 0) {
2044 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0)
2045 return ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002046
2047 continue;
2048 }
2049
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002050 memcpy(ssl->out_msg, cur->p, cur->len);
2051 ssl->out_msglen = cur->len;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002052 ssl->out_msgtype = cur->type;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002053
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002054 /* Update position inside current message */
2055 ssl->handshake->cur_msg_p += cur->len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002056 } else {
2057 const unsigned char *const p = ssl->handshake->cur_msg_p;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002058 const size_t hs_len = cur->len - 12;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002059 const size_t frag_off = p - (cur->p + 12);
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002060 const size_t rem_len = hs_len - frag_off;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002061 size_t cur_hs_frag_len, max_hs_frag_len;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002062
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002063 if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) {
2064 if (is_finished) {
2065 ret = ssl_swap_epochs(ssl);
2066 if (ret != 0)
2067 return ret;
Manuel Pégourié-Gonnarde07bc202020-02-26 09:53:42 +01002068 }
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002069
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002070 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0)
2071 return ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002072
2073 continue;
2074 }
2075 max_hs_frag_len = max_frag_len - 12;
2076
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002077 cur_hs_frag_len = rem_len > max_hs_frag_len ? max_hs_frag_len :
2078 rem_len;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002079
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002080 if (frag_off == 0 && cur_hs_frag_len != hs_len) {
2081 MBEDTLS_SSL_DEBUG_MSG(
2082 2, ("fragmenting handshake message (%u > %u)",
2083 (unsigned)cur_hs_frag_len, (unsigned)max_hs_frag_len));
Manuel Pégourié-Gonnard19c62f92018-08-16 10:50:39 +02002084 }
Manuel Pégourié-Gonnardb747c6c2018-08-12 13:28:53 +02002085
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002086 /* Messages are stored with handshake headers as if not fragmented,
2087 * copy beginning of headers then fill fragmentation fields.
2088 * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002089 memcpy(ssl->out_msg, cur->p, 6);
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002090
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002091 ssl->out_msg[6] = ((frag_off >> 16) & 0xff);
2092 ssl->out_msg[7] = ((frag_off >> 8) & 0xff);
2093 ssl->out_msg[8] = ((frag_off)&0xff);
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002094
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002095 ssl->out_msg[9] = ((cur_hs_frag_len >> 16) & 0xff);
2096 ssl->out_msg[10] = ((cur_hs_frag_len >> 8) & 0xff);
2097 ssl->out_msg[11] = ((cur_hs_frag_len)&0xff);
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002098
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002099 MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12);
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002100
Hanno Becker3f7b9732018-08-28 09:53:25 +01002101 /* Copy the handshake message content and set records fields */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002102 memcpy(ssl->out_msg + 12, p, cur_hs_frag_len);
Hanno Becker67bc7c32018-08-06 11:33:50 +01002103 ssl->out_msglen = cur_hs_frag_len + 12;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002104 ssl->out_msgtype = cur->type;
2105
2106 /* Update position inside current message */
Hanno Becker67bc7c32018-08-06 11:33:50 +01002107 ssl->handshake->cur_msg_p += cur_hs_frag_len;
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002108 }
2109
2110 /* If done with the current message move to the next one if any */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002111 if (ssl->handshake->cur_msg_p >= cur->p + cur->len) {
2112 if (cur->next != NULL) {
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002113 ssl->handshake->cur_msg = cur->next;
2114 ssl->handshake->cur_msg_p = cur->next->p + 12;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002115 } else {
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002116 ssl->handshake->cur_msg = NULL;
2117 ssl->handshake->cur_msg_p = NULL;
2118 }
2119 }
2120
2121 /* Actually send the message out */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002122 if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
2123 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
2124 return ret;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002125 }
2126 }
2127
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002128 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0)
2129 return ret;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002130
Manuel Pégourié-Gonnard28f4bea2017-09-13 14:00:05 +02002131 /* Update state and set timer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002132 if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002133 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002134 else {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002135 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002136 mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
Manuel Pégourié-Gonnard4e2f2452014-10-02 16:51:56 +02002137 }
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002139 MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit"));
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002140
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002141 return 0;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002142}
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002143
2144/*
2145 * To be called when the last message of an incoming flight is received.
2146 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002147void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002148{
2149 /* We won't need to resend that one any more */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002150 mbedtls_ssl_flight_free(ssl->handshake->flight);
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002151 ssl->handshake->flight = NULL;
2152 ssl->handshake->cur_msg = NULL;
2153
2154 /* The next incoming flight will start with this msg_seq */
2155 ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
2156
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01002157 /* We don't want to remember CCS's across flight boundaries. */
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01002158 ssl->handshake->buffering.seen_ccs = 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01002159
Hanno Becker0271f962018-08-16 13:23:47 +01002160 /* Clear future message buffering structure. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002161 mbedtls_ssl_buffering_free(ssl);
Hanno Becker0271f962018-08-16 13:23:47 +01002162
Manuel Pégourié-Gonnard6c1fa3a2014-10-01 16:58:16 +02002163 /* Cancel timer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002164 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002166 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2167 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002169 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002170 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
Manuel Pégourié-Gonnard5d8ba532014-09-19 15:09:21 +02002171}
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002172
2173/*
2174 * To be called when the last message of an outgoing flight is send.
2175 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002176void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002177{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002178 ssl_reset_retransmit_timeout(ssl);
2179 mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002180
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002181 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2182 ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002183 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002184 } else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185 ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
Manuel Pégourié-Gonnard7de3c9e2014-09-29 15:29:48 +02002186}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002187# endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002188
Paul Bakker5121ce52009-01-03 21:22:43 +00002189/*
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002190 * Handshake layer functions
Paul Bakker5121ce52009-01-03 21:22:43 +00002191 */
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002192
2193/*
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002194 * Write (DTLS: or queue) current handshake (including CCS) message.
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002195 *
2196 * - fill in handshake headers
2197 * - update handshake checksum
2198 * - DTLS: save message for resending
2199 * - then pass to the record layer
2200 *
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002201 * DTLS: except for HelloRequest, messages are only queued, and will only be
2202 * actually sent when calling flight_transmit() or resend().
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002203 *
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002204 * Inputs:
2205 * - ssl->out_msglen: 4 + actual handshake message len
2206 * (4 is the size of handshake headers for TLS)
2207 * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
2208 * - ssl->out_msg + 4: the handshake message body
2209 *
Manuel Pégourié-Gonnard065a2a32018-08-20 11:09:26 +02002210 * Outputs, ie state before passing to flight_append() or write_record():
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002211 * - ssl->out_msglen: the length of the record contents
2212 * (including handshake headers but excluding record headers)
2213 * - ssl->out_msg: the record contents (handshake headers + content)
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002214 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002215int mbedtls_ssl_write_handshake_msg(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00002216{
Janos Follath865b3eb2019-12-16 11:46:15 +00002217 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002218 const size_t hs_len = ssl->out_msglen - 4;
2219 const unsigned char hs_type = ssl->out_msg[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00002220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002221 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message"));
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002222
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002223 /*
2224 * Sanity checks
2225 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002226 if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
2227 ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
2228 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2229 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002230 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
Andrzej Kurekc470b6b2019-01-31 08:20:20 -05002232 /* Whenever we send anything different from a
2233 * HelloRequest we should be in a handshake - double check. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002234 if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2235 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST) &&
2236 ssl->handshake == NULL) {
2237 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2238 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002239 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002240
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002241# if defined(MBEDTLS_SSL_PROTO_DTLS)
2242 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002243 ssl->handshake != NULL &&
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002244 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
2245 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2246 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002247 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002248# endif
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002249
Hanno Beckerb50a2532018-08-06 11:52:54 +01002250 /* Double-check that we did not exceed the bounds
2251 * of the outgoing record buffer.
2252 * This should never fail as the various message
2253 * writing functions must obey the bounds of the
2254 * outgoing record buffer, but better be safe.
2255 *
2256 * Note: We deliberately do not check for the MTU or MFL here.
2257 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002258 if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) {
2259 MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: "
2260 "size %" MBEDTLS_PRINTF_SIZET
2261 ", maximum %" MBEDTLS_PRINTF_SIZET,
2262 ssl->out_msglen,
2263 (size_t)MBEDTLS_SSL_OUT_CONTENT_LEN));
2264 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Beckerb50a2532018-08-06 11:52:54 +01002265 }
2266
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002267 /*
2268 * Fill handshake headers
2269 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002270 if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
2271 ssl->out_msg[1] = (unsigned char)(hs_len >> 16);
2272 ssl->out_msg[2] = (unsigned char)(hs_len >> 8);
2273 ssl->out_msg[3] = (unsigned char)(hs_len);
Paul Bakker5121ce52009-01-03 21:22:43 +00002274
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002275 /*
2276 * DTLS has additional fields in the Handshake layer,
2277 * between the length field and the actual payload:
2278 * uint16 message_seq;
2279 * uint24 fragment_offset;
2280 * uint24 fragment_length;
2281 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002282# if defined(MBEDTLS_SSL_PROTO_DTLS)
2283 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnarde89bcf02014-02-18 18:50:02 +01002284 /* Make room for the additional DTLS fields */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002285 if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) {
2286 MBEDTLS_SSL_DEBUG_MSG(
2287 1, ("DTLS handshake message too large: "
2288 "size %" MBEDTLS_PRINTF_SIZET
2289 ", maximum %" MBEDTLS_PRINTF_SIZET,
2290 hs_len, (size_t)(MBEDTLS_SSL_OUT_CONTENT_LEN - 12)));
2291 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Hanno Becker9648f8b2017-09-18 10:55:54 +01002292 }
2293
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002294 memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len);
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002295 ssl->out_msglen += 8;
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002296
Manuel Pégourié-Gonnardc392b242014-08-19 17:53:11 +02002297 /* Write message_seq and update it, except for HelloRequest */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002298 if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) {
2299 ssl->out_msg[4] = (ssl->handshake->out_msg_seq >> 8) & 0xFF;
2300 ssl->out_msg[5] = (ssl->handshake->out_msg_seq) & 0xFF;
2301 ++(ssl->handshake->out_msg_seq);
2302 } else {
Manuel Pégourié-Gonnardc392b242014-08-19 17:53:11 +02002303 ssl->out_msg[4] = 0;
2304 ssl->out_msg[5] = 0;
2305 }
Manuel Pégourié-Gonnarde89bcf02014-02-18 18:50:02 +01002306
Manuel Pégourié-Gonnard9c3a8ca2017-09-13 09:54:27 +02002307 /* Handshake hashes are computed without fragmentation,
2308 * so set frag_offset = 0 and frag_len = hs_len for now */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002309 memset(ssl->out_msg + 6, 0x00, 3);
2310 memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3);
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002311 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002312# endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnardce441b32014-02-18 17:40:52 +01002313
Hanno Becker0207e532018-08-28 10:28:28 +01002314 /* Update running hashes of handshake messages seen */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002315 if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST)
2316 ssl->handshake->update_checksum(ssl, ssl->out_msg, ssl->out_msglen);
Paul Bakker5121ce52009-01-03 21:22:43 +00002317 }
2318
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002319 /* Either send now, or just save to be sent (and resent) later */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002320# if defined(MBEDTLS_SSL_PROTO_DTLS)
2321 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2322 !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2323 hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST)) {
2324 if ((ret = ssl_flight_append(ssl)) != 0) {
2325 MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret);
2326 return ret;
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002327 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002328 } else
2329# endif
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002330 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002331 if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
2332 MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret);
2333 return ret;
Manuel Pégourié-Gonnard87a346f2017-09-13 12:45:21 +02002334 }
2335 }
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002336
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002337 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message"));
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002338
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002339 return 0;
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002340}
2341
2342/*
2343 * Record layer functions
2344 */
2345
2346/*
2347 * Write current record.
2348 *
2349 * Uses:
2350 * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
2351 * - ssl->out_msglen: length of the record content (excl headers)
2352 * - ssl->out_msg: record content
2353 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002354int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, uint8_t force_flush)
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002355{
2356 int ret, done = 0;
2357 size_t len = ssl->out_msglen;
Hanno Becker67bc7c32018-08-06 11:33:50 +01002358 uint8_t flush = force_flush;
Manuel Pégourié-Gonnard31c15862017-09-13 09:38:11 +02002359
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002360 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record"));
Manuel Pégourié-Gonnardffa67be2014-09-19 11:18:57 +02002361
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002362 if (!done) {
Hanno Becker2b1e3542018-08-06 11:19:13 +01002363 unsigned i;
2364 size_t protected_record_size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002365# if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Darryl Greenb33cc762019-11-28 14:29:44 +00002366 size_t out_buf_len = ssl->out_buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002367# else
Darryl Greenb33cc762019-11-28 14:29:44 +00002368 size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002369# endif
Hanno Becker6430faf2019-05-08 11:57:13 +01002370 /* Skip writing the record content type to after the encryption,
2371 * as it may change when using the CID extension. */
2372
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002373 mbedtls_ssl_write_version(ssl->major_ver, ssl->minor_ver,
2374 ssl->conf->transport, ssl->out_hdr + 1);
Manuel Pégourié-Gonnard507e1e42014-02-13 11:17:34 +01002375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002376 memcpy(ssl->out_ctr, ssl->cur_out_ctr, 8);
2377 ssl->out_len[0] = (unsigned char)(len >> 8);
2378 ssl->out_len[1] = (unsigned char)(len);
Paul Bakker05ef8352012-05-08 09:17:57 +00002379
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002380 if (ssl->transform_out != NULL) {
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002381 mbedtls_record rec;
2382
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002383 rec.buf = ssl->out_iv;
2384 rec.buf_len = out_buf_len - (ssl->out_iv - ssl->out_buf);
2385 rec.data_len = ssl->out_msglen;
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002386 rec.data_offset = ssl->out_msg - rec.buf;
2387
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002388 memcpy(&rec.ctr[0], ssl->out_ctr, 8);
2389 mbedtls_ssl_write_version(ssl->major_ver, ssl->minor_ver,
2390 ssl->conf->transport, rec.ver);
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002391 rec.type = ssl->out_msgtype;
2392
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002393# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker43c24b82019-05-01 09:45:57 +01002394 /* The CID is set by mbedtls_ssl_encrypt_buf(). */
Hanno Beckercab87e62019-04-29 13:52:53 +01002395 rec.cid_len = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002396# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckercab87e62019-04-29 13:52:53 +01002397
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002398 if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec,
2399 ssl->conf->f_rng,
2400 ssl->conf->p_rng)) != 0) {
2401 MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret);
2402 return ret;
Paul Bakker05ef8352012-05-08 09:17:57 +00002403 }
2404
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002405 if (rec.data_offset != 0) {
2406 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2407 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker9eddaeb2017-12-27 21:37:21 +00002408 }
2409
Hanno Becker6430faf2019-05-08 11:57:13 +01002410 /* Update the record content type and CID. */
2411 ssl->out_msgtype = rec.type;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002412# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2413 memcpy(ssl->out_cid, rec.cid, rec.cid_len);
2414# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker78f839d2019-03-14 12:56:23 +00002415 ssl->out_msglen = len = rec.data_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002416 ssl->out_len[0] = (unsigned char)(rec.data_len >> 8);
2417 ssl->out_len[1] = (unsigned char)(rec.data_len);
Paul Bakker05ef8352012-05-08 09:17:57 +00002418 }
2419
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002420 protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl);
Hanno Becker2b1e3542018-08-06 11:19:13 +01002421
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002422# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker2b1e3542018-08-06 11:19:13 +01002423 /* In case of DTLS, double-check that we don't exceed
2424 * the remaining space in the datagram. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002425 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
2426 ret = ssl_get_remaining_space_in_datagram(ssl);
2427 if (ret < 0)
2428 return ret;
Hanno Becker2b1e3542018-08-06 11:19:13 +01002429
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002430 if (protected_record_size > (size_t)ret) {
Hanno Becker2b1e3542018-08-06 11:19:13 +01002431 /* Should never happen */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002432 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker2b1e3542018-08-06 11:19:13 +01002433 }
2434 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002435# endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker05ef8352012-05-08 09:17:57 +00002436
Hanno Becker6430faf2019-05-08 11:57:13 +01002437 /* Now write the potentially updated record content type. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002438 ssl->out_hdr[0] = (unsigned char)ssl->out_msgtype;
Hanno Becker6430faf2019-05-08 11:57:13 +01002439
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002440 MBEDTLS_SSL_DEBUG_MSG(
2441 3, ("output record: msgtype = %u, "
2442 "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
2443 ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], len));
Paul Bakker05ef8352012-05-08 09:17:57 +00002444
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002445 MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", ssl->out_hdr,
2446 protected_record_size);
Hanno Becker2b1e3542018-08-06 11:19:13 +01002447
2448 ssl->out_left += protected_record_size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002449 ssl->out_hdr += protected_record_size;
2450 mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
Hanno Becker2b1e3542018-08-06 11:19:13 +01002451
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002452 for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--)
2453 if (++ssl->cur_out_ctr[i - 1] != 0)
Hanno Becker04484622018-08-06 09:49:38 +01002454 break;
2455
2456 /* The loop goes to its end iff the counter is wrapping */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002457 if (i == mbedtls_ssl_ep_len(ssl)) {
2458 MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap"));
2459 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
Hanno Becker04484622018-08-06 09:49:38 +01002460 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002461 }
2462
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002463# if defined(MBEDTLS_SSL_PROTO_DTLS)
2464 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2465 flush == SSL_DONT_FORCE_FLUSH) {
Hanno Becker1f5a15d2018-08-21 13:31:31 +01002466 size_t remaining;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002467 ret = ssl_get_remaining_payload_in_datagram(ssl);
2468 if (ret < 0) {
2469 MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram",
2470 ret);
2471 return ret;
Hanno Becker1f5a15d2018-08-21 13:31:31 +01002472 }
2473
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002474 remaining = (size_t)ret;
2475 if (remaining == 0) {
Hanno Becker67bc7c32018-08-06 11:33:50 +01002476 flush = SSL_FORCE_FLUSH;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002477 } else {
2478 MBEDTLS_SSL_DEBUG_MSG(
2479 2, ("Still %u bytes available in current datagram",
2480 (unsigned)remaining));
Hanno Becker67bc7c32018-08-06 11:33:50 +01002481 }
2482 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002483# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker67bc7c32018-08-06 11:33:50 +01002484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002485 if ((flush == SSL_FORCE_FLUSH) &&
2486 (ret = mbedtls_ssl_flush_output(ssl)) != 0) {
2487 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
2488 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002489 }
2490
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002491 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record"));
Paul Bakker5121ce52009-01-03 21:22:43 +00002492
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002493 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00002494}
2495
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002496# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Beckere25e3b72018-08-16 09:30:53 +01002497
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002498static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl)
Hanno Beckere25e3b72018-08-16 09:30:53 +01002499{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002500 if (ssl->in_msglen < ssl->in_hslen ||
2501 memcmp(ssl->in_msg + 6, "\0\0\0", 3) != 0 ||
2502 memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) {
2503 return 1;
Hanno Beckere25e3b72018-08-16 09:30:53 +01002504 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002505 return 0;
Hanno Beckere25e3b72018-08-16 09:30:53 +01002506}
Hanno Becker44650b72018-08-16 12:51:11 +01002507
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002508static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
Hanno Becker44650b72018-08-16 12:51:11 +01002509{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002510 return ((ssl->in_msg[9] << 16) | (ssl->in_msg[10] << 8) | ssl->in_msg[11]);
Hanno Becker44650b72018-08-16 12:51:11 +01002511}
2512
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002513static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
Hanno Becker44650b72018-08-16 12:51:11 +01002514{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002515 return ((ssl->in_msg[6] << 16) | (ssl->in_msg[7] << 8) | ssl->in_msg[8]);
Hanno Becker44650b72018-08-16 12:51:11 +01002516}
2517
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002518static int ssl_check_hs_header(mbedtls_ssl_context const *ssl)
Hanno Becker44650b72018-08-16 12:51:11 +01002519{
2520 uint32_t msg_len, frag_off, frag_len;
2521
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002522 msg_len = ssl_get_hs_total_len(ssl);
2523 frag_off = ssl_get_hs_frag_off(ssl);
2524 frag_len = ssl_get_hs_frag_len(ssl);
Hanno Becker44650b72018-08-16 12:51:11 +01002525
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002526 if (frag_off > msg_len)
2527 return -1;
Hanno Becker44650b72018-08-16 12:51:11 +01002528
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002529 if (frag_len > msg_len - frag_off)
2530 return -1;
Hanno Becker44650b72018-08-16 12:51:11 +01002531
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002532 if (frag_len + 12 > ssl->in_msglen)
2533 return -1;
Hanno Becker44650b72018-08-16 12:51:11 +01002534
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002535 return 0;
Hanno Becker44650b72018-08-16 12:51:11 +01002536}
2537
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002538/*
2539 * Mark bits in bitmask (used for DTLS HS reassembly)
2540 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002541static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len)
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002542{
2543 unsigned int start_bits, end_bits;
2544
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002545 start_bits = 8 - (offset % 8);
2546 if (start_bits != 8) {
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002547 size_t first_byte_idx = offset / 8;
2548
Manuel Pégourié-Gonnardac030522014-09-02 14:23:40 +02002549 /* Special case */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002550 if (len <= start_bits) {
2551 for (; len != 0; len--)
2552 mask[first_byte_idx] |= 1 << (start_bits - len);
Manuel Pégourié-Gonnardac030522014-09-02 14:23:40 +02002553
2554 /* Avoid potential issues with offset or len becoming invalid */
2555 return;
2556 }
2557
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002558 offset += start_bits; /* Now offset % 8 == 0 */
2559 len -= start_bits;
2560
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002561 for (; start_bits != 0; start_bits--)
2562 mask[first_byte_idx] |= 1 << (start_bits - 1);
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002563 }
2564
2565 end_bits = len % 8;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002566 if (end_bits != 0) {
2567 size_t last_byte_idx = (offset + len) / 8;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002568
2569 len -= end_bits; /* Now len % 8 == 0 */
2570
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002571 for (; end_bits != 0; end_bits--)
2572 mask[last_byte_idx] |= 1 << (8 - end_bits);
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002573 }
2574
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002575 memset(mask + offset / 8, 0xFF, len / 8);
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002576}
2577
2578/*
2579 * Check that bitmask is full
2580 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002581static int ssl_bitmask_check(unsigned char *mask, size_t len)
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002582{
2583 size_t i;
2584
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002585 for (i = 0; i < len / 8; i++)
2586 if (mask[i] != 0xFF)
2587 return -1;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002588
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002589 for (i = 0; i < len % 8; i++)
2590 if ((mask[len / 8] & (1 << (7 - i))) == 0)
2591 return -1;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002592
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002593 return 0;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002594}
2595
Hanno Becker56e205e2018-08-16 09:06:12 +01002596/* msg_len does not include the handshake header */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002597static size_t ssl_get_reassembly_buffer_size(size_t msg_len,
2598 unsigned add_bitmap)
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002599{
Hanno Becker56e205e2018-08-16 09:06:12 +01002600 size_t alloc_len;
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002601
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002602 alloc_len = 12; /* Handshake header */
2603 alloc_len += msg_len; /* Content buffer */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002604
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002605 if (add_bitmap)
2606 alloc_len += msg_len / 8 + (msg_len % 8 != 0); /* Bitmap */
Manuel Pégourié-Gonnard502bf302014-08-20 13:12:58 +02002607
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002608 return alloc_len;
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002609}
Hanno Becker56e205e2018-08-16 09:06:12 +01002610
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002611# endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002612
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002613static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
Hanno Becker12555c62018-08-16 12:47:53 +01002614{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002615 return ((ssl->in_msg[1] << 16) | (ssl->in_msg[2] << 8) | ssl->in_msg[3]);
Hanno Becker12555c62018-08-16 12:47:53 +01002616}
Hanno Beckere25e3b72018-08-16 09:30:53 +01002617
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002618int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002619{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002620 if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
2621 MBEDTLS_SSL_DEBUG_MSG(
2622 1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
2623 ssl->in_msglen));
2624 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Manuel Pégourié-Gonnard9d1d7192014-09-03 11:01:14 +02002625 }
2626
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002627 ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002628
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002629 MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
2630 " %" MBEDTLS_PRINTF_SIZET
2631 ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET,
2632 ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002633
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002634# if defined(MBEDTLS_SSL_PROTO_DTLS)
2635 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Janos Follath865b3eb2019-12-16 11:46:15 +00002636 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002637 unsigned int recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5];
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002638
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002639 if (ssl_check_hs_header(ssl) != 0) {
2640 MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header"));
2641 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker44650b72018-08-16 12:51:11 +01002642 }
2643
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002644 if (ssl->handshake != NULL &&
2645 ((ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
2646 recv_msg_seq != ssl->handshake->in_msg_seq) ||
2647 (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
2648 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) {
2649 if (recv_msg_seq > ssl->handshake->in_msg_seq) {
2650 MBEDTLS_SSL_DEBUG_MSG(
2651 2,
2652 ("received future handshake message of sequence number %u (next %u)",
2653 recv_msg_seq, ssl->handshake->in_msg_seq));
2654 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
Hanno Becker9e1ec222018-08-15 15:54:43 +01002655 }
2656
Manuel Pégourié-Gonnardfc572dd2014-10-09 17:56:57 +02002657 /* Retransmit only on last message from previous flight, to avoid
2658 * too many retransmissions.
2659 * Besides, No sane server ever retransmits HelloVerifyRequest */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002660 if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
2661 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
2662 MBEDTLS_SSL_DEBUG_MSG(
2663 2, ("received message from last flight, "
2664 "message_seq = %u, start_of_flight = %u",
2665 recv_msg_seq, ssl->handshake->in_flight_start_seq));
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02002666
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002667 if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
2668 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
2669 return ret;
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02002670 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002671 } else {
2672 MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: "
2673 "message_seq = %u, expected = %u",
2674 recv_msg_seq,
2675 ssl->handshake->in_msg_seq));
Manuel Pégourié-Gonnard6a2bdfa2014-09-19 21:18:23 +02002676 }
2677
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002678 return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02002679 }
2680 /* Wait until message completion to increment in_msg_seq */
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002681
Hanno Becker6d97ef52018-08-16 13:09:04 +01002682 /* Message reassembly is handled alongside buffering of future
2683 * messages; the commonality is that both handshake fragments and
Hanno Becker83ab41c2018-08-28 17:19:38 +01002684 * future messages cannot be forwarded immediately to the
Hanno Becker6d97ef52018-08-16 13:09:04 +01002685 * handshake logic layer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002686 if (ssl_hs_is_proper_fragment(ssl) == 1) {
2687 MBEDTLS_SSL_DEBUG_MSG(2,
2688 ("found fragmented DTLS handshake message"));
2689 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
Manuel Pégourié-Gonnarded79a4b2014-08-20 10:43:01 +02002690 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002691 } else
2692# endif /* MBEDTLS_SSL_PROTO_DTLS */
2693 /* With TLS we don't handle fragmentation (for now) */
2694 if (ssl->in_msglen < ssl->in_hslen) {
2695 MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported"));
2696 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002697 }
2698
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002699 return 0;
Simon Butcher99000142016-10-13 17:21:01 +01002700}
2701
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002702void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
Simon Butcher99000142016-10-13 17:21:01 +01002703{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002704 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
Simon Butcher99000142016-10-13 17:21:01 +01002705
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002706 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL) {
2707 ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
Manuel Pégourié-Gonnard14bf7062015-06-23 14:07:13 +02002708 }
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002709
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02002710 /* Handshake message is complete, increment counter */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002711# if defined(MBEDTLS_SSL_PROTO_DTLS)
2712 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2713 ssl->handshake != NULL) {
Hanno Becker0271f962018-08-16 13:23:47 +01002714 unsigned offset;
2715 mbedtls_ssl_hs_buffer *hs_buf;
Hanno Beckere25e3b72018-08-16 09:30:53 +01002716
Hanno Becker0271f962018-08-16 13:23:47 +01002717 /* Increment handshake sequence number */
2718 hs->in_msg_seq++;
2719
2720 /*
2721 * Clear up handshake buffering and reassembly structure.
2722 */
2723
2724 /* Free first entry */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002725 ssl_buffering_free_slot(ssl, 0);
Hanno Becker0271f962018-08-16 13:23:47 +01002726
2727 /* Shift all other entries */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002728 for (offset = 0, hs_buf = &hs->buffering.hs[0];
2729 offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++, hs_buf++) {
Hanno Becker0271f962018-08-16 13:23:47 +01002730 *hs_buf = *(hs_buf + 1);
2731 }
2732
2733 /* Create a fresh last entry */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002734 memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
Manuel Pégourié-Gonnard1aa586e2014-09-03 12:54:04 +02002735 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002736# endif
Manuel Pégourié-Gonnarda59543a2014-02-18 11:33:49 +01002737}
2738
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02002739/*
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002740 * DTLS anti-replay: RFC 6347 4.1.2.6
2741 *
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02002742 * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
2743 * Bit n is set iff record number in_window_top - n has been seen.
2744 *
2745 * Usually, in_window_top is the last record number seen and the lsb of
2746 * in_window is set. The only exception is the initial state (record number 0
2747 * not seen yet).
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002748 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002749# if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
2750void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002751{
2752 ssl->in_window_top = 0;
2753 ssl->in_window = 0;
2754}
2755
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002756static inline uint64_t ssl_load_six_bytes(unsigned char *buf)
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002757{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002758 return (((uint64_t)buf[0] << 40) | ((uint64_t)buf[1] << 32) |
2759 ((uint64_t)buf[2] << 24) | ((uint64_t)buf[3] << 16) |
2760 ((uint64_t)buf[4] << 8) | ((uint64_t)buf[5]));
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002761}
2762
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002763static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl,
2764 uint8_t *record_in_ctr)
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02002765{
Janos Follath865b3eb2019-12-16 11:46:15 +00002766 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02002767 unsigned char *original_in_ctr;
2768
2769 // save original in_ctr
2770 original_in_ctr = ssl->in_ctr;
2771
2772 // use counter from record
2773 ssl->in_ctr = record_in_ctr;
2774
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002775 ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *)ssl);
Arto Kinnunen7f8089b2019-10-29 11:13:33 +02002776
2777 // restore the counter
2778 ssl->in_ctr = original_in_ctr;
2779
2780 return ret;
2781}
2782
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002783/*
2784 * Return 0 if sequence number is acceptable, -1 otherwise
2785 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002786int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl)
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002787{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002788 uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002789 uint64_t bit;
2790
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002791 if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED)
2792 return 0;
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02002793
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002794 if (rec_seqnum > ssl->in_window_top)
2795 return 0;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002796
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02002797 bit = ssl->in_window_top - rec_seqnum;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002798
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002799 if (bit >= 64)
2800 return -1;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002801
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002802 if ((ssl->in_window & ((uint64_t)1 << bit)) != 0)
2803 return -1;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002804
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002805 return 0;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002806}
2807
2808/*
2809 * Update replay window on new validated record
2810 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002811void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002812{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002813 uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002814
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002815 if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED)
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02002816 return;
2817
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002818 if (rec_seqnum > ssl->in_window_top) {
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002819 /* Update window_top and the contents of the window */
2820 uint64_t shift = rec_seqnum - ssl->in_window_top;
2821
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002822 if (shift >= 64)
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02002823 ssl->in_window = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002824 else {
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002825 ssl->in_window <<= shift;
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02002826 ssl->in_window |= 1;
2827 }
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002828
2829 ssl->in_window_top = rec_seqnum;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002830 } else {
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002831 /* Mark that number as seen in the current window */
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02002832 uint64_t bit = ssl->in_window_top - rec_seqnum;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002833
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002834 if (bit < 64) /* Always true, but be extra sure */
2835 ssl->in_window |= (uint64_t)1 << bit;
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002836 }
2837}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002838# endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02002839
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002840# if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
2841 defined(MBEDTLS_SSL_SRV_C)
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002842/*
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002843 * Without any SSL context, check if a datagram looks like a ClientHello with
2844 * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
Simon Butcher0789aed2015-09-11 17:15:17 +01002845 * Both input and output include full DTLS headers.
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002846 *
2847 * - if cookie is valid, return 0
2848 * - if ClientHello looks superficially valid but cookie is not,
2849 * fill obuf and set olen, then
2850 * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
2851 * - otherwise return a specific error code
2852 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002853static int
2854ssl_check_dtls_clihlo_cookie(mbedtls_ssl_cookie_write_t *f_cookie_write,
2855 mbedtls_ssl_cookie_check_t *f_cookie_check,
2856 void *p_cookie,
2857 const unsigned char *cli_id,
2858 size_t cli_id_len,
2859 const unsigned char *in,
2860 size_t in_len,
2861 unsigned char *obuf,
2862 size_t buf_len,
2863 size_t *olen)
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002864{
2865 size_t sid_len, cookie_len;
2866 unsigned char *p;
2867
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002868 /*
2869 * Structure of ClientHello with record and handshake headers,
2870 * and expected values. We don't need to check a lot, more checks will be
2871 * done when actually parsing the ClientHello - skipping those checks
2872 * avoids code duplication and does not make cookie forging any easier.
2873 *
2874 * 0-0 ContentType type; copied, must be handshake
2875 * 1-2 ProtocolVersion version; copied
2876 * 3-4 uint16 epoch; copied, must be 0
2877 * 5-10 uint48 sequence_number; copied
2878 * 11-12 uint16 length; (ignored)
2879 *
2880 * 13-13 HandshakeType msg_type; (ignored)
2881 * 14-16 uint24 length; (ignored)
2882 * 17-18 uint16 message_seq; copied
2883 * 19-21 uint24 fragment_offset; copied, must be 0
2884 * 22-24 uint24 fragment_length; (ignored)
2885 *
2886 * 25-26 ProtocolVersion client_version; (ignored)
2887 * 27-58 Random random; (ignored)
2888 * 59-xx SessionID session_id; 1 byte len + sid_len content
2889 * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
2890 * ...
2891 *
2892 * Minimum length is 61 bytes.
2893 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002894 if (in_len < 61 || in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || in[3] != 0 ||
2895 in[4] != 0 || in[19] != 0 || in[20] != 0 || in[21] != 0) {
2896 return MBEDTLS_ERR_SSL_DECODE_ERROR;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002897 }
2898
2899 sid_len = in[59];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002900 if (sid_len > in_len - 61)
2901 return MBEDTLS_ERR_SSL_DECODE_ERROR;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002902
2903 cookie_len = in[60 + sid_len];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002904 if (cookie_len > in_len - 60)
2905 return MBEDTLS_ERR_SSL_DECODE_ERROR;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002906
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002907 if (f_cookie_check(p_cookie, in + sid_len + 61, cookie_len, cli_id,
2908 cli_id_len) == 0) {
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002909 /* Valid cookie */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002910 return 0;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002911 }
2912
2913 /*
2914 * If we get here, we've got an invalid cookie, let's prepare HVR.
2915 *
2916 * 0-0 ContentType type; copied
2917 * 1-2 ProtocolVersion version; copied
2918 * 3-4 uint16 epoch; copied
2919 * 5-10 uint48 sequence_number; copied
2920 * 11-12 uint16 length; olen - 13
2921 *
2922 * 13-13 HandshakeType msg_type; hello_verify_request
2923 * 14-16 uint24 length; olen - 25
2924 * 17-18 uint16 message_seq; copied
2925 * 19-21 uint24 fragment_offset; copied
2926 * 22-24 uint24 fragment_length; olen - 25
2927 *
2928 * 25-26 ProtocolVersion server_version; 0xfe 0xff
2929 * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
2930 *
2931 * Minimum length is 28.
2932 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002933 if (buf_len < 28)
2934 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002935
2936 /* Copy most fields and adapt others */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002937 memcpy(obuf, in, 25);
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002938 obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
2939 obuf[25] = 0xfe;
2940 obuf[26] = 0xff;
2941
2942 /* Generate and write actual cookie */
2943 p = obuf + 28;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002944 if (f_cookie_write(p_cookie, &p, obuf + buf_len, cli_id, cli_id_len) != 0) {
2945 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002946 }
2947
2948 *olen = p - obuf;
2949
2950 /* Go back and fill length fields */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002951 obuf[27] = (unsigned char)(*olen - 28);
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002952
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002953 obuf[14] = obuf[22] = (unsigned char)((*olen - 25) >> 16);
2954 obuf[15] = obuf[23] = (unsigned char)((*olen - 25) >> 8);
2955 obuf[16] = obuf[24] = (unsigned char)((*olen - 25));
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002956
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002957 obuf[11] = (unsigned char)((*olen - 13) >> 8);
2958 obuf[12] = (unsigned char)((*olen - 13));
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002959
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002960 return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002961}
2962
2963/*
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002964 * Handle possible client reconnect with the same UDP quadruplet
2965 * (RFC 6347 Section 4.2.8).
2966 *
2967 * Called by ssl_parse_record_header() in case we receive an epoch 0 record
2968 * that looks like a ClientHello.
2969 *
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002970 * - if the input looks like a ClientHello without cookies,
Manuel Pégourié-Gonnard824655c2020-03-11 12:51:42 +01002971 * send back HelloVerifyRequest, then return 0
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002972 * - if the input looks like a ClientHello with a valid cookie,
2973 * reset the session of the current context, and
Manuel Pégourié-Gonnardbe619c12015-09-08 11:21:21 +02002974 * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002975 * - if anything goes wrong, return a specific error code
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002976 *
Manuel Pégourié-Gonnard824655c2020-03-11 12:51:42 +01002977 * This function is called (through ssl_check_client_reconnect()) when an
2978 * unexpected record is found in ssl_get_next_record(), which will discard the
2979 * record if we return 0, and bubble up the return value otherwise (this
2980 * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
2981 * errors, and is the right thing to do in both cases).
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002982 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002983static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002984{
Janos Follath865b3eb2019-12-16 11:46:15 +00002985 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002986 size_t len;
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02002987
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002988 if (ssl->conf->f_cookie_write == NULL ||
2989 ssl->conf->f_cookie_check == NULL) {
Hanno Becker2fddd372019-07-10 14:37:41 +01002990 /* If we can't use cookies to verify reachability of the peer,
2991 * drop the record. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002992 MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, "
2993 "can't check reconnect validity"));
2994 return 0;
Hanno Becker2fddd372019-07-10 14:37:41 +01002995 }
2996
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02002997 ret = ssl_check_dtls_clihlo_cookie(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02002998 ssl->conf->f_cookie_write, ssl->conf->f_cookie_check,
2999 ssl->conf->p_cookie, ssl->cli_id, ssl->cli_id_len, ssl->in_buf,
3000 ssl->in_left, ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len);
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003001
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003002 MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_dtls_clihlo_cookie", ret);
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003003
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003004 if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003005 int send_ret;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003006 MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest"));
3007 MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network", ssl->out_buf,
3008 len);
Brian J Murray1903fb32016-11-06 04:45:15 -08003009 /* Don't check write errors as we can't do anything here.
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003010 * If the error is permanent we'll catch it later,
3011 * if it's not, then hopefully it'll work next time. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003012 send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len);
3013 MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret);
3014 (void)send_ret;
Manuel Pégourié-Gonnard243d70f2020-03-31 12:07:47 +02003015
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003016 return 0;
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003017 }
3018
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003019 if (ret == 0) {
3020 MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context"));
3021 if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) {
3022 MBEDTLS_SSL_DEBUG_RET(1, "reset", ret);
3023 return ret;
Manuel Pégourié-Gonnard62c74bb2015-09-08 17:50:29 +02003024 }
3025
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003026 return MBEDTLS_ERR_SSL_CLIENT_RECONNECT;
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003027 }
3028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003029 return ret;
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003030}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003031# endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Manuel Pégourié-Gonnard11331fc2015-09-08 10:30:55 +02003032
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003033static int ssl_check_record_type(uint8_t record_type)
Hanno Beckerf661c9c2019-05-03 13:25:54 +01003034{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003035 if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
Hanno Beckerf661c9c2019-05-03 13:25:54 +01003036 record_type != MBEDTLS_SSL_MSG_ALERT &&
3037 record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003038 record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
3039 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckerf661c9c2019-05-03 13:25:54 +01003040 }
3041
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003042 return 0;
Hanno Beckerf661c9c2019-05-03 13:25:54 +01003043}
3044
Manuel Pégourié-Gonnard7a7e1402014-09-24 10:52:58 +02003045/*
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003046 * ContentType type;
3047 * ProtocolVersion version;
3048 * uint16 epoch; // DTLS only
3049 * uint48 sequence_number; // DTLS only
3050 * uint16 length;
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003051 *
3052 * Return 0 if header looks sane (and, for DTLS, the record is expected)
Simon Butcher207990d2015-12-16 01:51:30 +00003053 * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003054 * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
3055 *
3056 * With DTLS, mbedtls_ssl_read_record() will:
Simon Butcher207990d2015-12-16 01:51:30 +00003057 * 1. proceed with the record if this function returns 0
3058 * 2. drop only the current record if this function returns UNEXPECTED_RECORD
3059 * 3. return CLIENT_RECONNECT if this function return that value
3060 * 4. drop the whole datagram if this function returns anything else.
3061 * Point 2 is needed when the peer is resending, and we have already received
3062 * the first record from a datagram but are still waiting for the others.
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003063 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003064static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
3065 unsigned char *buf,
3066 size_t len,
3067 mbedtls_record *rec)
Paul Bakker5121ce52009-01-03 21:22:43 +00003068{
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01003069 int major_ver, minor_ver;
Paul Bakker5121ce52009-01-03 21:22:43 +00003070
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003071 size_t const rec_hdr_type_offset = 0;
3072 size_t const rec_hdr_type_len = 1;
Manuel Pégourié-Gonnard64dffc52014-09-02 13:39:16 +02003073
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003074 size_t const rec_hdr_version_offset =
3075 rec_hdr_type_offset + rec_hdr_type_len;
3076 size_t const rec_hdr_version_len = 2;
Paul Bakker5121ce52009-01-03 21:22:43 +00003077
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003078 size_t const rec_hdr_ctr_len = 8;
3079# if defined(MBEDTLS_SSL_PROTO_DTLS)
3080 uint32_t rec_epoch;
3081 size_t const rec_hdr_ctr_offset =
3082 rec_hdr_version_offset + rec_hdr_version_len;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003083
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003084# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3085 size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
3086 size_t rec_hdr_cid_len = 0;
3087# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3088# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003089
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003090 size_t rec_hdr_len_offset; /* To be determined */
3091 size_t const rec_hdr_len_len = 2;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003092
3093 /*
3094 * Check minimum lengths for record header.
3095 */
3096
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003097# if defined(MBEDTLS_SSL_PROTO_DTLS)
3098 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003099 rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003100 } else
3101# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003102 {
3103 rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
3104 }
3105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003106 if (len < rec_hdr_len_offset + rec_hdr_len_len) {
3107 MBEDTLS_SSL_DEBUG_MSG(
3108 1,
3109 ("datagram of length %u too small to hold DTLS record header of length %u",
3110 (unsigned)len, (unsigned)(rec_hdr_len_len + rec_hdr_len_len)));
3111 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003112 }
3113
3114 /*
3115 * Parse and validate record content type
3116 */
3117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003118 rec->type = buf[rec_hdr_type_offset];
Hanno Beckere5e7e782019-07-11 12:29:35 +01003119
3120 /* Check record content type */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003121# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckere5e7e782019-07-11 12:29:35 +01003122 rec->cid_len = 0;
3123
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003124 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3125 ssl->conf->cid_len != 0 && rec->type == MBEDTLS_SSL_MSG_CID) {
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003126 /* Shift pointers to account for record header including CID
3127 * struct {
3128 * ContentType special_type = tls12_cid;
3129 * ProtocolVersion version;
3130 * uint16 epoch;
3131 * uint48 sequence_number;
Hanno Becker8e55b0f2019-05-23 17:03:19 +01003132 * opaque cid[cid_length]; // Additional field compared to
3133 * // default DTLS record format
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003134 * uint16 length;
3135 * opaque enc_content[DTLSCiphertext.length];
3136 * } DTLSCiphertext;
3137 */
3138
3139 /* So far, we only support static CID lengths
3140 * fixed in the configuration. */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003141 rec_hdr_cid_len = ssl->conf->cid_len;
3142 rec_hdr_len_offset += rec_hdr_cid_len;
Hanno Beckere538d822019-07-10 14:50:10 +01003143
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003144 if (len < rec_hdr_len_offset + rec_hdr_len_len) {
3145 MBEDTLS_SSL_DEBUG_MSG(
3146 1,
3147 ("datagram of length %u too small to hold DTLS record header including CID, length %u",
3148 (unsigned)len,
3149 (unsigned)(rec_hdr_len_offset + rec_hdr_len_len)));
3150 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckere538d822019-07-10 14:50:10 +01003151 }
Hanno Beckere5e7e782019-07-11 12:29:35 +01003152
Manuel Pégourié-Gonnard7e821b52019-08-02 10:17:15 +02003153 /* configured CID len is guaranteed at most 255, see
3154 * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003155 rec->cid_len = (uint8_t)rec_hdr_cid_len;
3156 memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len);
3157 } else
3158# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Manuel Pégourié-Gonnardedcbe542014-08-11 19:27:24 +02003159 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003160 if (ssl_check_record_type(rec->type)) {
3161 MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u",
3162 (unsigned)rec->type));
3163 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003164 }
Manuel Pégourié-Gonnardedcbe542014-08-11 19:27:24 +02003165 }
3166
Hanno Beckere5e7e782019-07-11 12:29:35 +01003167 /*
3168 * Parse and validate record version
3169 */
3170
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003171 rec->ver[0] = buf[rec_hdr_version_offset + 0];
3172 rec->ver[1] = buf[rec_hdr_version_offset + 1];
3173 mbedtls_ssl_read_version(&major_ver, &minor_ver, ssl->conf->transport,
3174 &rec->ver[0]);
Hanno Beckere5e7e782019-07-11 12:29:35 +01003175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003176 if (major_ver != ssl->major_ver) {
3177 MBEDTLS_SSL_DEBUG_MSG(1, ("major version mismatch"));
3178 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Paul Bakker5121ce52009-01-03 21:22:43 +00003179 }
3180
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003181 if (minor_ver > ssl->conf->max_minor_ver) {
3182 MBEDTLS_SSL_DEBUG_MSG(1, ("minor version mismatch"));
3183 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Paul Bakker5121ce52009-01-03 21:22:43 +00003184 }
3185
Hanno Beckere5e7e782019-07-11 12:29:35 +01003186 /*
3187 * Parse/Copy record sequence number.
3188 */
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003189
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003190# if defined(MBEDTLS_SSL_PROTO_DTLS)
3191 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Beckere5e7e782019-07-11 12:29:35 +01003192 /* Copy explicit record sequence number from input buffer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003193 memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset, rec_hdr_ctr_len);
3194 } else
3195# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Beckere5e7e782019-07-11 12:29:35 +01003196 {
3197 /* Copy implicit record sequence number from SSL context structure. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003198 memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len);
Hanno Beckere5e7e782019-07-11 12:29:35 +01003199 }
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003200
Hanno Beckere5e7e782019-07-11 12:29:35 +01003201 /*
3202 * Parse record length.
3203 */
3204
Hanno Beckere5e7e782019-07-11 12:29:35 +01003205 rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003206 rec->data_len = ((size_t)buf[rec_hdr_len_offset + 0] << 8) |
3207 ((size_t)buf[rec_hdr_len_offset + 1] << 0);
3208 MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset);
Paul Bakker1a1fbba2014-04-30 14:38:05 +02003209
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003210 MBEDTLS_SSL_DEBUG_MSG(3,
3211 ("input record: msgtype = %u, "
3212 "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET,
3213 rec->type, major_ver, minor_ver, rec->data_len));
Hanno Beckere5e7e782019-07-11 12:29:35 +01003214
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003215 rec->buf = buf;
Hanno Beckere5e7e782019-07-11 12:29:35 +01003216 rec->buf_len = rec->data_offset + rec->data_len;
Hanno Beckerca59c2b2019-05-08 12:03:28 +01003217
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003218 if (rec->data_len == 0)
3219 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Paul Bakker5121ce52009-01-03 21:22:43 +00003220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003221 /*
3222 * DTLS-related tests.
3223 * Check epoch before checking length constraint because
3224 * the latter varies with the epoch. E.g., if a ChangeCipherSpec
3225 * message gets duplicated before the corresponding Finished message,
3226 * the second ChangeCipherSpec should be discarded because it belongs
3227 * to an old epoch, but not because its length is shorter than
3228 * the minimum record length for packets using the new record transform.
3229 * Note that these two kinds of failures are handled differently,
3230 * as an unexpected record is silently skipped but an invalid
3231 * record leads to the entire datagram being dropped.
3232 */
3233# if defined(MBEDTLS_SSL_PROTO_DTLS)
3234 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3235 rec_epoch = (rec->ctr[0] << 8) | rec->ctr[1];
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003236
Hanno Becker955a5c92019-07-10 17:12:07 +01003237 /* Check that the datagram is large enough to contain a record
3238 * of the advertised length. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003239 if (len < rec->data_offset + rec->data_len) {
3240 MBEDTLS_SSL_DEBUG_MSG(
3241 1,
3242 ("Datagram of length %u too small to contain record of advertised length %u.",
3243 (unsigned)len, (unsigned)(rec->data_offset + rec->data_len)));
3244 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker955a5c92019-07-10 17:12:07 +01003245 }
Hanno Becker37cfe732019-07-10 17:20:01 +01003246
Hanno Becker37cfe732019-07-10 17:20:01 +01003247 /* Records from other, non-matching epochs are silently discarded.
3248 * (The case of same-port Client reconnects must be considered in
3249 * the caller). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003250 if (rec_epoch != ssl->in_epoch) {
3251 MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: "
3252 "expected %u, received %lu",
3253 ssl->in_epoch, (unsigned long)rec_epoch));
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003254
Hanno Becker552f7472019-07-19 10:59:12 +01003255 /* Records from the next epoch are considered for buffering
3256 * (concretely: early Finished messages). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003257 if (rec_epoch == (unsigned)ssl->in_epoch + 1) {
3258 MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering"));
3259 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003260 }
Hanno Becker5f066e72018-08-16 14:56:31 +01003261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003262 return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003263 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003264# if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Hanno Becker37cfe732019-07-10 17:20:01 +01003265 /* For records from the correct epoch, check whether their
3266 * sequence number has been seen before. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003267 else if (mbedtls_ssl_dtls_record_replay_check(
3268 (mbedtls_ssl_context *)ssl, &rec->ctr[0]) != 0) {
3269 MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record"));
3270 return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003271 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003272# endif
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003273 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003274# endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01003275
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003276 return 0;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003277}
Paul Bakker5121ce52009-01-03 21:22:43 +00003278
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003279# if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
3280 defined(MBEDTLS_SSL_SRV_C)
3281static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
Hanno Becker2fddd372019-07-10 14:37:41 +01003282{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003283 unsigned int rec_epoch = (ssl->in_ctr[0] << 8) | ssl->in_ctr[1];
Hanno Becker2fddd372019-07-10 14:37:41 +01003284
3285 /*
3286 * Check for an epoch 0 ClientHello. We can't use in_msg here to
3287 * access the first byte of record content (handshake type), as we
3288 * have an active transform (possibly iv_len != 0), so use the
3289 * fact that the record header len is 13 instead.
3290 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003291 if (rec_epoch == 0 && ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
Hanno Becker2fddd372019-07-10 14:37:41 +01003292 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003293 ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && ssl->in_left > 13 &&
3294 ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) {
3295 MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect "
3296 "from the same port"));
3297 return ssl_handle_possible_reconnect(ssl);
Paul Bakker5121ce52009-01-03 21:22:43 +00003298 }
3299
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003300 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00003301}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003302# endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
Paul Bakker5121ce52009-01-03 21:22:43 +00003303
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003304/*
Manuel Pégourié-Gonnardc40b6852020-01-03 12:18:49 +01003305 * If applicable, decrypt record content
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003306 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003307static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
3308 mbedtls_record *rec)
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003309{
3310 int ret, done = 0;
Manuel Pégourié-Gonnardb2f3be82014-07-10 17:54:52 +02003311
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003312 MBEDTLS_SSL_DEBUG_BUF(4, "input record from network", rec->buf,
3313 rec->buf_len);
Paul Bakker5121ce52009-01-03 21:22:43 +00003314
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003315 if (!done && ssl->transform_in != NULL) {
Hanno Becker58ef0bf2019-07-12 09:35:58 +01003316 unsigned char const old_msg_type = rec->type;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003317
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003318 if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, rec)) != 0) {
3319 MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret);
Hanno Becker8367ccc2019-05-14 11:30:10 +01003320
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003321# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3322 if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
3323 ssl->conf->ignore_unexpected_cid ==
3324 MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
3325 MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID"));
Hanno Becker16ded982019-05-08 13:02:55 +01003326 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
Hanno Becker8367ccc2019-05-14 11:30:10 +01003327 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003328# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker16ded982019-05-08 13:02:55 +01003329
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003330 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00003331 }
3332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003333 if (old_msg_type != rec->type) {
3334 MBEDTLS_SSL_DEBUG_MSG(4,
3335 ("record type after decrypt (before %d): %d",
3336 old_msg_type, rec->type));
Hanno Becker6430faf2019-05-08 11:57:13 +01003337 }
3338
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003339 MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt",
3340 rec->buf + rec->data_offset, rec->data_len);
Hanno Becker1c0c37f2018-08-07 14:29:29 +01003341
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003342# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker6430faf2019-05-08 11:57:13 +01003343 /* We have already checked the record content type
3344 * in ssl_parse_record_header(), failing or silently
3345 * dropping the record in the case of an unknown type.
3346 *
3347 * Since with the use of CIDs, the record content type
3348 * might change during decryption, re-check the record
3349 * content type, but treat a failure as fatal this time. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003350 if (ssl_check_record_type(rec->type)) {
3351 MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type"));
3352 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker6430faf2019-05-08 11:57:13 +01003353 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003354# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker6430faf2019-05-08 11:57:13 +01003355
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003356 if (rec->data_len == 0) {
3357# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
3358 if (ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
3359 rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
3360 /* TLS v1.2 explicitly disallows zero-length messages which are
3361 * not application data */
3362 MBEDTLS_SSL_DEBUG_MSG(1,
3363 ("invalid zero-length message type: %d",
3364 ssl->in_msgtype));
3365 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003366 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003367# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003368
3369 ssl->nb_zero++;
3370
3371 /*
3372 * Three or more empty messages may be a DoS attack
3373 * (excessive CPU consumption).
3374 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003375 if (ssl->nb_zero > 3) {
3376 MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty "
3377 "messages, possible DoS attack"));
Hanno Becker6e7700d2019-05-08 10:38:32 +01003378 /* Treat the records as if they were not properly authenticated,
3379 * thereby failing the connection if we see more than allowed
3380 * by the configured bad MAC threshold. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003381 return MBEDTLS_ERR_SSL_INVALID_MAC;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003382 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003383 } else
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003384 ssl->nb_zero = 0;
3385
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003386# if defined(MBEDTLS_SSL_PROTO_DTLS)
3387 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003388 ; /* in_ctr read from peer, not maintained internally */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003389 } else
3390# endif
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003391 {
3392 unsigned i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003393 for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--)
3394 if (++ssl->in_ctr[i - 1] != 0)
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003395 break;
3396
3397 /* The loop goes to its end iff the counter is wrapping */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003398 if (i == mbedtls_ssl_ep_len(ssl)) {
3399 MBEDTLS_SSL_DEBUG_MSG(1,
3400 ("incoming message counter would wrap"));
3401 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
Hanno Becker2e24c3b2017-12-27 21:28:58 +00003402 }
3403 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003404 }
3405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003406# if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3407 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3408 mbedtls_ssl_dtls_replay_update(ssl);
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02003409 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003410# endif
Manuel Pégourié-Gonnardb47368a2014-09-24 13:29:58 +02003411
Hanno Beckerd96e10b2019-07-09 17:30:02 +01003412 /* Check actual (decrypted) record content length against
3413 * configured maximum. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003414 if (ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN) {
3415 MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length"));
3416 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckerd96e10b2019-07-09 17:30:02 +01003417 }
3418
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003419 return 0;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003420}
3421
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02003422/*
3423 * Read a record.
3424 *
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02003425 * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
3426 * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
3427 *
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02003428 */
Hanno Becker1097b342018-08-15 14:09:41 +01003429
3430/* Helper functions for mbedtls_ssl_read_record(). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003431static int ssl_consume_current_message(mbedtls_ssl_context *ssl);
3432static int ssl_get_next_record(mbedtls_ssl_context *ssl);
3433static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl);
Hanno Becker4162b112018-08-15 14:05:04 +01003434
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003435int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl, unsigned update_hs_digest)
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003436{
Janos Follath865b3eb2019-12-16 11:46:15 +00003437 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003438
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003439 MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record"));
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003440
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003441 if (ssl->keep_current_message == 0) {
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003442 do {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003443 ret = ssl_consume_current_message(ssl);
3444 if (ret != 0)
3445 return ret;
Simon Butcher99000142016-10-13 17:21:01 +01003446
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003447 if (ssl_record_is_in_progress(ssl) == 0) {
3448# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker40f50842018-08-15 14:48:01 +01003449 int have_buffered = 0;
Hanno Beckere74d5562018-08-15 14:26:08 +01003450
Hanno Becker40f50842018-08-15 14:48:01 +01003451 /* We only check for buffered messages if the
3452 * current datagram is fully consumed. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003453 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3454 ssl_next_record_is_in_datagram(ssl) == 0) {
3455 if (ssl_load_buffered_message(ssl) == 0)
Hanno Becker40f50842018-08-15 14:48:01 +01003456 have_buffered = 1;
3457 }
3458
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003459 if (have_buffered == 0)
3460# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker40f50842018-08-15 14:48:01 +01003461 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003462 ret = ssl_get_next_record(ssl);
3463 if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING)
Hanno Becker40f50842018-08-15 14:48:01 +01003464 continue;
3465
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003466 if (ret != 0) {
3467 MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret);
3468 return ret;
Hanno Becker40f50842018-08-15 14:48:01 +01003469 }
Hanno Beckere74d5562018-08-15 14:26:08 +01003470 }
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003471 }
3472
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003473 ret = mbedtls_ssl_handle_message_type(ssl);
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003474
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003475# if defined(MBEDTLS_SSL_PROTO_DTLS)
3476 if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
Hanno Becker40f50842018-08-15 14:48:01 +01003477 /* Buffer future message */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003478 ret = ssl_buffer_message(ssl);
3479 if (ret != 0)
3480 return ret;
Hanno Becker40f50842018-08-15 14:48:01 +01003481
3482 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3483 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003484# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker40f50842018-08-15 14:48:01 +01003485
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003486 } while (MBEDTLS_ERR_SSL_NON_FATAL == ret ||
3487 MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret);
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003488
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003489 if (0 != ret) {
3490 MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret);
3491 return ret;
Simon Butcher99000142016-10-13 17:21:01 +01003492 }
3493
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003494 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
3495 update_hs_digest == 1) {
3496 mbedtls_ssl_update_handshake_status(ssl);
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003497 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003498 } else {
3499 MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message"));
Hanno Beckeraf0665d2017-05-24 09:16:26 +01003500 ssl->keep_current_message = 0;
Simon Butcher99000142016-10-13 17:21:01 +01003501 }
3502
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003503 MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record"));
Simon Butcher99000142016-10-13 17:21:01 +01003504
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003505 return 0;
Simon Butcher99000142016-10-13 17:21:01 +01003506}
3507
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003508# if defined(MBEDTLS_SSL_PROTO_DTLS)
3509static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl)
Simon Butcher99000142016-10-13 17:21:01 +01003510{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003511 if (ssl->in_left > ssl->next_record_offset)
3512 return 1;
Simon Butcher99000142016-10-13 17:21:01 +01003513
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003514 return 0;
Hanno Becker40f50842018-08-15 14:48:01 +01003515}
3516
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003517static int ssl_load_buffered_message(mbedtls_ssl_context *ssl)
Hanno Becker40f50842018-08-15 14:48:01 +01003518{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003519 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
3520 mbedtls_ssl_hs_buffer *hs_buf;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003521 int ret = 0;
3522
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003523 if (hs == NULL)
3524 return -1;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003525
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003526 MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_messsage"));
Hanno Beckere00ae372018-08-20 09:39:42 +01003527
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003528 if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
3529 ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003530 /* Check if we have seen a ChangeCipherSpec before.
3531 * If yes, synthesize a CCS record. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003532 if (!hs->buffering.seen_ccs) {
3533 MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight"));
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003534 ret = -1;
Hanno Becker0d4b3762018-08-20 09:36:59 +01003535 goto exit;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003536 }
3537
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003538 MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message"));
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003539 ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
3540 ssl->in_msglen = 1;
3541 ssl->in_msg[0] = 1;
3542
3543 /* As long as they are equal, the exact value doesn't matter. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003544 ssl->in_left = 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003545 ssl->next_record_offset = 0;
3546
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01003547 hs->buffering.seen_ccs = 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003548 goto exit;
3549 }
Hanno Becker37f95322018-08-16 13:55:32 +01003550
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003551# if defined(MBEDTLS_DEBUG_C)
Hanno Becker37f95322018-08-16 13:55:32 +01003552 /* Debug only */
3553 {
3554 unsigned offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003555 for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
Hanno Becker37f95322018-08-16 13:55:32 +01003556 hs_buf = &hs->buffering.hs[offset];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003557 if (hs_buf->is_valid == 1) {
3558 MBEDTLS_SSL_DEBUG_MSG(
3559 2, ("Future message with sequence number %u %s buffered.",
3560 hs->in_msg_seq + offset,
3561 hs_buf->is_complete ? "fully" : "partially"));
Hanno Becker37f95322018-08-16 13:55:32 +01003562 }
3563 }
3564 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003565# endif /* MBEDTLS_DEBUG_C */
Hanno Becker37f95322018-08-16 13:55:32 +01003566
3567 /* Check if we have buffered and/or fully reassembled the
3568 * next handshake message. */
3569 hs_buf = &hs->buffering.hs[0];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003570 if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) {
Hanno Becker37f95322018-08-16 13:55:32 +01003571 /* Synthesize a record containing the buffered HS message. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003572 size_t msg_len = (hs_buf->data[1] << 16) | (hs_buf->data[2] << 8) |
3573 hs_buf->data[3];
Hanno Becker37f95322018-08-16 13:55:32 +01003574
3575 /* Double-check that we haven't accidentally buffered
3576 * a message that doesn't fit into the input buffer. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003577 if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
3578 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3579 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker37f95322018-08-16 13:55:32 +01003580 }
3581
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003582 MBEDTLS_SSL_DEBUG_MSG(
3583 2, ("Next handshake message has been buffered - load"));
3584 MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)",
3585 hs_buf->data, msg_len + 12);
Hanno Becker37f95322018-08-16 13:55:32 +01003586
3587 ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003588 ssl->in_hslen = msg_len + 12;
3589 ssl->in_msglen = msg_len + 12;
3590 memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen);
Hanno Becker37f95322018-08-16 13:55:32 +01003591
3592 ret = 0;
3593 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003594 } else {
3595 MBEDTLS_SSL_DEBUG_MSG(
3596 2, ("Next handshake message %u not or only partially bufffered",
3597 hs->in_msg_seq));
Hanno Becker37f95322018-08-16 13:55:32 +01003598 }
3599
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003600 ret = -1;
3601
3602exit:
3603
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003604 MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message"));
3605 return ret;
Hanno Becker40f50842018-08-15 14:48:01 +01003606}
3607
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003608static int ssl_buffer_make_space(mbedtls_ssl_context *ssl, size_t desired)
Hanno Beckera02b0b42018-08-21 17:20:27 +01003609{
3610 int offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003611 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
3612 MBEDTLS_SSL_DEBUG_MSG(
3613 2, ("Attempt to free buffered messages to have %u bytes available",
3614 (unsigned)desired));
Hanno Beckera02b0b42018-08-21 17:20:27 +01003615
Hanno Becker01315ea2018-08-21 17:22:17 +01003616 /* Get rid of future records epoch first, if such exist. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003617 ssl_free_buffered_record(ssl);
Hanno Becker01315ea2018-08-21 17:22:17 +01003618
3619 /* Check if we have enough space available now. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003620 if (desired <=
3621 (MBEDTLS_SSL_DTLS_MAX_BUFFERING - hs->buffering.total_bytes_buffered)) {
3622 MBEDTLS_SSL_DEBUG_MSG(
3623 2, ("Enough space available after freeing future epoch record"));
3624 return 0;
Hanno Becker01315ea2018-08-21 17:22:17 +01003625 }
Hanno Beckera02b0b42018-08-21 17:20:27 +01003626
Hanno Becker4f432ad2018-08-28 10:02:32 +01003627 /* We don't have enough space to buffer the next expected handshake
3628 * message. Remove buffers used for future messages to gain space,
3629 * starting with the most distant one. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003630 for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1; offset >= 0; offset--) {
3631 MBEDTLS_SSL_DEBUG_MSG(
3632 2,
3633 ("Free buffering slot %d to make space for reassembly of next handshake message",
3634 offset));
Hanno Beckera02b0b42018-08-21 17:20:27 +01003635
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003636 ssl_buffering_free_slot(ssl, (uint8_t)offset);
Hanno Beckera02b0b42018-08-21 17:20:27 +01003637
3638 /* Check if we have enough space available now. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003639 if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
3640 hs->buffering.total_bytes_buffered)) {
3641 MBEDTLS_SSL_DEBUG_MSG(
3642 2,
3643 ("Enough space available after freeing buffered HS messages"));
3644 return 0;
Hanno Beckera02b0b42018-08-21 17:20:27 +01003645 }
3646 }
3647
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003648 return -1;
Hanno Beckera02b0b42018-08-21 17:20:27 +01003649}
3650
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003651static int ssl_buffer_message(mbedtls_ssl_context *ssl)
Hanno Becker40f50842018-08-15 14:48:01 +01003652{
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003653 int ret = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003654 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003655
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003656 if (hs == NULL)
3657 return 0;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003658
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003659 MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message"));
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003660
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003661 switch (ssl->in_msgtype) {
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003662 case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003663 MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message"));
Hanno Beckere678eaa2018-08-21 14:57:46 +01003664
Hanno Beckerd7f8ae22018-08-16 09:45:56 +01003665 hs->buffering.seen_ccs = 1;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003666 break;
3667
3668 case MBEDTLS_SSL_MSG_HANDSHAKE:
Hanno Becker37f95322018-08-16 13:55:32 +01003669 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003670 unsigned recv_msg_seq_offset;
3671 unsigned recv_msg_seq = (ssl->in_msg[4] << 8) | ssl->in_msg[5];
3672 mbedtls_ssl_hs_buffer *hs_buf;
3673 size_t msg_len = ssl->in_hslen - 12;
Hanno Becker37f95322018-08-16 13:55:32 +01003674
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003675 /* We should never receive an old handshake
3676 * message - double-check nonetheless. */
3677 if (recv_msg_seq < ssl->handshake->in_msg_seq) {
3678 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3679 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3680 }
Hanno Becker37f95322018-08-16 13:55:32 +01003681
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003682 recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
3683 if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
3684 /* Silently ignore -- message too far in the future */
3685 MBEDTLS_SSL_DEBUG_MSG(
3686 2, ("Ignore future HS message with sequence number %u, "
3687 "buffering window %u - %u",
3688 recv_msg_seq, ssl->handshake->in_msg_seq,
3689 ssl->handshake->in_msg_seq +
3690 MBEDTLS_SSL_MAX_BUFFERED_HS - 1));
Hanno Becker37f95322018-08-16 13:55:32 +01003691
Hanno Becker37f95322018-08-16 13:55:32 +01003692 goto exit;
3693 }
3694
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003695 MBEDTLS_SSL_DEBUG_MSG(
3696 2,
3697 ("Buffering HS message with sequence number %u, offset %u ",
3698 recv_msg_seq, recv_msg_seq_offset));
Hanno Beckere0b150f2018-08-21 15:51:03 +01003699
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003700 hs_buf = &hs->buffering.hs[recv_msg_seq_offset];
Hanno Beckere0b150f2018-08-21 15:51:03 +01003701
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003702 /* Check if the buffering for this seq nr has already commenced.
Hanno Becker37f95322018-08-16 13:55:32 +01003703 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003704 if (!hs_buf->is_valid) {
3705 size_t reassembly_buf_sz;
Hanno Becker37f95322018-08-16 13:55:32 +01003706
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003707 hs_buf->is_fragmented =
3708 (ssl_hs_is_proper_fragment(ssl) == 1);
Hanno Becker37f95322018-08-16 13:55:32 +01003709
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003710 /* We copy the message back into the input buffer
3711 * after reassembly, so check that it's not too large.
3712 * This is an implementation-specific limitation
3713 * and not one from the standard, hence it is not
3714 * checked in ssl_check_hs_header(). */
3715 if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
3716 /* Ignore message */
3717 goto exit;
3718 }
Hanno Becker37f95322018-08-16 13:55:32 +01003719
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003720 /* Check if we have enough space to buffer the message. */
3721 if (hs->buffering.total_bytes_buffered >
3722 MBEDTLS_SSL_DTLS_MAX_BUFFERING) {
3723 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3724 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3725 }
3726
3727 reassembly_buf_sz = ssl_get_reassembly_buffer_size(
3728 msg_len, hs_buf->is_fragmented);
3729
3730 if (reassembly_buf_sz >
3731 (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
3732 hs->buffering.total_bytes_buffered)) {
3733 if (recv_msg_seq_offset > 0) {
3734 /* If we can't buffer a future message because
3735 * of space limitations -- ignore. */
3736 MBEDTLS_SSL_DEBUG_MSG(
3737 2,
3738 ("Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
3739 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
3740 " (already %" MBEDTLS_PRINTF_SIZET
3741 " bytes buffered) -- ignore\n",
3742 msg_len,
3743 (size_t)MBEDTLS_SSL_DTLS_MAX_BUFFERING,
3744 hs->buffering.total_bytes_buffered));
3745 goto exit;
3746 } else {
3747 MBEDTLS_SSL_DEBUG_MSG(
3748 2,
3749 ("Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
3750 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
3751 " (already %" MBEDTLS_PRINTF_SIZET
3752 " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
3753 msg_len,
3754 (size_t)MBEDTLS_SSL_DTLS_MAX_BUFFERING,
3755 hs->buffering.total_bytes_buffered));
3756 }
3757
3758 if (ssl_buffer_make_space(ssl, reassembly_buf_sz) !=
3759 0) {
3760 MBEDTLS_SSL_DEBUG_MSG(
3761 2,
3762 ("Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET
3763 " (%" MBEDTLS_PRINTF_SIZET
3764 " with bitmap) would exceed"
3765 " the compile-time limit %" MBEDTLS_PRINTF_SIZET
3766 " (already %" MBEDTLS_PRINTF_SIZET
3767 " bytes buffered) -- fail\n",
3768 msg_len, reassembly_buf_sz,
3769 (size_t)MBEDTLS_SSL_DTLS_MAX_BUFFERING,
3770 hs->buffering.total_bytes_buffered));
3771 ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
3772 goto exit;
3773 }
3774 }
3775
3776 MBEDTLS_SSL_DEBUG_MSG(
3777 2,
3778 ("initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET,
3779 msg_len));
3780
3781 hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz);
3782 if (hs_buf->data == NULL) {
3783 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
3784 goto exit;
3785 }
3786 hs_buf->data_len = reassembly_buf_sz;
3787
3788 /* Prepare final header: copy msg_type, length and
3789 * message_seq, then add standardised fragment_offset and
3790 * fragment_length */
3791 memcpy(hs_buf->data, ssl->in_msg, 6);
3792 memset(hs_buf->data + 6, 0, 3);
3793 memcpy(hs_buf->data + 9, hs_buf->data + 1, 3);
3794
3795 hs_buf->is_valid = 1;
3796
3797 hs->buffering.total_bytes_buffered += reassembly_buf_sz;
3798 } else {
3799 /* Make sure msg_type and length are consistent */
3800 if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) {
3801 MBEDTLS_SSL_DEBUG_MSG(
3802 1, ("Fragment header mismatch - ignore"));
3803 /* Ignore */
3804 goto exit;
3805 }
Hanno Becker37f95322018-08-16 13:55:32 +01003806 }
3807
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003808 if (!hs_buf->is_complete) {
3809 size_t frag_len, frag_off;
3810 unsigned char *const msg = hs_buf->data + 12;
3811
3812 /*
3813 * Check and copy current fragment
3814 */
3815
3816 /* Validation of header fields already done in
3817 * mbedtls_ssl_prepare_handshake_record(). */
3818 frag_off = ssl_get_hs_frag_off(ssl);
3819 frag_len = ssl_get_hs_frag_len(ssl);
3820
3821 MBEDTLS_SSL_DEBUG_MSG(
3822 2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
3823 ", length = %" MBEDTLS_PRINTF_SIZET,
3824 frag_off, frag_len));
3825 memcpy(msg + frag_off, ssl->in_msg + 12, frag_len);
3826
3827 if (hs_buf->is_fragmented) {
3828 unsigned char *const bitmask = msg + msg_len;
3829 ssl_bitmask_set(bitmask, frag_off, frag_len);
3830 hs_buf->is_complete =
3831 (ssl_bitmask_check(bitmask, msg_len) == 0);
3832 } else {
3833 hs_buf->is_complete = 1;
3834 }
3835
3836 MBEDTLS_SSL_DEBUG_MSG(
3837 2, ("message %scomplete",
3838 hs_buf->is_complete ? "" : "not yet "));
3839 }
3840
3841 break;
Hanno Becker37f95322018-08-16 13:55:32 +01003842 }
3843
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003844 default:
Hanno Becker360bef32018-08-28 10:04:33 +01003845 /* We don't buffer other types of messages. */
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01003846 break;
3847 }
3848
3849exit:
3850
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003851 MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message"));
3852 return ret;
Hanno Becker40f50842018-08-15 14:48:01 +01003853}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003854# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker40f50842018-08-15 14:48:01 +01003855
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003856static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003857{
Hanno Becker4a810fb2017-05-24 16:27:30 +01003858 /*
Hanno Becker4a810fb2017-05-24 16:27:30 +01003859 * Consume last content-layer message and potentially
3860 * update in_msglen which keeps track of the contents'
3861 * consumption state.
3862 *
3863 * (1) Handshake messages:
3864 * Remove last handshake message, move content
3865 * and adapt in_msglen.
3866 *
3867 * (2) Alert messages:
3868 * Consume whole record content, in_msglen = 0.
3869 *
Hanno Becker4a810fb2017-05-24 16:27:30 +01003870 * (3) Change cipher spec:
3871 * Consume whole record content, in_msglen = 0.
3872 *
3873 * (4) Application data:
3874 * Don't do anything - the record layer provides
3875 * the application data as a stream transport
3876 * and consumes through mbedtls_ssl_read only.
3877 *
3878 */
3879
3880 /* Case (1): Handshake messages */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003881 if (ssl->in_hslen != 0) {
Hanno Beckerbb9dd0c2017-06-08 11:55:34 +01003882 /* Hard assertion to be sure that no application data
3883 * is in flight, as corrupting ssl->in_msglen during
3884 * ssl->in_offt != NULL is fatal. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003885 if (ssl->in_offt != NULL) {
3886 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3887 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Beckerbb9dd0c2017-06-08 11:55:34 +01003888 }
3889
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003890 /*
3891 * Get next Handshake message in the current record
3892 */
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003893
Hanno Becker4a810fb2017-05-24 16:27:30 +01003894 /* Notes:
Hanno Beckere72489d2017-10-23 13:23:50 +01003895 * (1) in_hslen is not necessarily the size of the
Hanno Becker4a810fb2017-05-24 16:27:30 +01003896 * current handshake content: If DTLS handshake
3897 * fragmentation is used, that's the fragment
3898 * size instead. Using the total handshake message
Hanno Beckere72489d2017-10-23 13:23:50 +01003899 * size here is faulty and should be changed at
3900 * some point.
Hanno Becker4a810fb2017-05-24 16:27:30 +01003901 * (2) While it doesn't seem to cause problems, one
3902 * has to be very careful not to assume that in_hslen
3903 * is always <= in_msglen in a sensible communication.
3904 * Again, it's wrong for DTLS handshake fragmentation.
3905 * The following check is therefore mandatory, and
3906 * should not be treated as a silently corrected assertion.
Hanno Beckerbb9dd0c2017-06-08 11:55:34 +01003907 * Additionally, ssl->in_hslen might be arbitrarily out of
3908 * bounds after handling a DTLS message with an unexpected
3909 * sequence number, see mbedtls_ssl_prepare_handshake_record.
Hanno Becker4a810fb2017-05-24 16:27:30 +01003910 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003911 if (ssl->in_hslen < ssl->in_msglen) {
Hanno Becker4a810fb2017-05-24 16:27:30 +01003912 ssl->in_msglen -= ssl->in_hslen;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003913 memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen, ssl->in_msglen);
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02003914
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003915 MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record", ssl->in_msg,
3916 ssl->in_msglen);
3917 } else {
Hanno Becker4a810fb2017-05-24 16:27:30 +01003918 ssl->in_msglen = 0;
3919 }
Manuel Pégourié-Gonnard4a175362014-09-09 17:45:31 +02003920
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003921 ssl->in_hslen = 0;
Hanno Becker4a810fb2017-05-24 16:27:30 +01003922 }
3923 /* Case (4): Application data */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003924 else if (ssl->in_offt != NULL) {
3925 return 0;
Hanno Becker4a810fb2017-05-24 16:27:30 +01003926 }
3927 /* Everything else (CCS & Alerts) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003928 else {
Hanno Becker4a810fb2017-05-24 16:27:30 +01003929 ssl->in_msglen = 0;
3930 }
3931
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003932 return 0;
Hanno Becker1097b342018-08-15 14:09:41 +01003933}
Hanno Becker4a810fb2017-05-24 16:27:30 +01003934
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003935static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl)
Hanno Beckere74d5562018-08-15 14:26:08 +01003936{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003937 if (ssl->in_msglen > 0)
3938 return 1;
Hanno Beckere74d5562018-08-15 14:26:08 +01003939
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003940 return 0;
Hanno Beckere74d5562018-08-15 14:26:08 +01003941}
3942
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003943# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker5f066e72018-08-16 14:56:31 +01003944
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003945static void ssl_free_buffered_record(mbedtls_ssl_context *ssl)
Hanno Becker5f066e72018-08-16 14:56:31 +01003946{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003947 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
3948 if (hs == NULL)
Hanno Becker5f066e72018-08-16 14:56:31 +01003949 return;
3950
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003951 if (hs->buffering.future_record.data != NULL) {
3952 hs->buffering.total_bytes_buffered -= hs->buffering.future_record.len;
Hanno Becker01315ea2018-08-21 17:22:17 +01003953
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003954 mbedtls_free(hs->buffering.future_record.data);
Hanno Becker01315ea2018-08-21 17:22:17 +01003955 hs->buffering.future_record.data = NULL;
3956 }
Hanno Becker5f066e72018-08-16 14:56:31 +01003957}
3958
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003959static int ssl_load_buffered_record(mbedtls_ssl_context *ssl)
Hanno Becker5f066e72018-08-16 14:56:31 +01003960{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003961 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
3962 unsigned char *rec;
Hanno Becker5f066e72018-08-16 14:56:31 +01003963 size_t rec_len;
3964 unsigned rec_epoch;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003965# if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
Darryl Greenb33cc762019-11-28 14:29:44 +00003966 size_t in_buf_len = ssl->in_buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003967# else
Darryl Greenb33cc762019-11-28 14:29:44 +00003968 size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003969# endif
3970 if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM)
3971 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01003972
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003973 if (hs == NULL)
3974 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01003975
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003976 rec = hs->buffering.future_record.data;
3977 rec_len = hs->buffering.future_record.len;
Hanno Becker5f066e72018-08-16 14:56:31 +01003978 rec_epoch = hs->buffering.future_record.epoch;
3979
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003980 if (rec == NULL)
3981 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01003982
Hanno Becker4cb782d2018-08-20 11:19:05 +01003983 /* Only consider loading future records if the
3984 * input buffer is empty. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003985 if (ssl_next_record_is_in_datagram(ssl) == 1)
3986 return 0;
Hanno Becker4cb782d2018-08-20 11:19:05 +01003987
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003988 MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record"));
Hanno Becker5f066e72018-08-16 14:56:31 +01003989
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003990 if (rec_epoch != ssl->in_epoch) {
3991 MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch."));
Hanno Becker5f066e72018-08-16 14:56:31 +01003992 goto exit;
3993 }
3994
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003995 MBEDTLS_SSL_DEBUG_MSG(2,
3996 ("Found buffered record from current epoch - load"));
Hanno Becker5f066e72018-08-16 14:56:31 +01003997
3998 /* Double-check that the record is not too large */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02003999 if (rec_len > in_buf_len - (size_t)(ssl->in_hdr - ssl->in_buf)) {
4000 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4001 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Hanno Becker5f066e72018-08-16 14:56:31 +01004002 }
4003
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004004 memcpy(ssl->in_hdr, rec, rec_len);
Hanno Becker5f066e72018-08-16 14:56:31 +01004005 ssl->in_left = rec_len;
4006 ssl->next_record_offset = 0;
4007
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004008 ssl_free_buffered_record(ssl);
Hanno Becker5f066e72018-08-16 14:56:31 +01004009
4010exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004011 MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record"));
4012 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004013}
4014
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004015static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
4016 mbedtls_record const *rec)
Hanno Becker5f066e72018-08-16 14:56:31 +01004017{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004018 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
Hanno Becker5f066e72018-08-16 14:56:31 +01004019
4020 /* Don't buffer future records outside handshakes. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004021 if (hs == NULL)
4022 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004023
4024 /* Only buffer handshake records (we are only interested
4025 * in Finished messages). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004026 if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE)
4027 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004028
4029 /* Don't buffer more than one future epoch record. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004030 if (hs->buffering.future_record.data != NULL)
4031 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004032
Hanno Becker01315ea2018-08-21 17:22:17 +01004033 /* Don't buffer record if there's not enough buffering space remaining. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004034 if (rec->buf_len >
4035 (MBEDTLS_SSL_DTLS_MAX_BUFFERING - hs->buffering.total_bytes_buffered)) {
4036 MBEDTLS_SSL_DEBUG_MSG(
4037 2,
4038 ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
4039 " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
4040 " (already %" MBEDTLS_PRINTF_SIZET " bytes buffered) -- ignore\n",
4041 rec->buf_len, (size_t)MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4042 hs->buffering.total_bytes_buffered));
4043 return 0;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004044 }
4045
Hanno Becker5f066e72018-08-16 14:56:31 +01004046 /* Buffer record */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004047 MBEDTLS_SSL_DEBUG_MSG(2,
4048 ("Buffer record from epoch %u", ssl->in_epoch + 1U));
4049 MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len);
Hanno Becker5f066e72018-08-16 14:56:31 +01004050
4051 /* ssl_parse_record_header() only considers records
4052 * of the next epoch as candidates for buffering. */
4053 hs->buffering.future_record.epoch = ssl->in_epoch + 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004054 hs->buffering.future_record.len = rec->buf_len;
Hanno Becker5f066e72018-08-16 14:56:31 +01004055
4056 hs->buffering.future_record.data =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004057 mbedtls_calloc(1, hs->buffering.future_record.len);
4058 if (hs->buffering.future_record.data == NULL) {
Hanno Becker5f066e72018-08-16 14:56:31 +01004059 /* If we run out of RAM trying to buffer a
4060 * record from the next epoch, just ignore. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004061 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004062 }
4063
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004064 memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len);
Hanno Becker5f066e72018-08-16 14:56:31 +01004065
Hanno Becker519f15d2019-07-11 12:43:20 +01004066 hs->buffering.total_bytes_buffered += rec->buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004067 return 0;
Hanno Becker5f066e72018-08-16 14:56:31 +01004068}
4069
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004070# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker5f066e72018-08-16 14:56:31 +01004071
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004072static int ssl_get_next_record(mbedtls_ssl_context *ssl)
Hanno Becker1097b342018-08-15 14:09:41 +01004073{
Janos Follath865b3eb2019-12-16 11:46:15 +00004074 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckere5e7e782019-07-11 12:29:35 +01004075 mbedtls_record rec;
Hanno Becker1097b342018-08-15 14:09:41 +01004076
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004077# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker5f066e72018-08-16 14:56:31 +01004078 /* We might have buffered a future record; if so,
4079 * and if the epoch matches now, load it.
4080 * On success, this call will set ssl->in_left to
4081 * the length of the buffered record, so that
4082 * the calls to ssl_fetch_input() below will
4083 * essentially be no-ops. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004084 ret = ssl_load_buffered_record(ssl);
4085 if (ret != 0)
4086 return ret;
4087# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker4a810fb2017-05-24 16:27:30 +01004088
Hanno Beckerca59c2b2019-05-08 12:03:28 +01004089 /* Ensure that we have enough space available for the default form
4090 * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
4091 * with no space for CIDs counted in). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004092 ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl));
4093 if (ret != 0) {
4094 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
4095 return ret;
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004096 }
4097
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004098 ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec);
4099 if (ret != 0) {
4100# if defined(MBEDTLS_SSL_PROTO_DTLS)
4101 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4102 if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
4103 ret = ssl_buffer_future_record(ssl, &rec);
4104 if (ret != 0)
4105 return ret;
Hanno Becker5f066e72018-08-16 14:56:31 +01004106
4107 /* Fall through to handling of unexpected records */
4108 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
4109 }
4110
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004111 if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) {
4112# if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \
4113 defined(MBEDTLS_SSL_SRV_C)
Hanno Beckerd8bf8ce2019-07-12 09:23:47 +01004114 /* Reset in pointers to default state for TLS/DTLS records,
4115 * assuming no CID and no offset between record content and
4116 * record plaintext. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004117 mbedtls_ssl_update_in_pointers(ssl);
Hanno Beckerd8bf8ce2019-07-12 09:23:47 +01004118
Hanno Becker7ae20e02019-07-12 08:33:49 +01004119 /* Setup internal message pointers from record structure. */
4120 ssl->in_msgtype = rec.type;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004121# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker7ae20e02019-07-12 08:33:49 +01004122 ssl->in_len = ssl->in_cid + rec.cid_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004123# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4124 ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
Hanno Becker7ae20e02019-07-12 08:33:49 +01004125 ssl->in_msglen = rec.data_len;
4126
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004127 ret = ssl_check_client_reconnect(ssl);
4128 MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret);
4129 if (ret != 0)
4130 return ret;
4131# endif
Hanno Becker2fddd372019-07-10 14:37:41 +01004132
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004133 /* Skip unexpected record (but not whole datagram) */
Hanno Becker4acada32019-07-11 12:48:53 +01004134 ssl->next_record_offset = rec.buf_len;
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004135
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004136 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record "
4137 "(header)"));
4138 } else {
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004139 /* Skip invalid record and the rest of the datagram */
4140 ssl->next_record_offset = 0;
4141 ssl->in_left = 0;
4142
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004143 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record "
4144 "(header)"));
Manuel Pégourié-Gonnarde2e25e72015-12-03 16:13:17 +01004145 }
4146
4147 /* Get next record */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004148 return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4149 } else
4150# endif
Hanno Becker2fddd372019-07-10 14:37:41 +01004151 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004152 return ret;
Hanno Becker2fddd372019-07-10 14:37:41 +01004153 }
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004154 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004155
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004156# if defined(MBEDTLS_SSL_PROTO_DTLS)
4157 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Beckera8814792019-07-10 15:01:45 +01004158 /* Remember offset of next record within datagram. */
Hanno Beckerf50da502019-07-11 12:50:10 +01004159 ssl->next_record_offset = rec.buf_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004160 if (ssl->next_record_offset < ssl->in_left) {
4161 MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram"));
Hanno Beckere65ce782017-05-22 14:47:48 +01004162 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004163 } else
4164# endif
Hanno Beckera8814792019-07-10 15:01:45 +01004165 {
Hanno Becker955a5c92019-07-10 17:12:07 +01004166 /*
4167 * Fetch record contents from underlying transport.
4168 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004169 ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len);
4170 if (ret != 0) {
4171 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
4172 return ret;
Hanno Beckera8814792019-07-10 15:01:45 +01004173 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004174
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004175 ssl->in_left = 0;
Hanno Beckera8814792019-07-10 15:01:45 +01004176 }
4177
4178 /*
4179 * Decrypt record contents.
4180 */
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004181
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004182 if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) {
4183# if defined(MBEDTLS_SSL_PROTO_DTLS)
4184 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004185 /* Silently discard invalid records */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004186 if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
Manuel Pégourié-Gonnard0a885742015-08-04 12:08:35 +02004187 /* Except when waiting for Finished as a bad mac here
4188 * probably means something went wrong in the handshake
4189 * (eg wrong psk used, mitm downgrade attempt, etc.) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004190 if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
4191 ssl->state == MBEDTLS_SSL_SERVER_FINISHED) {
4192# if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4193 if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
4194 mbedtls_ssl_send_alert_message(
4195 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4196 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
Manuel Pégourié-Gonnard0a885742015-08-04 12:08:35 +02004197 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004198# endif
4199 return ret;
Manuel Pégourié-Gonnard0a885742015-08-04 12:08:35 +02004200 }
4201
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004202 if (ssl->conf->badmac_limit != 0 &&
4203 ++ssl->badmac_seen >= ssl->conf->badmac_limit) {
4204 MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
4205 return MBEDTLS_ERR_SSL_INVALID_MAC;
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004206 }
Manuel Pégourié-Gonnardb0643d12014-10-14 18:30:36 +02004207
Hanno Becker4a810fb2017-05-24 16:27:30 +01004208 /* As above, invalid records cause
4209 * dismissal of the whole datagram. */
4210
4211 ssl->next_record_offset = 0;
4212 ssl->in_left = 0;
4213
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004214 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)"));
4215 return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004216 }
4217
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004218 return ret;
4219 } else
4220# endif
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004221 {
4222 /* Error out (and send alert) on invalid records */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004223# if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4224 if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
4225 mbedtls_ssl_send_alert_message(
4226 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4227 MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004228 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004229# endif
4230 return ret;
Manuel Pégourié-Gonnard63eca932014-09-08 16:39:08 +02004231 }
4232 }
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004233
Hanno Becker44d89b22019-07-12 09:40:44 +01004234 /* Reset in pointers to default state for TLS/DTLS records,
4235 * assuming no CID and no offset between record content and
4236 * record plaintext. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004237 mbedtls_ssl_update_in_pointers(ssl);
4238# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker44d89b22019-07-12 09:40:44 +01004239 ssl->in_len = ssl->in_cid + rec.cid_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004240# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4241 ssl->in_iv = ssl->in_len + 2;
Hanno Becker44d89b22019-07-12 09:40:44 +01004242
Hanno Becker8685c822019-07-12 09:37:30 +01004243 /* The record content type may change during decryption,
4244 * so re-read it. */
4245 ssl->in_msgtype = rec.type;
4246 /* Also update the input buffer, because unfortunately
4247 * the server-side ssl_parse_client_hello() reparses the
4248 * record header when receiving a ClientHello initiating
4249 * a renegotiation. */
4250 ssl->in_hdr[0] = rec.type;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004251 ssl->in_msg = rec.buf + rec.data_offset;
Hanno Becker8685c822019-07-12 09:37:30 +01004252 ssl->in_msglen = rec.data_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004253 ssl->in_len[0] = (unsigned char)(rec.data_len >> 8);
4254 ssl->in_len[1] = (unsigned char)(rec.data_len);
Hanno Becker8685c822019-07-12 09:37:30 +01004255
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004256 return 0;
Simon Butcher99000142016-10-13 17:21:01 +01004257}
4258
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004259int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
Simon Butcher99000142016-10-13 17:21:01 +01004260{
Janos Follath865b3eb2019-12-16 11:46:15 +00004261 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Simon Butcher99000142016-10-13 17:21:01 +01004262
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02004263 /*
Manuel Pégourié-Gonnard167a3762014-09-08 16:14:10 +02004264 * Handle particular types of records
4265 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004266 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
4267 if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) {
4268 return ret;
Simon Butcher99000142016-10-13 17:21:01 +01004269 }
Paul Bakker5121ce52009-01-03 21:22:43 +00004270 }
4271
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004272 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
4273 if (ssl->in_msglen != 1) {
4274 MBEDTLS_SSL_DEBUG_MSG(
4275 1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
4276 ssl->in_msglen));
4277 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004278 }
4279
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004280 if (ssl->in_msg[0] != 1) {
4281 MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x",
4282 ssl->in_msg[0]));
4283 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Hanno Beckere678eaa2018-08-21 14:57:46 +01004284 }
4285
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004286# if defined(MBEDTLS_SSL_PROTO_DTLS)
4287 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4288 ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
4289 ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
4290 if (ssl->handshake == NULL) {
4291 MBEDTLS_SSL_DEBUG_MSG(
4292 1, ("dropping ChangeCipherSpec outside handshake"));
4293 return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
Hanno Beckere678eaa2018-08-21 14:57:46 +01004294 }
4295
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004296 MBEDTLS_SSL_DEBUG_MSG(
4297 1, ("received out-of-order ChangeCipherSpec - remember"));
4298 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
Hanno Beckere678eaa2018-08-21 14:57:46 +01004299 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004300# endif
Hanno Beckere678eaa2018-08-21 14:57:46 +01004301 }
Hanno Becker2ed6bcc2018-08-15 15:11:57 +01004302
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004303 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
4304 if (ssl->in_msglen != 2) {
Angus Gratton1a7a17e2018-06-20 15:43:50 +10004305 /* Note: Standard allows for more than one 2 byte alert
4306 to be packed in a single message, but Mbed TLS doesn't
4307 currently support this. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004308 MBEDTLS_SSL_DEBUG_MSG(
4309 1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
4310 ssl->in_msglen));
4311 return MBEDTLS_ERR_SSL_INVALID_RECORD;
Angus Gratton1a7a17e2018-06-20 15:43:50 +10004312 }
4313
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004314 MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]",
4315 ssl->in_msg[0], ssl->in_msg[1]));
Paul Bakker5121ce52009-01-03 21:22:43 +00004316
4317 /*
Simon Butcher459a9502015-10-27 16:09:03 +00004318 * Ignore non-fatal alerts, except close_notify and no_renegotiation
Paul Bakker5121ce52009-01-03 21:22:43 +00004319 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004320 if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) {
4321 MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)",
4322 ssl->in_msg[1]));
4323 return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00004324 }
4325
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004326 if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4327 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) {
4328 MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message"));
4329 return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
Paul Bakker5121ce52009-01-03 21:22:43 +00004330 }
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004331
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004332# if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
4333 if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
4334 ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) {
4335 MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert"));
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004336 /* Will be handled when trying to parse ServerHello */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004337 return 0;
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004338 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004339# endif
Manuel Pégourié-Gonnardfbdf06c2015-10-23 11:13:28 +02004340 /* Silently ignore: fetch new message */
Simon Butcher99000142016-10-13 17:21:01 +01004341 return MBEDTLS_ERR_SSL_NON_FATAL;
Paul Bakker5121ce52009-01-03 21:22:43 +00004342 }
4343
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004344# if defined(MBEDTLS_SSL_PROTO_DTLS)
4345 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Becker37ae9522019-05-03 16:54:26 +01004346 /* Drop unexpected ApplicationData records,
4347 * except at the beginning of renegotiations */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004348 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
Hanno Becker37ae9522019-05-03 16:54:26 +01004349 ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004350# if defined(MBEDTLS_SSL_RENEGOTIATION)
4351 && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
4352 ssl->state == MBEDTLS_SSL_SERVER_HELLO)
4353# endif
4354 ) {
4355 MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData"));
4356 return MBEDTLS_ERR_SSL_NON_FATAL;
Hanno Becker37ae9522019-05-03 16:54:26 +01004357 }
4358
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004359 if (ssl->handshake != NULL &&
4360 ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER) {
4361 mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
Hanno Becker37ae9522019-05-03 16:54:26 +01004362 }
4363 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004364# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Beckerc76c6192017-06-06 10:03:17 +01004365
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004366 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004367}
4368
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004369int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl)
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00004370{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004371 return (mbedtls_ssl_send_alert_message(
4372 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4373 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE));
Paul Bakkerd0f6fa72012-09-17 09:18:12 +00004374}
4375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004376int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
4377 unsigned char level,
4378 unsigned char message)
Paul Bakker0a925182012-04-16 06:46:41 +00004379{
Janos Follath865b3eb2019-12-16 11:46:15 +00004380 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker0a925182012-04-16 06:46:41 +00004381
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004382 if (ssl == NULL || ssl->conf == NULL)
4383 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02004384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004385 MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message"));
4386 MBEDTLS_SSL_DEBUG_MSG(3,
4387 ("send alert level=%u message=%u", level, message));
Paul Bakker0a925182012-04-16 06:46:41 +00004388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004389 ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
Paul Bakker0a925182012-04-16 06:46:41 +00004390 ssl->out_msglen = 2;
4391 ssl->out_msg[0] = level;
4392 ssl->out_msg[1] = message;
4393
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004394 if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
4395 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
4396 return ret;
Paul Bakker0a925182012-04-16 06:46:41 +00004397 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004398 MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message"));
Paul Bakker0a925182012-04-16 06:46:41 +00004399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004400 return 0;
Paul Bakker0a925182012-04-16 06:46:41 +00004401}
4402
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004403int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004404{
Janos Follath865b3eb2019-12-16 11:46:15 +00004405 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00004406
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004407 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
Paul Bakker5121ce52009-01-03 21:22:43 +00004408
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004409 ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004410 ssl->out_msglen = 1;
4411 ssl->out_msg[0] = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00004412
Paul Bakker5121ce52009-01-03 21:22:43 +00004413 ssl->state++;
4414
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004415 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
4416 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
4417 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004418 }
4419
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004420 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));
Paul Bakker5121ce52009-01-03 21:22:43 +00004421
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004422 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004423}
4424
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004425int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004426{
Janos Follath865b3eb2019-12-16 11:46:15 +00004427 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00004428
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004429 MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec"));
Paul Bakker5121ce52009-01-03 21:22:43 +00004430
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004431 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
4432 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
4433 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004434 }
4435
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004436 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
4437 MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message"));
4438 mbedtls_ssl_send_alert_message(
4439 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4440 MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
4441 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00004442 }
4443
Hanno Beckere678eaa2018-08-21 14:57:46 +01004444 /* CCS records are only accepted if they have length 1 and content '1',
4445 * so we don't need to check this here. */
Paul Bakker5121ce52009-01-03 21:22:43 +00004446
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004447 /*
4448 * Switch to our negotiated transform and session parameters for inbound
4449 * data.
4450 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004451 MBEDTLS_SSL_DEBUG_MSG(3,
4452 ("switching to new transform spec for inbound data"));
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004453 ssl->transform_in = ssl->transform_negotiate;
4454 ssl->session_in = ssl->session_negotiate;
4455
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004456# if defined(MBEDTLS_SSL_PROTO_DTLS)
4457 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4458# if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
4459 mbedtls_ssl_dtls_replay_reset(ssl);
4460# endif
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004461
4462 /* Increment epoch */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004463 if (++ssl->in_epoch == 0) {
4464 MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
Gilles Peskine1cc8e342017-05-03 16:28:34 +02004465 /* This is highly unlikely to happen for legitimate reasons, so
4466 treat it as an attack and don't send an alert. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004467 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004468 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004469 } else
4470# endif /* MBEDTLS_SSL_PROTO_DTLS */
4471 memset(ssl->in_ctr, 0, 8);
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004472
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004473 mbedtls_ssl_update_in_pointers(ssl);
Manuel Pégourié-Gonnard246c13a2014-09-24 13:56:09 +02004474
Paul Bakker5121ce52009-01-03 21:22:43 +00004475 ssl->state++;
4476
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004477 MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec"));
Paul Bakker5121ce52009-01-03 21:22:43 +00004478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004479 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00004480}
4481
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004482/* Once ssl->out_hdr as the address of the beginning of the
4483 * next outgoing record is set, deduce the other pointers.
4484 *
4485 * Note: For TLS, we save the implicit record sequence number
4486 * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
4487 * and the caller has to make sure there's space for this.
4488 */
4489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004490static size_t
4491ssl_transform_get_explicit_iv_len(mbedtls_ssl_transform const *transform)
Hanno Beckerc0eefa82020-05-28 07:17:36 +01004492{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004493 if (transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3)
4494 return 0;
Hanno Beckerc0eefa82020-05-28 07:17:36 +01004495
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004496 return transform->ivlen - transform->fixed_ivlen;
Hanno Beckerc0eefa82020-05-28 07:17:36 +01004497}
4498
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004499void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
4500 mbedtls_ssl_transform *transform)
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004501{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004502# if defined(MBEDTLS_SSL_PROTO_DTLS)
4503 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4504 ssl->out_ctr = ssl->out_hdr + 3;
4505# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4506 ssl->out_cid = ssl->out_ctr + 8;
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004507 ssl->out_len = ssl->out_cid;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004508 if (transform != NULL)
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004509 ssl->out_len += transform->out_cid_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004510# else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004511 ssl->out_len = ssl->out_ctr + 8;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004512# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4513 ssl->out_iv = ssl->out_len + 2;
4514 } else
4515# endif
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004516 {
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004517 ssl->out_len = ssl->out_hdr + 3;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004518# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4c3eb7c2019-05-08 16:43:21 +01004519 ssl->out_cid = ssl->out_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004520# endif
4521 ssl->out_iv = ssl->out_hdr + 5;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004522 }
4523
Hanno Beckerc0eefa82020-05-28 07:17:36 +01004524 ssl->out_msg = ssl->out_iv;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004525 /* Adjust out_msg to make space for explicit IV, if used. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004526 if (transform != NULL)
4527 ssl->out_msg += ssl_transform_get_explicit_iv_len(transform);
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004528}
4529
4530/* Once ssl->in_hdr as the address of the beginning of the
4531 * next incoming record is set, deduce the other pointers.
4532 *
4533 * Note: For TLS, we save the implicit record sequence number
4534 * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
4535 * and the caller has to make sure there's space for this.
4536 */
4537
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004538void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004539{
Hanno Becker79594fd2019-05-08 09:38:41 +01004540 /* This function sets the pointers to match the case
4541 * of unprotected TLS/DTLS records, with both ssl->in_iv
4542 * and ssl->in_msg pointing to the beginning of the record
4543 * content.
4544 *
4545 * When decrypting a protected record, ssl->in_msg
4546 * will be shifted to point to the beginning of the
4547 * record plaintext.
4548 */
4549
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004550# if defined(MBEDTLS_SSL_PROTO_DTLS)
4551 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004552 /* This sets the header pointers to match records
4553 * without CID. When we receive a record containing
4554 * a CID, the fields are shifted accordingly in
4555 * ssl_parse_record_header(). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004556 ssl->in_ctr = ssl->in_hdr + 3;
4557# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4558 ssl->in_cid = ssl->in_ctr + 8;
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004559 ssl->in_len = ssl->in_cid; /* Default: no CID */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004560# else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerf9c6a4b2019-05-03 14:34:53 +01004561 ssl->in_len = ssl->in_ctr + 8;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004562# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4563 ssl->in_iv = ssl->in_len + 2;
4564 } else
4565# endif
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004566 {
4567 ssl->in_ctr = ssl->in_hdr - 8;
4568 ssl->in_len = ssl->in_hdr + 3;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004569# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Becker4c3eb7c2019-05-08 16:43:21 +01004570 ssl->in_cid = ssl->in_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004571# endif
4572 ssl->in_iv = ssl->in_hdr + 5;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004573 }
4574
Hanno Becker79594fd2019-05-08 09:38:41 +01004575 /* This will be adjusted at record decryption time. */
4576 ssl->in_msg = ssl->in_iv;
Hanno Becker5aa4e2c2018-08-06 09:26:08 +01004577}
4578
Paul Bakker5121ce52009-01-03 21:22:43 +00004579/*
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +02004580 * Setup an SSL context
4581 */
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004582
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004583void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004584{
4585 /* Set the incoming and outgoing record pointers. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004586# if defined(MBEDTLS_SSL_PROTO_DTLS)
4587 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004588 ssl->out_hdr = ssl->out_buf;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004589 ssl->in_hdr = ssl->in_buf;
4590 } else
4591# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004592 {
Hanno Becker12078f42021-03-02 15:28:41 +00004593 ssl->out_ctr = ssl->out_buf;
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004594 ssl->out_hdr = ssl->out_buf + 8;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004595 ssl->in_hdr = ssl->in_buf + 8;
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004596 }
4597
4598 /* Derive other internal pointers. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004599 mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
4600 mbedtls_ssl_update_in_pointers(ssl);
Hanno Becker2a43f6f2018-08-10 11:12:52 +01004601}
4602
Paul Bakker5121ce52009-01-03 21:22:43 +00004603/*
4604 * SSL get accessors
4605 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004606size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00004607{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004608 return ssl->in_offt == NULL ? 0 : ssl->in_msglen;
Paul Bakker5121ce52009-01-03 21:22:43 +00004609}
4610
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004611int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl)
Hanno Becker8b170a02017-10-10 11:51:19 +01004612{
4613 /*
4614 * Case A: We're currently holding back
4615 * a message for further processing.
4616 */
4617
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004618 if (ssl->keep_current_message == 1) {
4619 MBEDTLS_SSL_DEBUG_MSG(
4620 3, ("ssl_check_pending: record held back for processing"));
4621 return 1;
Hanno Becker8b170a02017-10-10 11:51:19 +01004622 }
4623
4624 /*
4625 * Case B: Further records are pending in the current datagram.
4626 */
4627
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004628# if defined(MBEDTLS_SSL_PROTO_DTLS)
4629 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4630 ssl->in_left > ssl->next_record_offset) {
4631 MBEDTLS_SSL_DEBUG_MSG(
4632 3, ("ssl_check_pending: more records within current datagram"));
4633 return 1;
Hanno Becker8b170a02017-10-10 11:51:19 +01004634 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004635# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker8b170a02017-10-10 11:51:19 +01004636
4637 /*
4638 * Case C: A handshake message is being processed.
4639 */
4640
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004641 if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) {
4642 MBEDTLS_SSL_DEBUG_MSG(
4643 3,
4644 ("ssl_check_pending: more handshake messages within current record"));
4645 return 1;
Hanno Becker8b170a02017-10-10 11:51:19 +01004646 }
4647
4648 /*
4649 * Case D: An application data message is being processed
4650 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004651 if (ssl->in_offt != NULL) {
4652 MBEDTLS_SSL_DEBUG_MSG(
4653 3,
4654 ("ssl_check_pending: application data record is being processed"));
4655 return 1;
Hanno Becker8b170a02017-10-10 11:51:19 +01004656 }
4657
4658 /*
4659 * In all other cases, the rest of the message can be dropped.
Hanno Beckerc573ac32018-08-28 17:15:25 +01004660 * As in ssl_get_next_record, this needs to be adapted if
Hanno Becker8b170a02017-10-10 11:51:19 +01004661 * we implement support for multiple alerts in single records.
4662 */
4663
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004664 MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending"));
4665 return 0;
Hanno Becker8b170a02017-10-10 11:51:19 +01004666}
4667
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004668int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004669{
Hanno Becker3136ede2018-08-17 15:28:19 +01004670 size_t transform_expansion = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004671 const mbedtls_ssl_transform *transform = ssl->transform_out;
Hanno Becker5b559ac2018-08-03 09:40:07 +01004672 unsigned block_size;
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004673
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004674 size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl);
Hanno Becker5903de42019-05-03 14:46:38 +01004675
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004676 if (transform == NULL)
4677 return (int)out_hdr_len;
Hanno Becker78640902018-08-13 16:35:15 +01004678
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004679 switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004680 case MBEDTLS_MODE_GCM:
4681 case MBEDTLS_MODE_CCM:
Hanno Becker5b559ac2018-08-03 09:40:07 +01004682 case MBEDTLS_MODE_CHACHAPOLY:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004683 case MBEDTLS_MODE_STREAM:
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004684 transform_expansion = transform->minlen;
4685 break;
4686
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004687 case MBEDTLS_MODE_CBC:
Hanno Becker5b559ac2018-08-03 09:40:07 +01004688
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004689 block_size =
4690 mbedtls_cipher_get_block_size(&transform->cipher_ctx_enc);
Hanno Becker5b559ac2018-08-03 09:40:07 +01004691
Hanno Becker3136ede2018-08-17 15:28:19 +01004692 /* Expansion due to the addition of the MAC. */
4693 transform_expansion += transform->maclen;
4694
4695 /* Expansion due to the addition of CBC padding;
4696 * Theoretically up to 256 bytes, but we never use
4697 * more than the block size of the underlying cipher. */
4698 transform_expansion += block_size;
4699
TRodziewicz4ca18aa2021-05-20 14:46:20 +02004700 /* For TLS 1.2 or higher, an explicit IV is added
Hanno Becker3136ede2018-08-17 15:28:19 +01004701 * after the record header. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004702# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
TRodziewicz345165c2021-07-06 13:42:11 +02004703 transform_expansion += block_size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004704# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Becker3136ede2018-08-17 15:28:19 +01004705
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004706 break;
4707
4708 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004709 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4710 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004711 }
4712
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004713# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4714 if (transform->out_cid_len != 0)
Hanno Becker6cbad552019-05-08 15:40:11 +01004715 transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004716# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Becker6cbad552019-05-08 15:40:11 +01004717
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004718 return ((int)(out_hdr_len + transform_expansion));
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02004719}
4720
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004721# if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard214eed32013-10-30 13:06:54 +01004722/*
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004723 * Check record counters and renegotiate if they're above the limit.
4724 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004725static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004726{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004727 size_t ep_len = mbedtls_ssl_ep_len(ssl);
Andres AG2196c7f2016-12-15 17:01:16 +00004728 int in_ctr_cmp;
4729 int out_ctr_cmp;
4730
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004731 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004732 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004733 ssl->conf->disable_renegotiation ==
4734 MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
4735 return 0;
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004736 }
4737
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004738 in_ctr_cmp = memcmp(ssl->in_ctr + ep_len, ssl->conf->renego_period + ep_len,
4739 8 - ep_len);
4740 out_ctr_cmp = memcmp(ssl->cur_out_ctr + ep_len,
4741 ssl->conf->renego_period + ep_len, 8 - ep_len);
Andres AG2196c7f2016-12-15 17:01:16 +00004742
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004743 if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) {
4744 return 0;
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004745 }
4746
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004747 MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate"));
4748 return mbedtls_ssl_renegotiate(ssl);
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004749}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004750# endif /* MBEDTLS_SSL_RENEGOTIATION */
Paul Bakker48916f92012-09-16 19:57:18 +00004751
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004752/* This function is called from mbedtls_ssl_read() when a handshake message is
Hanno Beckerf26cc722021-04-21 07:30:13 +01004753 * received after the initial handshake. In this context, handshake messages
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004754 * may only be sent for the purpose of initiating renegotiations.
4755 *
4756 * This function is introduced as a separate helper since the handling
4757 * of post-handshake handshake messages changes significantly in TLS 1.3,
4758 * and having a helper function allows to distinguish between TLS <= 1.2 and
4759 * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read().
4760 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004761static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004762{
Hanno Beckerfae12cf2021-04-21 07:20:20 +01004763 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004764
4765 /*
4766 * - For client-side, expect SERVER_HELLO_REQUEST.
4767 * - For server-side, expect CLIENT_HELLO.
4768 * - Fail (TLS) or silently drop record (DTLS) in other cases.
4769 */
4770
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004771# if defined(MBEDTLS_SSL_CLI_C)
4772 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
4773 (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
4774 ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl))) {
4775 MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)"));
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004776
4777 /* With DTLS, drop the packet (probably from last handshake) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004778# if defined(MBEDTLS_SSL_PROTO_DTLS)
4779 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4780 return 0;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004781 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004782# endif
4783 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004784 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004785# endif /* MBEDTLS_SSL_CLI_C */
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004786
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004787# if defined(MBEDTLS_SSL_SRV_C)
4788 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
4789 ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
4790 MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)"));
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004791
4792 /* With DTLS, drop the packet (probably from last handshake) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004793# if defined(MBEDTLS_SSL_PROTO_DTLS)
4794 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4795 return 0;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004796 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004797# endif
4798 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004799 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004800# endif /* MBEDTLS_SSL_SRV_C */
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004801
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004802# if defined(MBEDTLS_SSL_RENEGOTIATION)
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004803 /* Determine whether renegotiation attempt should be accepted */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004804 if (!(ssl->conf->disable_renegotiation ==
4805 MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
4806 (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
4807 ssl->conf->allow_legacy_renegotiation ==
4808 MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) {
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004809 /*
4810 * Accept renegotiation request
4811 */
4812
4813 /* DTLS clients need to know renego is server-initiated */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004814# if defined(MBEDTLS_SSL_PROTO_DTLS)
4815 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4816 ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004817 ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
4818 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004819# endif
4820 ret = mbedtls_ssl_start_renegotiation(ssl);
4821 if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && ret != 0) {
4822 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation", ret);
4823 return ret;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004824 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004825 } else
4826# endif /* MBEDTLS_SSL_RENEGOTIATION */
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004827 {
4828 /*
4829 * Refuse renegotiation
4830 */
4831
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004832 MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert"));
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004833
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004834# if defined(MBEDTLS_SSL_PROTO_TLS1_2)
4835 if ((ret = mbedtls_ssl_send_alert_message(
4836 ssl, MBEDTLS_SSL_ALERT_LEVEL_WARNING,
4837 MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) {
4838 return ret;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004839 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004840# endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004841 }
4842
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004843 return 0;
Hanno Beckerb03f88f2020-11-24 06:41:37 +00004844}
4845
Paul Bakker48916f92012-09-16 19:57:18 +00004846/*
Paul Bakker5121ce52009-01-03 21:22:43 +00004847 * Receive application data decrypted from the SSL layer
4848 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004849int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
Paul Bakker5121ce52009-01-03 21:22:43 +00004850{
Janos Follath865b3eb2019-12-16 11:46:15 +00004851 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00004852 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +00004853
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004854 if (ssl == NULL || ssl->conf == NULL)
4855 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02004856
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004857 MBEDTLS_SSL_DEBUG_MSG(2, ("=> read"));
Paul Bakker5121ce52009-01-03 21:22:43 +00004858
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004859# if defined(MBEDTLS_SSL_PROTO_DTLS)
4860 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4861 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0)
4862 return ret;
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02004863
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004864 if (ssl->handshake != NULL &&
4865 ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
4866 if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0)
4867 return ret;
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02004868 }
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02004869 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004870# endif
Manuel Pégourié-Gonnardabf16242014-09-23 09:42:16 +02004871
Hanno Becker4a810fb2017-05-24 16:27:30 +01004872 /*
4873 * Check if renegotiation is necessary and/or handshake is
4874 * in process. If yes, perform/continue, and fall through
4875 * if an unexpected packet is received while the client
4876 * is waiting for the ServerHello.
4877 *
4878 * (There is no equivalent to the last condition on
4879 * the server-side as it is not treated as within
4880 * a handshake while waiting for the ClientHello
4881 * after a renegotiation request.)
4882 */
4883
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004884# if defined(MBEDTLS_SSL_RENEGOTIATION)
4885 ret = ssl_check_ctr_renegotiate(ssl);
4886 if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && ret != 0) {
4887 MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
4888 return ret;
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004889 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004890# endif
Manuel Pégourié-Gonnardb4458052014-11-04 21:04:22 +01004891
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004892 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
4893 ret = mbedtls_ssl_handshake(ssl);
4894 if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && ret != 0) {
4895 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
4896 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004897 }
4898 }
4899
Hanno Beckere41158b2017-10-23 13:30:32 +01004900 /* Loop as long as no application data record is available */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004901 while (ssl->in_offt == NULL) {
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02004902 /* Start timer if not already running */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004903 if (ssl->f_get_timer != NULL && ssl->f_get_timer(ssl->p_timer) == -1) {
4904 mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout);
Manuel Pégourié-Gonnard545102e2015-05-13 17:28:43 +02004905 }
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02004906
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004907 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
4908 if (ret == MBEDTLS_ERR_SSL_CONN_EOF)
4909 return 0;
Paul Bakker831a7552011-05-18 13:32:51 +00004910
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004911 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
4912 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004913 }
4914
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004915 if (ssl->in_msglen == 0 &&
4916 ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
Paul Bakker5121ce52009-01-03 21:22:43 +00004917 /*
4918 * OpenSSL sends empty messages to randomize the IV
4919 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004920 if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
4921 if (ret == MBEDTLS_ERR_SSL_CONN_EOF)
4922 return 0;
Paul Bakker831a7552011-05-18 13:32:51 +00004923
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004924 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
4925 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00004926 }
4927 }
4928
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004929 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
4930 ret = ssl_handle_hs_message_post_handshake(ssl);
4931 if (ret != 0) {
4932 MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake",
4933 ret);
4934 return ret;
Paul Bakker48916f92012-09-16 19:57:18 +00004935 }
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02004936
Hanno Beckerf26cc722021-04-21 07:30:13 +01004937 /* At this point, we don't know whether the renegotiation triggered
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004938 * by the post-handshake message has been completed or not. The
4939 * cases to consider are the following: 1) The renegotiation is
4940 * complete. In this case, no new record has been read yet. 2) The
4941 * renegotiation is incomplete because the client received an
4942 * application data record while awaiting the ServerHello. 3) The
4943 * renegotiation is incomplete because the client received a
4944 * non-handshake, non-application data message while awaiting the
4945 * ServerHello.
Hanno Beckerf26cc722021-04-21 07:30:13 +01004946 *
4947 * In each of these cases, looping will be the proper action:
Hanno Becker90333da2017-10-10 11:27:13 +01004948 * - For 1), the next iteration will read a new record and check
4949 * if it's application data.
4950 * - For 2), the loop condition isn't satisfied as application data
4951 * is present, hence continue is the same as break
4952 * - For 3), the loop condition is satisfied and read_record
4953 * will re-deliver the message that was held back by the client
4954 * when expecting the ServerHello.
4955 */
Hanno Beckerf26cc722021-04-21 07:30:13 +01004956
Hanno Becker90333da2017-10-10 11:27:13 +01004957 continue;
Paul Bakker48916f92012-09-16 19:57:18 +00004958 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004959# if defined(MBEDTLS_SSL_RENEGOTIATION)
4960 else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
4961 if (ssl->conf->renego_max_records >= 0) {
4962 if (++ssl->renego_records_seen >
4963 ssl->conf->renego_max_records) {
4964 MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, "
4965 "but not honored by client"));
4966 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Manuel Pégourié-Gonnarddf3acd82014-10-15 15:07:45 +02004967 }
Manuel Pégourié-Gonnarda9964db2014-07-03 19:29:16 +02004968 }
Manuel Pégourié-Gonnard6d8404d2013-10-30 16:41:45 +01004969 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004970# endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02004971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02004972 /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004973 if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
4974 MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert"));
4975 return MBEDTLS_ERR_SSL_WANT_READ;
Manuel Pégourié-Gonnardf26a1e82014-08-19 12:28:50 +02004976 }
4977
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004978 if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
4979 MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message"));
4980 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
Paul Bakker5121ce52009-01-03 21:22:43 +00004981 }
4982
4983 ssl->in_offt = ssl->in_msg;
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +02004984
Manuel Pégourié-Gonnardba958b82014-10-09 16:13:44 +02004985 /* We're going to return something now, cancel timer,
4986 * except if handshake (renegotiation) is in progress */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004987 if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER)
4988 mbedtls_ssl_set_timer(ssl, 0);
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02004989
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004990# if defined(MBEDTLS_SSL_PROTO_DTLS)
4991 /* If we requested renego but received AppData, resend HelloRequest.
4992 * Do it now, after setting in_offt, to avoid taking this branch
4993 * again if ssl_write_hello_request() returns WANT_WRITE */
4994# if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
4995 if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
4996 ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
4997 if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
4998 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
4999 ret);
5000 return ret;
Manuel Pégourié-Gonnard26a4cf62014-10-15 13:52:48 +02005001 }
5002 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005003# endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
5004# endif /* MBEDTLS_SSL_PROTO_DTLS */
Paul Bakker5121ce52009-01-03 21:22:43 +00005005 }
5006
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005007 n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
Paul Bakker5121ce52009-01-03 21:22:43 +00005008
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005009 memcpy(buf, ssl->in_offt, n);
Paul Bakker5121ce52009-01-03 21:22:43 +00005010 ssl->in_msglen -= n;
5011
gabor-mezei-arma3214132020-07-15 10:55:00 +02005012 /* Zeroising the plaintext buffer to erase unused application data
5013 from the memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005014 mbedtls_platform_zeroize(ssl->in_offt, n);
gabor-mezei-arma3214132020-07-15 10:55:00 +02005015
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005016 if (ssl->in_msglen == 0) {
Hanno Becker4a810fb2017-05-24 16:27:30 +01005017 /* all bytes consumed */
Paul Bakker5121ce52009-01-03 21:22:43 +00005018 ssl->in_offt = NULL;
Hanno Beckerbdf39052017-06-09 10:42:03 +01005019 ssl->keep_current_message = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005020 } else {
Paul Bakker5121ce52009-01-03 21:22:43 +00005021 /* more data available */
5022 ssl->in_offt += n;
Hanno Becker4a810fb2017-05-24 16:27:30 +01005023 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005024
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005025 MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
Paul Bakker5121ce52009-01-03 21:22:43 +00005026
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005027 return (int)n;
Paul Bakker5121ce52009-01-03 21:22:43 +00005028}
5029
5030/*
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005031 * Send application data to be encrypted by the SSL layer, taking care of max
5032 * fragment length and buffer size.
5033 *
5034 * According to RFC 5246 Section 6.2.1:
5035 *
5036 * Zero-length fragments of Application data MAY be sent as they are
5037 * potentially useful as a traffic analysis countermeasure.
5038 *
5039 * Therefore, it is possible that the input message length is 0 and the
5040 * corresponding return code is 0 on success.
Paul Bakker5121ce52009-01-03 21:22:43 +00005041 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005042static int
5043ssl_write_real(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
Paul Bakker5121ce52009-01-03 21:22:43 +00005044{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005045 int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
5046 const size_t max_len = (size_t)ret;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005047
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005048 if (ret < 0) {
5049 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret);
5050 return ret;
Manuel Pégourié-Gonnard9468ff12017-09-21 13:49:50 +02005051 }
5052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005053 if (len > max_len) {
5054# if defined(MBEDTLS_SSL_PROTO_DTLS)
5055 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5056 MBEDTLS_SSL_DEBUG_MSG(
5057 1, ("fragment larger than the (negotiated) "
5058 "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
5059 " > %" MBEDTLS_PRINTF_SIZET,
5060 len, max_len));
5061 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5062 } else
5063# endif
Manuel Pégourié-Gonnard37e08e12014-10-13 17:55:52 +02005064 len = max_len;
5065 }
Paul Bakker887bd502011-06-08 13:10:54 +00005066
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005067 if (ssl->out_left != 0) {
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005068 /*
5069 * The user has previously tried to send the data and
5070 * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
5071 * written. In this case, we expect the high-level write function
5072 * (e.g. mbedtls_ssl_write()) to be called with the same parameters
5073 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005074 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
5075 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
5076 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00005077 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005078 } else {
Andres Amaya Garcia5b923522017-09-28 14:41:17 +01005079 /*
5080 * The user is trying to send a message the first time, so we need to
5081 * copy the data into the internal buffers and setup the data structure
5082 * to keep track of partial writes
5083 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005084 ssl->out_msglen = len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005085 ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005086 memcpy(ssl->out_msg, buf, len);
Paul Bakker887bd502011-06-08 13:10:54 +00005087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005088 if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
5089 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
5090 return ret;
Paul Bakker887bd502011-06-08 13:10:54 +00005091 }
Paul Bakker5121ce52009-01-03 21:22:43 +00005092 }
5093
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005094 return (int)len;
Paul Bakker5121ce52009-01-03 21:22:43 +00005095}
5096
5097/*
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005098 * Write application data (public-facing wrapper)
5099 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005100int mbedtls_ssl_write(mbedtls_ssl_context *ssl,
5101 const unsigned char *buf,
5102 size_t len)
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005103{
Janos Follath865b3eb2019-12-16 11:46:15 +00005104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005106 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write"));
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005107
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005108 if (ssl == NULL || ssl->conf == NULL)
5109 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005110
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005111# if defined(MBEDTLS_SSL_RENEGOTIATION)
5112 if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) {
5113 MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
5114 return ret;
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005115 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005116# endif
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005118 if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5119 if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
5120 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
5121 return ret;
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005122 }
5123 }
5124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005125 ret = ssl_write_real(ssl, buf, len);
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005126
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005127 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write"));
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005128
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005129 return ret;
Manuel Pégourié-Gonnarda2fce212015-04-15 19:09:03 +02005130}
5131
5132/*
Paul Bakker5121ce52009-01-03 21:22:43 +00005133 * Notify the peer that the connection is being closed
5134 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005135int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
Paul Bakker5121ce52009-01-03 21:22:43 +00005136{
Janos Follath865b3eb2019-12-16 11:46:15 +00005137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00005138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005139 if (ssl == NULL || ssl->conf == NULL)
5140 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardf81ee2e2015-09-01 17:43:40 +02005141
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005142 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify"));
Paul Bakker5121ce52009-01-03 21:22:43 +00005143
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005144 if (ssl->out_left != 0)
5145 return mbedtls_ssl_flush_output(ssl);
Paul Bakker5121ce52009-01-03 21:22:43 +00005146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005147 if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER) {
5148 if ((ret = mbedtls_ssl_send_alert_message(
5149 ssl, MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5150 MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) {
5151 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret);
5152 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00005153 }
5154 }
5155
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005156 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify"));
Paul Bakker5121ce52009-01-03 21:22:43 +00005157
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005158 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00005159}
5160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005161void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform)
Paul Bakker48916f92012-09-16 19:57:18 +00005162{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005163 if (transform == NULL)
Paul Bakkeraccaffe2014-06-26 13:37:14 +02005164 return;
5165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005166 mbedtls_cipher_free(&transform->cipher_ctx_enc);
5167 mbedtls_cipher_free(&transform->cipher_ctx_dec);
Manuel Pégourié-Gonnardf71e5872013-09-23 17:12:43 +02005168
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005169# if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
5170 mbedtls_md_free(&transform->md_ctx_enc);
5171 mbedtls_md_free(&transform->md_ctx_dec);
5172# endif
Paul Bakker61d113b2013-07-04 11:51:43 +02005173
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005174 mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform));
Paul Bakker48916f92012-09-16 19:57:18 +00005175}
5176
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005177# if defined(MBEDTLS_SSL_PROTO_DTLS)
Hanno Becker0271f962018-08-16 13:23:47 +01005178
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005179void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl)
Hanno Becker0271f962018-08-16 13:23:47 +01005180{
5181 unsigned offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005182 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
Hanno Becker0271f962018-08-16 13:23:47 +01005183
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005184 if (hs == NULL)
Hanno Becker0271f962018-08-16 13:23:47 +01005185 return;
5186
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005187 ssl_free_buffered_record(ssl);
Hanno Becker283f5ef2018-08-24 09:34:47 +01005188
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005189 for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++)
5190 ssl_buffering_free_slot(ssl, offset);
Hanno Beckere605b192018-08-21 15:59:07 +01005191}
5192
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005193static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl, uint8_t slot)
Hanno Beckere605b192018-08-21 15:59:07 +01005194{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005195 mbedtls_ssl_handshake_params *const hs = ssl->handshake;
5196 mbedtls_ssl_hs_buffer *const hs_buf = &hs->buffering.hs[slot];
Hanno Beckerb309b922018-08-23 13:18:05 +01005197
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005198 if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS)
Hanno Beckerb309b922018-08-23 13:18:05 +01005199 return;
5200
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005201 if (hs_buf->is_valid == 1) {
Hanno Beckere605b192018-08-21 15:59:07 +01005202 hs->buffering.total_bytes_buffered -= hs_buf->data_len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005203 mbedtls_platform_zeroize(hs_buf->data, hs_buf->data_len);
5204 mbedtls_free(hs_buf->data);
5205 memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
Hanno Becker0271f962018-08-16 13:23:47 +01005206 }
5207}
5208
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005209# endif /* MBEDTLS_SSL_PROTO_DTLS */
Hanno Becker0271f962018-08-16 13:23:47 +01005210
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005211/*
5212 * Convert version numbers to/from wire format
5213 * and, for DTLS, to/from TLS equivalent.
5214 *
5215 * For TLS this is the identity.
Brian J Murray1903fb32016-11-06 04:45:15 -08005216 * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005217 * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
5218 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005219void mbedtls_ssl_write_version(int major,
5220 int minor,
5221 int transport,
5222 unsigned char ver[2])
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005223{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005224# if defined(MBEDTLS_SSL_PROTO_DTLS)
5225 if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5226 if (minor == MBEDTLS_SSL_MINOR_VERSION_2)
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005227 --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
5228
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005229 ver[0] = (unsigned char)(255 - (major - 2));
5230 ver[1] = (unsigned char)(255 - (minor - 1));
5231 } else
5232# else
5233 ((void)transport);
5234# endif
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005235 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005236 ver[0] = (unsigned char)major;
5237 ver[1] = (unsigned char)minor;
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005238 }
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005239}
5240
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005241void mbedtls_ssl_read_version(int *major,
5242 int *minor,
5243 int transport,
5244 const unsigned char ver[2])
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005245{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005246# if defined(MBEDTLS_SSL_PROTO_DTLS)
5247 if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005248 *major = 255 - ver[0] + 2;
5249 *minor = 255 - ver[1] + 1;
5250
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005251 if (*minor == MBEDTLS_SSL_MINOR_VERSION_1)
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005252 ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02005253 } else
5254# else
5255 ((void)transport);
5256# endif
Manuel Pégourié-Gonnard34c10112014-03-25 13:36:22 +01005257 {
5258 *major = ver[0];
5259 *minor = ver[1];
5260 }
Manuel Pégourié-Gonnardabc7e3b2014-02-11 18:15:03 +01005261}
5262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02005263#endif /* MBEDTLS_SSL_TLS_C */