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