xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_msg.c (revision cb03400251f98aed22a2664509e3ed9e183800b0)
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
6b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
711fa71b9SJerome Forissier  */
811fa71b9SJerome Forissier /*
911fa71b9SJerome Forissier  *  http://www.ietf.org/rfc/rfc2246.txt
1011fa71b9SJerome Forissier  *  http://www.ietf.org/rfc/rfc4346.txt
1111fa71b9SJerome Forissier  */
1211fa71b9SJerome Forissier 
137901324dSJerome Forissier #include "common.h"
1411fa71b9SJerome Forissier 
1511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_TLS_C)
1611fa71b9SJerome Forissier 
1711fa71b9SJerome Forissier #include "mbedtls/platform.h"
1811fa71b9SJerome Forissier 
1911fa71b9SJerome Forissier #include "mbedtls/ssl.h"
2032b31808SJens Wiklander #include "ssl_misc.h"
21b0563631STom Van Eyck #include "debug_internal.h"
2211fa71b9SJerome Forissier #include "mbedtls/error.h"
2311fa71b9SJerome Forissier #include "mbedtls/platform_util.h"
2411fa71b9SJerome Forissier #include "mbedtls/version.h"
25039e02dfSJerome Forissier #include "constant_time_internal.h"
26039e02dfSJerome Forissier #include "mbedtls/constant_time.h"
277901324dSJerome Forissier 
2811fa71b9SJerome Forissier #include <string.h>
2911fa71b9SJerome Forissier 
3011fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
31b0563631STom Van Eyck #include "psa_util_internal.h"
3211fa71b9SJerome Forissier #include "psa/crypto.h"
3311fa71b9SJerome Forissier #endif
3411fa71b9SJerome Forissier 
3511fa71b9SJerome Forissier #if defined(MBEDTLS_X509_CRT_PARSE_C)
3611fa71b9SJerome Forissier #include "mbedtls/oid.h"
3711fa71b9SJerome Forissier #endif
3811fa71b9SJerome Forissier 
3932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
40b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many
41b0563631STom Van Eyck  * arguments in each translating place. */
42b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
43b0563631STom Van Eyck {
44b0563631STom Van Eyck     return psa_status_to_mbedtls(status, psa_to_ssl_errors,
45b0563631STom Van Eyck                                  ARRAY_LENGTH(psa_to_ssl_errors),
46b0563631STom Van Eyck                                  psa_generic_status_to_mbedtls);
47b0563631STom Van Eyck }
48b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
4932b31808SJens Wiklander #endif
5032b31808SJens Wiklander 
51b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
52b0563631STom Van Eyck 
53b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
54b0563631STom Van Eyck 
55b0563631STom Van Eyck #if defined(PSA_WANT_ALG_SHA_384)
56b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384)
57b0563631STom Van Eyck #elif defined(PSA_WANT_ALG_SHA_256)
58b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)
59b0563631STom Van Eyck #else /* See check_config.h */
60b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1)
61b0563631STom Van Eyck #endif
62b0563631STom Van Eyck 
63b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE
64b0563631STom Van Eyck int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
65b0563631STom Van Eyck                     psa_algorithm_t mac_alg,
66b0563631STom Van Eyck                     const unsigned char *add_data,
67b0563631STom Van Eyck                     size_t add_data_len,
68b0563631STom Van Eyck                     const unsigned char *data,
69b0563631STom Van Eyck                     size_t data_len_secret,
70b0563631STom Van Eyck                     size_t min_data_len,
71b0563631STom Van Eyck                     size_t max_data_len,
72b0563631STom Van Eyck                     unsigned char *output)
73b0563631STom Van Eyck {
74b0563631STom Van Eyck     /*
75b0563631STom Van Eyck      * This function breaks the HMAC abstraction and uses psa_hash_clone()
76b0563631STom Van Eyck      * extension in order to get constant-flow behaviour.
77b0563631STom Van Eyck      *
78b0563631STom Van Eyck      * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
79b0563631STom Van Eyck      * concatenation, and okey/ikey are the XOR of the key with some fixed bit
80b0563631STom Van Eyck      * patterns (see RFC 2104, sec. 2).
81b0563631STom Van Eyck      *
82b0563631STom Van Eyck      * We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
83b0563631STom Van Eyck      * hashing up to minlen, then cloning the context, and for each byte up
84b0563631STom Van Eyck      * to maxlen finishing up the hash computation, keeping only the
85b0563631STom Van Eyck      * correct result.
86b0563631STom Van Eyck      *
87b0563631STom Van Eyck      * Then we only need to compute HASH(okey + inner_hash) and we're done.
88b0563631STom Van Eyck      */
89b0563631STom Van Eyck     psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
90b0563631STom Van Eyck     const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
91b0563631STom Van Eyck     unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
92b0563631STom Van Eyck     const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
93b0563631STom Van Eyck     psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
94b0563631STom Van Eyck     size_t hash_length;
95b0563631STom Van Eyck 
96b0563631STom Van Eyck     unsigned char aux_out[PSA_HASH_MAX_SIZE];
97b0563631STom Van Eyck     psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
98b0563631STom Van Eyck     size_t offset;
99b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
100b0563631STom Van Eyck 
101b0563631STom Van Eyck     size_t mac_key_length;
102b0563631STom Van Eyck     size_t i;
103b0563631STom Van Eyck 
104b0563631STom Van Eyck #define PSA_CHK(func_call)        \
105b0563631STom Van Eyck     do {                            \
106b0563631STom Van Eyck         status = (func_call);       \
107b0563631STom Van Eyck         if (status != PSA_SUCCESS) \
108b0563631STom Van Eyck         goto cleanup;           \
109b0563631STom Van Eyck     } while (0)
110b0563631STom Van Eyck 
111b0563631STom Van Eyck     /* Export MAC key
112b0563631STom Van Eyck      * We assume key length is always exactly the output size
113b0563631STom Van Eyck      * which is never more than the block size, thus we use block_size
114b0563631STom Van Eyck      * as the key buffer size.
115b0563631STom Van Eyck      */
116b0563631STom Van Eyck     PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
117b0563631STom Van Eyck 
118b0563631STom Van Eyck     /* Calculate ikey */
119b0563631STom Van Eyck     for (i = 0; i < mac_key_length; i++) {
120b0563631STom Van Eyck         key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
121b0563631STom Van Eyck     }
122b0563631STom Van Eyck     for (; i < block_size; ++i) {
123b0563631STom Van Eyck         key_buf[i] = 0x36;
124b0563631STom Van Eyck     }
125b0563631STom Van Eyck 
126b0563631STom Van Eyck     PSA_CHK(psa_hash_setup(&operation, hash_alg));
127b0563631STom Van Eyck 
128b0563631STom Van Eyck     /* Now compute inner_hash = HASH(ikey + msg) */
129b0563631STom Van Eyck     PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
130b0563631STom Van Eyck     PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
131b0563631STom Van Eyck     PSA_CHK(psa_hash_update(&operation, data, min_data_len));
132b0563631STom Van Eyck 
133b0563631STom Van Eyck     /* Fill the hash buffer in advance with something that is
134b0563631STom Van Eyck      * not a valid hash (barring an attack on the hash and
135b0563631STom Van Eyck      * deliberately-crafted input), in case the caller doesn't
136b0563631STom Van Eyck      * check the return status properly. */
137b0563631STom Van Eyck     memset(output, '!', hash_size);
138b0563631STom Van Eyck 
139b0563631STom Van Eyck     /* For each possible length, compute the hash up to that point */
140b0563631STom Van Eyck     for (offset = min_data_len; offset <= max_data_len; offset++) {
141b0563631STom Van Eyck         PSA_CHK(psa_hash_clone(&operation, &aux_operation));
142b0563631STom Van Eyck         PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
143b0563631STom Van Eyck                                 PSA_HASH_MAX_SIZE, &hash_length));
144b0563631STom Van Eyck         /* Keep only the correct inner_hash in the output buffer */
145b0563631STom Van Eyck         mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
146b0563631STom Van Eyck                              output, aux_out, NULL, hash_size);
147b0563631STom Van Eyck 
148b0563631STom Van Eyck         if (offset < max_data_len) {
149b0563631STom Van Eyck             PSA_CHK(psa_hash_update(&operation, data + offset, 1));
150b0563631STom Van Eyck         }
151b0563631STom Van Eyck     }
152b0563631STom Van Eyck 
153b0563631STom Van Eyck     /* Abort current operation to prepare for final operation */
154b0563631STom Van Eyck     PSA_CHK(psa_hash_abort(&operation));
155b0563631STom Van Eyck 
156b0563631STom Van Eyck     /* Calculate okey */
157b0563631STom Van Eyck     for (i = 0; i < mac_key_length; i++) {
158b0563631STom Van Eyck         key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
159b0563631STom Van Eyck     }
160b0563631STom Van Eyck     for (; i < block_size; ++i) {
161b0563631STom Van Eyck         key_buf[i] = 0x5C;
162b0563631STom Van Eyck     }
163b0563631STom Van Eyck 
164b0563631STom Van Eyck     /* Now compute HASH(okey + inner_hash) */
165b0563631STom Van Eyck     PSA_CHK(psa_hash_setup(&operation, hash_alg));
166b0563631STom Van Eyck     PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
167b0563631STom Van Eyck     PSA_CHK(psa_hash_update(&operation, output, hash_size));
168b0563631STom Van Eyck     PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
169b0563631STom Van Eyck 
170b0563631STom Van Eyck #undef PSA_CHK
171b0563631STom Van Eyck 
172b0563631STom Van Eyck cleanup:
173b0563631STom Van Eyck     mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
174b0563631STom Van Eyck     mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
175b0563631STom Van Eyck 
176b0563631STom Van Eyck     psa_hash_abort(&operation);
177b0563631STom Van Eyck     psa_hash_abort(&aux_operation);
178b0563631STom Van Eyck     return PSA_TO_MBEDTLS_ERR(status);
179b0563631STom Van Eyck }
180b0563631STom Van Eyck 
181b0563631STom Van Eyck #undef MAX_HASH_BLOCK_LENGTH
182b0563631STom Van Eyck 
183b0563631STom Van Eyck #else
184b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE
185b0563631STom Van Eyck int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
186b0563631STom Van Eyck                     const unsigned char *add_data,
187b0563631STom Van Eyck                     size_t add_data_len,
188b0563631STom Van Eyck                     const unsigned char *data,
189b0563631STom Van Eyck                     size_t data_len_secret,
190b0563631STom Van Eyck                     size_t min_data_len,
191b0563631STom Van Eyck                     size_t max_data_len,
192b0563631STom Van Eyck                     unsigned char *output)
193b0563631STom Van Eyck {
194b0563631STom Van Eyck     /*
195b0563631STom Van Eyck      * This function breaks the HMAC abstraction and uses the md_clone()
196b0563631STom Van Eyck      * extension to the MD API in order to get constant-flow behaviour.
197b0563631STom Van Eyck      *
198b0563631STom Van Eyck      * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
199b0563631STom Van Eyck      * concatenation, and okey/ikey are the XOR of the key with some fixed bit
200b0563631STom Van Eyck      * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
201b0563631STom Van Eyck      *
202b0563631STom Van Eyck      * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
203b0563631STom Van Eyck      * minlen, then cloning the context, and for each byte up to maxlen
204b0563631STom Van Eyck      * finishing up the hash computation, keeping only the correct result.
205b0563631STom Van Eyck      *
206b0563631STom Van Eyck      * Then we only need to compute HASH(okey + inner_hash) and we're done.
207b0563631STom Van Eyck      */
208b0563631STom Van Eyck     const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
209b0563631STom Van Eyck     /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
210b0563631STom Van Eyck      * all of which have the same block size except SHA-384. */
211b0563631STom Van Eyck     const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
212b0563631STom Van Eyck     const unsigned char * const ikey = ctx->hmac_ctx;
213b0563631STom Van Eyck     const unsigned char * const okey = ikey + block_size;
214b0563631STom Van Eyck     const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
215b0563631STom Van Eyck 
216b0563631STom Van Eyck     unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
217b0563631STom Van Eyck     mbedtls_md_context_t aux;
218b0563631STom Van Eyck     size_t offset;
219b0563631STom Van Eyck     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
220b0563631STom Van Eyck 
221b0563631STom Van Eyck     mbedtls_md_init(&aux);
222b0563631STom Van Eyck 
223b0563631STom Van Eyck #define MD_CHK(func_call) \
224b0563631STom Van Eyck     do {                    \
225b0563631STom Van Eyck         ret = (func_call);  \
226b0563631STom Van Eyck         if (ret != 0)      \
227b0563631STom Van Eyck         goto cleanup;   \
228b0563631STom Van Eyck     } while (0)
229b0563631STom Van Eyck 
230b0563631STom Van Eyck     MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
231b0563631STom Van Eyck 
232b0563631STom Van Eyck     /* After hmac_start() of hmac_reset(), ikey has already been hashed,
233b0563631STom Van Eyck      * so we can start directly with the message */
234b0563631STom Van Eyck     MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
235b0563631STom Van Eyck     MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
236b0563631STom Van Eyck 
237b0563631STom Van Eyck     /* Fill the hash buffer in advance with something that is
238b0563631STom Van Eyck      * not a valid hash (barring an attack on the hash and
239b0563631STom Van Eyck      * deliberately-crafted input), in case the caller doesn't
240b0563631STom Van Eyck      * check the return status properly. */
241b0563631STom Van Eyck     memset(output, '!', hash_size);
242b0563631STom Van Eyck 
243b0563631STom Van Eyck     /* For each possible length, compute the hash up to that point */
244b0563631STom Van Eyck     for (offset = min_data_len; offset <= max_data_len; offset++) {
245b0563631STom Van Eyck         MD_CHK(mbedtls_md_clone(&aux, ctx));
246b0563631STom Van Eyck         MD_CHK(mbedtls_md_finish(&aux, aux_out));
247b0563631STom Van Eyck         /* Keep only the correct inner_hash in the output buffer */
248b0563631STom Van Eyck         mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
249b0563631STom Van Eyck                              output, aux_out, NULL, hash_size);
250b0563631STom Van Eyck 
251b0563631STom Van Eyck         if (offset < max_data_len) {
252b0563631STom Van Eyck             MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
253b0563631STom Van Eyck         }
254b0563631STom Van Eyck     }
255b0563631STom Van Eyck 
256b0563631STom Van Eyck     /* The context needs to finish() before it starts() again */
257b0563631STom Van Eyck     MD_CHK(mbedtls_md_finish(ctx, aux_out));
258b0563631STom Van Eyck 
259b0563631STom Van Eyck     /* Now compute HASH(okey + inner_hash) */
260b0563631STom Van Eyck     MD_CHK(mbedtls_md_starts(ctx));
261b0563631STom Van Eyck     MD_CHK(mbedtls_md_update(ctx, okey, block_size));
262b0563631STom Van Eyck     MD_CHK(mbedtls_md_update(ctx, output, hash_size));
263b0563631STom Van Eyck     MD_CHK(mbedtls_md_finish(ctx, output));
264b0563631STom Van Eyck 
265b0563631STom Van Eyck     /* Done, get ready for next time */
266b0563631STom Van Eyck     MD_CHK(mbedtls_md_hmac_reset(ctx));
267b0563631STom Van Eyck 
268b0563631STom Van Eyck #undef MD_CHK
269b0563631STom Van Eyck 
270b0563631STom Van Eyck cleanup:
271b0563631STom Van Eyck     mbedtls_md_free(&aux);
272b0563631STom Van Eyck     return ret;
273b0563631STom Van Eyck }
274b0563631STom Van Eyck 
275b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
276b0563631STom Van Eyck 
277b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
278b0563631STom Van Eyck 
27911fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
28011fa71b9SJerome Forissier 
28111fa71b9SJerome Forissier /*
28211fa71b9SJerome Forissier  * Start a timer.
28311fa71b9SJerome Forissier  * Passing millisecs = 0 cancels a running timer.
28411fa71b9SJerome Forissier  */
28511fa71b9SJerome Forissier void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs)
28611fa71b9SJerome Forissier {
28732b31808SJens Wiklander     if (ssl->f_set_timer == NULL) {
28811fa71b9SJerome Forissier         return;
28932b31808SJens Wiklander     }
29011fa71b9SJerome Forissier 
29111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int) millisecs));
29211fa71b9SJerome Forissier     ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs);
29311fa71b9SJerome Forissier }
29411fa71b9SJerome Forissier 
29511fa71b9SJerome Forissier /*
29611fa71b9SJerome Forissier  * Return -1 is timer is expired, 0 if it isn't.
29711fa71b9SJerome Forissier  */
29811fa71b9SJerome Forissier int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl)
29911fa71b9SJerome Forissier {
30032b31808SJens Wiklander     if (ssl->f_get_timer == NULL) {
30132b31808SJens Wiklander         return 0;
30232b31808SJens Wiklander     }
30311fa71b9SJerome Forissier 
30432b31808SJens Wiklander     if (ssl->f_get_timer(ssl->p_timer) == 2) {
30511fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired"));
30632b31808SJens Wiklander         return -1;
30711fa71b9SJerome Forissier     }
30811fa71b9SJerome Forissier 
30932b31808SJens Wiklander     return 0;
31011fa71b9SJerome Forissier }
31111fa71b9SJerome Forissier 
312039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
31311fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
31411fa71b9SJerome Forissier                                    unsigned char *buf,
31511fa71b9SJerome Forissier                                    size_t len,
31611fa71b9SJerome Forissier                                    mbedtls_record *rec);
31711fa71b9SJerome Forissier 
31811fa71b9SJerome Forissier int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl,
31911fa71b9SJerome Forissier                              unsigned char *buf,
32011fa71b9SJerome Forissier                              size_t buflen)
32111fa71b9SJerome Forissier {
32211fa71b9SJerome Forissier     int ret = 0;
32311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record"));
32411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen);
32511fa71b9SJerome Forissier 
32611fa71b9SJerome Forissier     /* We don't support record checking in TLS because
32732b31808SJens Wiklander      * there doesn't seem to be a usecase for it.
32811fa71b9SJerome Forissier      */
32932b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
33011fa71b9SJerome Forissier         ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
33111fa71b9SJerome Forissier         goto exit;
33211fa71b9SJerome Forissier     }
33311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
33432b31808SJens Wiklander     else {
33511fa71b9SJerome Forissier         mbedtls_record rec;
33611fa71b9SJerome Forissier 
33711fa71b9SJerome Forissier         ret = ssl_parse_record_header(ssl, buf, buflen, &rec);
33832b31808SJens Wiklander         if (ret != 0) {
33911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret);
34011fa71b9SJerome Forissier             goto exit;
34111fa71b9SJerome Forissier         }
34211fa71b9SJerome Forissier 
34332b31808SJens Wiklander         if (ssl->transform_in != NULL) {
34411fa71b9SJerome Forissier             ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec);
34532b31808SJens Wiklander             if (ret != 0) {
34611fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret);
34711fa71b9SJerome Forissier                 goto exit;
34811fa71b9SJerome Forissier             }
34911fa71b9SJerome Forissier         }
35011fa71b9SJerome Forissier     }
35111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
35211fa71b9SJerome Forissier 
35311fa71b9SJerome Forissier exit:
35411fa71b9SJerome Forissier     /* On success, we have decrypted the buffer in-place, so make
35511fa71b9SJerome Forissier      * sure we don't leak any plaintext data. */
35611fa71b9SJerome Forissier     mbedtls_platform_zeroize(buf, buflen);
35711fa71b9SJerome Forissier 
35811fa71b9SJerome Forissier     /* For the purpose of this API, treat messages with unexpected CID
35911fa71b9SJerome Forissier      * as well as such from future epochs as unexpected. */
36011fa71b9SJerome Forissier     if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
36132b31808SJens Wiklander         ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
36211fa71b9SJerome Forissier         ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
36311fa71b9SJerome Forissier     }
36411fa71b9SJerome Forissier 
36511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record"));
36632b31808SJens Wiklander     return ret;
36711fa71b9SJerome Forissier }
36811fa71b9SJerome Forissier 
36911fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0
37011fa71b9SJerome Forissier #define SSL_FORCE_FLUSH      1
37111fa71b9SJerome Forissier 
37211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
37311fa71b9SJerome Forissier 
37411fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */
37511fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
37611fa71b9SJerome Forissier                                     uint8_t slot);
37711fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl);
378039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
37911fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl);
380039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38111fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl);
382039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38311fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl);
384039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38511fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
38611fa71b9SJerome Forissier                                     mbedtls_record const *rec);
387039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38811fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl);
38911fa71b9SJerome Forissier 
39011fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl)
39111fa71b9SJerome Forissier {
39211fa71b9SJerome Forissier     size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
39311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
39411fa71b9SJerome Forissier     size_t out_buf_len = ssl->out_buf_len;
39511fa71b9SJerome Forissier #else
39611fa71b9SJerome Forissier     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
39711fa71b9SJerome Forissier #endif
39811fa71b9SJerome Forissier 
39932b31808SJens Wiklander     if (mtu != 0 && mtu < out_buf_len) {
40032b31808SJens Wiklander         return mtu;
40132b31808SJens Wiklander     }
40211fa71b9SJerome Forissier 
40332b31808SJens Wiklander     return out_buf_len;
40411fa71b9SJerome Forissier }
40511fa71b9SJerome Forissier 
406039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
40711fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl)
40811fa71b9SJerome Forissier {
40911fa71b9SJerome Forissier     size_t const bytes_written = ssl->out_left;
41011fa71b9SJerome Forissier     size_t const mtu           = ssl_get_maximum_datagram_size(ssl);
41111fa71b9SJerome Forissier 
41211fa71b9SJerome Forissier     /* Double-check that the write-index hasn't gone
41311fa71b9SJerome Forissier      * past what we can transmit in a single datagram. */
41432b31808SJens Wiklander     if (bytes_written > mtu) {
41511fa71b9SJerome Forissier         /* Should never happen... */
41632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
41711fa71b9SJerome Forissier     }
41811fa71b9SJerome Forissier 
41932b31808SJens Wiklander     return (int) (mtu - bytes_written);
42011fa71b9SJerome Forissier }
42111fa71b9SJerome Forissier 
422039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
42311fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl)
42411fa71b9SJerome Forissier {
42511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
42611fa71b9SJerome Forissier     size_t remaining, expansion;
42711fa71b9SJerome Forissier     size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
42811fa71b9SJerome Forissier 
42911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
43011fa71b9SJerome Forissier     const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
43111fa71b9SJerome Forissier 
43232b31808SJens Wiklander     if (max_len > mfl) {
43311fa71b9SJerome Forissier         max_len = mfl;
43432b31808SJens Wiklander     }
43511fa71b9SJerome Forissier 
43611fa71b9SJerome Forissier     /* By the standard (RFC 6066 Sect. 4), the MFL extension
43711fa71b9SJerome Forissier      * only limits the maximum record payload size, so in theory
43811fa71b9SJerome Forissier      * we would be allowed to pack multiple records of payload size
43911fa71b9SJerome Forissier      * MFL into a single datagram. However, this would mean that there's
44011fa71b9SJerome Forissier      * no way to explicitly communicate MTU restrictions to the peer.
44111fa71b9SJerome Forissier      *
44211fa71b9SJerome Forissier      * The following reduction of max_len makes sure that we never
44311fa71b9SJerome Forissier      * write datagrams larger than MFL + Record Expansion Overhead.
44411fa71b9SJerome Forissier      */
44532b31808SJens Wiklander     if (max_len <= ssl->out_left) {
44632b31808SJens Wiklander         return 0;
44732b31808SJens Wiklander     }
44811fa71b9SJerome Forissier 
44911fa71b9SJerome Forissier     max_len -= ssl->out_left;
45011fa71b9SJerome Forissier #endif
45111fa71b9SJerome Forissier 
45211fa71b9SJerome Forissier     ret = ssl_get_remaining_space_in_datagram(ssl);
45332b31808SJens Wiklander     if (ret < 0) {
45432b31808SJens Wiklander         return ret;
45532b31808SJens Wiklander     }
45611fa71b9SJerome Forissier     remaining = (size_t) ret;
45711fa71b9SJerome Forissier 
45811fa71b9SJerome Forissier     ret = mbedtls_ssl_get_record_expansion(ssl);
45932b31808SJens Wiklander     if (ret < 0) {
46032b31808SJens Wiklander         return ret;
46132b31808SJens Wiklander     }
46211fa71b9SJerome Forissier     expansion = (size_t) ret;
46311fa71b9SJerome Forissier 
46432b31808SJens Wiklander     if (remaining <= expansion) {
46532b31808SJens Wiklander         return 0;
46632b31808SJens Wiklander     }
46711fa71b9SJerome Forissier 
46811fa71b9SJerome Forissier     remaining -= expansion;
46932b31808SJens Wiklander     if (remaining >= max_len) {
47011fa71b9SJerome Forissier         remaining = max_len;
47132b31808SJens Wiklander     }
47211fa71b9SJerome Forissier 
47332b31808SJens Wiklander     return (int) remaining;
47411fa71b9SJerome Forissier }
47511fa71b9SJerome Forissier 
47611fa71b9SJerome Forissier /*
47711fa71b9SJerome Forissier  * Double the retransmit timeout value, within the allowed range,
47811fa71b9SJerome Forissier  * returning -1 if the maximum value has already been reached.
47911fa71b9SJerome Forissier  */
480039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
48111fa71b9SJerome Forissier static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl)
48211fa71b9SJerome Forissier {
48311fa71b9SJerome Forissier     uint32_t new_timeout;
48411fa71b9SJerome Forissier 
48532b31808SJens Wiklander     if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max) {
48632b31808SJens Wiklander         return -1;
48732b31808SJens Wiklander     }
48811fa71b9SJerome Forissier 
48911fa71b9SJerome Forissier     /* Implement the final paragraph of RFC 6347 section 4.1.1.1
49011fa71b9SJerome Forissier      * in the following way: after the initial transmission and a first
49111fa71b9SJerome Forissier      * retransmission, back off to a temporary estimated MTU of 508 bytes.
49211fa71b9SJerome Forissier      * This value is guaranteed to be deliverable (if not guaranteed to be
49311fa71b9SJerome Forissier      * delivered) of any compliant IPv4 (and IPv6) network, and should work
49411fa71b9SJerome Forissier      * on most non-IP stacks too. */
49532b31808SJens Wiklander     if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) {
49611fa71b9SJerome Forissier         ssl->handshake->mtu = 508;
49711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes", ssl->handshake->mtu));
49811fa71b9SJerome Forissier     }
49911fa71b9SJerome Forissier 
50011fa71b9SJerome Forissier     new_timeout = 2 * ssl->handshake->retransmit_timeout;
50111fa71b9SJerome Forissier 
50211fa71b9SJerome Forissier     /* Avoid arithmetic overflow and range overflow */
50311fa71b9SJerome Forissier     if (new_timeout < ssl->handshake->retransmit_timeout ||
50432b31808SJens Wiklander         new_timeout > ssl->conf->hs_timeout_max) {
50511fa71b9SJerome Forissier         new_timeout = ssl->conf->hs_timeout_max;
50611fa71b9SJerome Forissier     }
50711fa71b9SJerome Forissier 
50811fa71b9SJerome Forissier     ssl->handshake->retransmit_timeout = new_timeout;
5097901324dSJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
5107901324dSJerome Forissier                               (unsigned long) ssl->handshake->retransmit_timeout));
51111fa71b9SJerome Forissier 
51232b31808SJens Wiklander     return 0;
51311fa71b9SJerome Forissier }
51411fa71b9SJerome Forissier 
51511fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl)
51611fa71b9SJerome Forissier {
51711fa71b9SJerome Forissier     ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
5187901324dSJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
5197901324dSJerome Forissier                               (unsigned long) ssl->handshake->retransmit_timeout));
52011fa71b9SJerome Forissier }
52111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
52211fa71b9SJerome Forissier 
52311fa71b9SJerome Forissier /*
52411fa71b9SJerome Forissier  * Encryption/decryption functions
52511fa71b9SJerome Forissier  */
52611fa71b9SJerome Forissier 
52732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
5287901324dSJerome Forissier 
5297901324dSJerome Forissier static size_t ssl_compute_padding_length(size_t len,
5307901324dSJerome Forissier                                          size_t granularity)
5317901324dSJerome Forissier {
53232b31808SJens Wiklander     return (granularity - (len + 1) % granularity) % granularity;
5337901324dSJerome Forissier }
5347901324dSJerome Forissier 
5357901324dSJerome Forissier /* This functions transforms a (D)TLS plaintext fragment and a record content
5367901324dSJerome Forissier  * type into an instance of the (D)TLSInnerPlaintext structure. This is used
5377901324dSJerome Forissier  * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
5387901324dSJerome Forissier  * a record's content type.
53911fa71b9SJerome Forissier  *
54011fa71b9SJerome Forissier  *        struct {
54111fa71b9SJerome Forissier  *            opaque content[DTLSPlaintext.length];
54211fa71b9SJerome Forissier  *            ContentType real_type;
54311fa71b9SJerome Forissier  *            uint8 zeros[length_of_padding];
5447901324dSJerome Forissier  *        } (D)TLSInnerPlaintext;
54511fa71b9SJerome Forissier  *
54611fa71b9SJerome Forissier  *  Input:
54711fa71b9SJerome Forissier  *  - `content`: The beginning of the buffer holding the
54811fa71b9SJerome Forissier  *               plaintext to be wrapped.
54911fa71b9SJerome Forissier  *  - `*content_size`: The length of the plaintext in Bytes.
55011fa71b9SJerome Forissier  *  - `max_len`: The number of Bytes available starting from
55111fa71b9SJerome Forissier  *               `content`. This must be `>= *content_size`.
55211fa71b9SJerome Forissier  *  - `rec_type`: The desired record content type.
55311fa71b9SJerome Forissier  *
55411fa71b9SJerome Forissier  *  Output:
5557901324dSJerome Forissier  *  - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
5567901324dSJerome Forissier  *  - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
55711fa71b9SJerome Forissier  *
55811fa71b9SJerome Forissier  *  Returns:
55911fa71b9SJerome Forissier  *  - `0` on success.
56011fa71b9SJerome Forissier  *  - A negative error code if `max_len` didn't offer enough space
56111fa71b9SJerome Forissier  *    for the expansion.
56211fa71b9SJerome Forissier  */
563039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
5647901324dSJerome Forissier static int ssl_build_inner_plaintext(unsigned char *content,
56511fa71b9SJerome Forissier                                      size_t *content_size,
56611fa71b9SJerome Forissier                                      size_t remaining,
5677901324dSJerome Forissier                                      uint8_t rec_type,
5687901324dSJerome Forissier                                      size_t pad)
56911fa71b9SJerome Forissier {
57011fa71b9SJerome Forissier     size_t len = *content_size;
57111fa71b9SJerome Forissier 
57211fa71b9SJerome Forissier     /* Write real content type */
57332b31808SJens Wiklander     if (remaining == 0) {
57432b31808SJens Wiklander         return -1;
57532b31808SJens Wiklander     }
57611fa71b9SJerome Forissier     content[len] = rec_type;
57711fa71b9SJerome Forissier     len++;
57811fa71b9SJerome Forissier     remaining--;
57911fa71b9SJerome Forissier 
58032b31808SJens Wiklander     if (remaining < pad) {
58132b31808SJens Wiklander         return -1;
58232b31808SJens Wiklander     }
58311fa71b9SJerome Forissier     memset(content + len, 0, pad);
58411fa71b9SJerome Forissier     len += pad;
58511fa71b9SJerome Forissier     remaining -= pad;
58611fa71b9SJerome Forissier 
58711fa71b9SJerome Forissier     *content_size = len;
58832b31808SJens Wiklander     return 0;
58911fa71b9SJerome Forissier }
59011fa71b9SJerome Forissier 
5917901324dSJerome Forissier /* This function parses a (D)TLSInnerPlaintext structure.
5927901324dSJerome Forissier  * See ssl_build_inner_plaintext() for details. */
593039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
5947901324dSJerome Forissier static int ssl_parse_inner_plaintext(unsigned char const *content,
59511fa71b9SJerome Forissier                                      size_t *content_size,
59611fa71b9SJerome Forissier                                      uint8_t *rec_type)
59711fa71b9SJerome Forissier {
59811fa71b9SJerome Forissier     size_t remaining = *content_size;
59911fa71b9SJerome Forissier 
60011fa71b9SJerome Forissier     /* Determine length of padding by skipping zeroes from the back. */
60132b31808SJens Wiklander     do {
60232b31808SJens Wiklander         if (remaining == 0) {
60332b31808SJens Wiklander             return -1;
60432b31808SJens Wiklander         }
60511fa71b9SJerome Forissier         remaining--;
60611fa71b9SJerome Forissier     } while (content[remaining] == 0);
60711fa71b9SJerome Forissier 
60811fa71b9SJerome Forissier     *content_size = remaining;
60911fa71b9SJerome Forissier     *rec_type = content[remaining];
61011fa71b9SJerome Forissier 
61132b31808SJens Wiklander     return 0;
61211fa71b9SJerome Forissier }
61332b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */
61411fa71b9SJerome Forissier 
61532b31808SJens Wiklander /* The size of the `add_data` structure depends on various
61632b31808SJens Wiklander  * factors, namely
61732b31808SJens Wiklander  *
61832b31808SJens Wiklander  * 1) CID functionality disabled
61932b31808SJens Wiklander  *
62032b31808SJens Wiklander  * additional_data =
62132b31808SJens Wiklander  *    8:                    seq_num +
62232b31808SJens Wiklander  *    1:                       type +
62332b31808SJens Wiklander  *    2:                    version +
62432b31808SJens Wiklander  *    2:  length of inner plaintext +
62532b31808SJens Wiklander  *
62632b31808SJens Wiklander  * size = 13 bytes
62732b31808SJens Wiklander  *
62832b31808SJens Wiklander  * 2) CID functionality based on RFC 9146 enabled
62932b31808SJens Wiklander  *
63032b31808SJens Wiklander  * size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length
63132b31808SJens Wiklander  *      = 23 + CID-length
63232b31808SJens Wiklander  *
63332b31808SJens Wiklander  * 3) CID functionality based on legacy CID version
63432b31808SJens Wiklander     according to draft-ietf-tls-dtls-connection-id-05
63532b31808SJens Wiklander  *  https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
63632b31808SJens Wiklander  *
63732b31808SJens Wiklander  * size = 13 + 1 + CID-length
63832b31808SJens Wiklander  *
63932b31808SJens Wiklander  * More information about the CID usage:
64032b31808SJens Wiklander  *
64132b31808SJens Wiklander  * Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the
64232b31808SJens Wiklander  * size of the additional data structure is calculated as:
64332b31808SJens Wiklander  *
64432b31808SJens Wiklander  * additional_data =
64532b31808SJens Wiklander  *    8:                    seq_num +
64632b31808SJens Wiklander  *    1:                  tls12_cid +
64732b31808SJens Wiklander  *    2:     DTLSCipherText.version +
64832b31808SJens Wiklander  *    n:                        cid +
64932b31808SJens Wiklander  *    1:                 cid_length +
65032b31808SJens Wiklander  *    2: length_of_DTLSInnerPlaintext
65132b31808SJens Wiklander  *
65232b31808SJens Wiklander  * Per RFC 9146 the size of the add_data structure is calculated as:
65332b31808SJens Wiklander  *
65432b31808SJens Wiklander  * additional_data =
65532b31808SJens Wiklander  *    8:        seq_num_placeholder +
65632b31808SJens Wiklander  *    1:                  tls12_cid +
65732b31808SJens Wiklander  *    1:                 cid_length +
65832b31808SJens Wiklander  *    1:                  tls12_cid +
65932b31808SJens Wiklander  *    2:     DTLSCiphertext.version +
66032b31808SJens Wiklander  *    2:                      epoch +
66132b31808SJens Wiklander  *    6:            sequence_number +
66232b31808SJens Wiklander  *    n:                        cid +
66332b31808SJens Wiklander  *    2: length_of_DTLSInnerPlaintext
66432b31808SJens Wiklander  *
66532b31808SJens Wiklander  */
66611fa71b9SJerome Forissier static void ssl_extract_add_data_from_record(unsigned char *add_data,
66711fa71b9SJerome Forissier                                              size_t *add_data_len,
6687901324dSJerome Forissier                                              mbedtls_record *rec,
66932b31808SJens Wiklander                                              mbedtls_ssl_protocol_version
67032b31808SJens Wiklander                                              tls_version,
67132b31808SJens Wiklander                                              size_t taglen)
67211fa71b9SJerome Forissier {
67332b31808SJens Wiklander     /* Several types of ciphers have been defined for use with TLS and DTLS,
67432b31808SJens Wiklander      * and the MAC calculations for those ciphers differ slightly. Further
67532b31808SJens Wiklander      * variants were added when the CID functionality was added with RFC 9146.
67632b31808SJens Wiklander      * This implementations also considers the use of a legacy version of the
67732b31808SJens Wiklander      * CID specification published in draft-ietf-tls-dtls-connection-id-05,
67832b31808SJens Wiklander      * which is used in deployments.
67932b31808SJens Wiklander      *
68032b31808SJens Wiklander      * We will distinguish between the non-CID and the CID cases below.
68132b31808SJens Wiklander      *
68232b31808SJens Wiklander      * --- Non-CID cases ---
68332b31808SJens Wiklander      *
68432b31808SJens Wiklander      * Quoting RFC 5246 (TLS 1.2):
68511fa71b9SJerome Forissier      *
68611fa71b9SJerome Forissier      *    additional_data = seq_num + TLSCompressed.type +
68711fa71b9SJerome Forissier      *                      TLSCompressed.version + TLSCompressed.length;
68811fa71b9SJerome Forissier      *
6897901324dSJerome Forissier      * For TLS 1.3, the record sequence number is dropped from the AAD
6907901324dSJerome Forissier      * and encoded within the nonce of the AEAD operation instead.
69132b31808SJens Wiklander      * Moreover, the additional data involves the length of the TLS
69232b31808SJens Wiklander      * ciphertext, not the TLS plaintext as in earlier versions.
69332b31808SJens Wiklander      * Quoting RFC 8446 (TLS 1.3):
69432b31808SJens Wiklander      *
69532b31808SJens Wiklander      *      additional_data = TLSCiphertext.opaque_type ||
69632b31808SJens Wiklander      *                        TLSCiphertext.legacy_record_version ||
69732b31808SJens Wiklander      *                        TLSCiphertext.length
69832b31808SJens Wiklander      *
69932b31808SJens Wiklander      * We pass the tag length to this function in order to compute the
70032b31808SJens Wiklander      * ciphertext length from the inner plaintext length rec->data_len via
70132b31808SJens Wiklander      *
70232b31808SJens Wiklander      *     TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
70332b31808SJens Wiklander      *
70432b31808SJens Wiklander      * --- CID cases ---
70532b31808SJens Wiklander      *
70632b31808SJens Wiklander      * RFC 9146 uses a common pattern when constructing the data
70732b31808SJens Wiklander      * passed into a MAC / AEAD cipher.
70832b31808SJens Wiklander      *
70932b31808SJens Wiklander      * Data concatenation for MACs used with block ciphers with
71032b31808SJens Wiklander      * Encrypt-then-MAC Processing (with CID):
71132b31808SJens Wiklander      *
71232b31808SJens Wiklander      *  data = seq_num_placeholder +
71332b31808SJens Wiklander      *         tls12_cid +
71432b31808SJens Wiklander      *         cid_length +
71532b31808SJens Wiklander      *         tls12_cid +
71632b31808SJens Wiklander      *         DTLSCiphertext.version +
71732b31808SJens Wiklander      *         epoch +
71832b31808SJens Wiklander      *         sequence_number +
71932b31808SJens Wiklander      *         cid +
72032b31808SJens Wiklander      *         DTLSCiphertext.length +
72132b31808SJens Wiklander      *         IV +
72232b31808SJens Wiklander      *         ENC(content + padding + padding_length)
72332b31808SJens Wiklander      *
72432b31808SJens Wiklander      * Data concatenation for MACs used with block ciphers (with CID):
72532b31808SJens Wiklander      *
72632b31808SJens Wiklander      *  data =  seq_num_placeholder +
72732b31808SJens Wiklander      *          tls12_cid +
72832b31808SJens Wiklander      *          cid_length +
72932b31808SJens Wiklander      *          tls12_cid +
73032b31808SJens Wiklander      *          DTLSCiphertext.version +
73132b31808SJens Wiklander      *          epoch +
73232b31808SJens Wiklander      *          sequence_number +
73332b31808SJens Wiklander      *          cid +
73432b31808SJens Wiklander      *          length_of_DTLSInnerPlaintext +
73532b31808SJens Wiklander      *          DTLSInnerPlaintext.content +
73632b31808SJens Wiklander      *          DTLSInnerPlaintext.real_type +
73732b31808SJens Wiklander      *          DTLSInnerPlaintext.zeros
73832b31808SJens Wiklander      *
73932b31808SJens Wiklander      * AEAD ciphers use the following additional data calculation (with CIDs):
74032b31808SJens Wiklander      *
74132b31808SJens Wiklander      *     additional_data = seq_num_placeholder +
74232b31808SJens Wiklander      *                tls12_cid +
74332b31808SJens Wiklander      *                cid_length +
74432b31808SJens Wiklander      *                tls12_cid +
74532b31808SJens Wiklander      *                DTLSCiphertext.version +
74632b31808SJens Wiklander      *                epoch +
74732b31808SJens Wiklander      *                sequence_number +
74832b31808SJens Wiklander      *                cid +
74932b31808SJens Wiklander      *                length_of_DTLSInnerPlaintext
75032b31808SJens Wiklander      *
75132b31808SJens Wiklander      * Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use)
75232b31808SJens Wiklander      * defines the additional data calculation as follows:
75332b31808SJens Wiklander      *
75432b31808SJens Wiklander      *     additional_data = seq_num +
75532b31808SJens Wiklander      *                tls12_cid +
75632b31808SJens Wiklander      *                DTLSCipherText.version +
75732b31808SJens Wiklander      *                cid +
75832b31808SJens Wiklander      *                cid_length +
75932b31808SJens Wiklander      *                length_of_DTLSInnerPlaintext
76011fa71b9SJerome Forissier      */
76111fa71b9SJerome Forissier 
7627901324dSJerome Forissier     unsigned char *cur = add_data;
76332b31808SJens Wiklander     size_t ad_len_field = rec->data_len;
7647901324dSJerome Forissier 
76532b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
76632b31808SJens Wiklander     MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
76732b31808SJens Wiklander     const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
76832b31808SJens Wiklander #endif
76932b31808SJens Wiklander 
77032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
77132b31808SJens Wiklander     if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
77232b31808SJens Wiklander         /* In TLS 1.3, the AAD contains the length of the TLSCiphertext,
77332b31808SJens Wiklander          * which differs from the length of the TLSInnerPlaintext
77432b31808SJens Wiklander          * by the length of the authentication tag. */
77532b31808SJens Wiklander         ad_len_field += taglen;
77632b31808SJens Wiklander     } else
77732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
7787901324dSJerome Forissier     {
77932b31808SJens Wiklander         ((void) tls_version);
78032b31808SJens Wiklander         ((void) taglen);
7817901324dSJerome Forissier 
78232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
78332b31808SJens Wiklander         MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
78432b31808SJens Wiklander         if (rec->cid_len != 0) {
78532b31808SJens Wiklander             // seq_num_placeholder
78632b31808SJens Wiklander             memcpy(cur, seq_num_placeholder, sizeof(seq_num_placeholder));
78732b31808SJens Wiklander             cur += sizeof(seq_num_placeholder);
78832b31808SJens Wiklander 
78932b31808SJens Wiklander             // tls12_cid type
7907901324dSJerome Forissier             *cur = rec->type;
7917901324dSJerome Forissier             cur++;
7927901324dSJerome Forissier 
79332b31808SJens Wiklander             // cid_length
79432b31808SJens Wiklander             *cur = rec->cid_len;
79532b31808SJens Wiklander             cur++;
79632b31808SJens Wiklander         } else
79732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
79832b31808SJens Wiklander         {
79932b31808SJens Wiklander             // epoch + sequence number
80032b31808SJens Wiklander             memcpy(cur, rec->ctr, sizeof(rec->ctr));
80132b31808SJens Wiklander             cur += sizeof(rec->ctr);
80232b31808SJens Wiklander         }
80332b31808SJens Wiklander     }
80432b31808SJens Wiklander 
80532b31808SJens Wiklander     // type
80632b31808SJens Wiklander     *cur = rec->type;
80732b31808SJens Wiklander     cur++;
80832b31808SJens Wiklander 
80932b31808SJens Wiklander     // version
8107901324dSJerome Forissier     memcpy(cur, rec->ver, sizeof(rec->ver));
8117901324dSJerome Forissier     cur += sizeof(rec->ver);
81211fa71b9SJerome Forissier 
81332b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
81432b31808SJens Wiklander     MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1
81532b31808SJens Wiklander 
81632b31808SJens Wiklander     if (rec->cid_len != 0) {
81732b31808SJens Wiklander         // CID
8187901324dSJerome Forissier         memcpy(cur, rec->cid, rec->cid_len);
8197901324dSJerome Forissier         cur += rec->cid_len;
8207901324dSJerome Forissier 
82132b31808SJens Wiklander         // cid_length
8227901324dSJerome Forissier         *cur = rec->cid_len;
8237901324dSJerome Forissier         cur++;
8247901324dSJerome Forissier 
82532b31808SJens Wiklander         // length of inner plaintext
82632b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
8277901324dSJerome Forissier         cur += 2;
82832b31808SJens Wiklander     } else
82932b31808SJens Wiklander #elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
83032b31808SJens Wiklander     MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
83132b31808SJens Wiklander 
83232b31808SJens Wiklander     if (rec->cid_len != 0) {
83332b31808SJens Wiklander         // epoch + sequence number
83432b31808SJens Wiklander         memcpy(cur, rec->ctr, sizeof(rec->ctr));
83532b31808SJens Wiklander         cur += sizeof(rec->ctr);
83632b31808SJens Wiklander 
83732b31808SJens Wiklander         // CID
83832b31808SJens Wiklander         memcpy(cur, rec->cid, rec->cid_len);
83932b31808SJens Wiklander         cur += rec->cid_len;
84032b31808SJens Wiklander 
84132b31808SJens Wiklander         // length of inner plaintext
84232b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
84332b31808SJens Wiklander         cur += 2;
84432b31808SJens Wiklander     } else
84511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
84611fa71b9SJerome Forissier     {
84732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
8487901324dSJerome Forissier         cur += 2;
84911fa71b9SJerome Forissier     }
8507901324dSJerome Forissier 
851b0563631STom Van Eyck     *add_data_len = (size_t) (cur - add_data);
85211fa71b9SJerome Forissier }
85311fa71b9SJerome Forissier 
854b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
855039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
8567901324dSJerome Forissier static int ssl_transform_aead_dynamic_iv_is_explicit(
8577901324dSJerome Forissier     mbedtls_ssl_transform const *transform)
8587901324dSJerome Forissier {
85932b31808SJens Wiklander     return transform->ivlen != transform->fixed_ivlen;
8607901324dSJerome Forissier }
8617901324dSJerome Forissier 
8627901324dSJerome Forissier /* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
8637901324dSJerome Forissier  *
8647901324dSJerome Forissier  * Concretely, this occurs in two variants:
8657901324dSJerome Forissier  *
8667901324dSJerome Forissier  * a) Fixed and dynamic IV lengths add up to total IV length, giving
8677901324dSJerome Forissier  *       IV = fixed_iv || dynamic_iv
8687901324dSJerome Forissier  *
8697901324dSJerome Forissier  *    This variant is used in TLS 1.2 when used with GCM or CCM.
8707901324dSJerome Forissier  *
8717901324dSJerome Forissier  * b) Fixed IV lengths matches total IV length, giving
8727901324dSJerome Forissier  *       IV = fixed_iv XOR ( 0 || dynamic_iv )
8737901324dSJerome Forissier  *
8747901324dSJerome Forissier  *    This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
8757901324dSJerome Forissier  *
8767901324dSJerome Forissier  * See also the documentation of mbedtls_ssl_transform.
8777901324dSJerome Forissier  *
8787901324dSJerome Forissier  * This function has the precondition that
8797901324dSJerome Forissier  *
8807901324dSJerome Forissier  *     dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
8817901324dSJerome Forissier  *
8827901324dSJerome Forissier  * which has to be ensured by the caller. If this precondition
8837901324dSJerome Forissier  * violated, the behavior of this function is undefined.
8847901324dSJerome Forissier  */
8857901324dSJerome Forissier static void ssl_build_record_nonce(unsigned char *dst_iv,
8867901324dSJerome Forissier                                    size_t dst_iv_len,
8877901324dSJerome Forissier                                    unsigned char const *fixed_iv,
8887901324dSJerome Forissier                                    size_t fixed_iv_len,
8897901324dSJerome Forissier                                    unsigned char const *dynamic_iv,
8907901324dSJerome Forissier                                    size_t dynamic_iv_len)
8917901324dSJerome Forissier {
8927901324dSJerome Forissier     /* Start with Fixed IV || 0 */
8937901324dSJerome Forissier     memset(dst_iv, 0, dst_iv_len);
8947901324dSJerome Forissier     memcpy(dst_iv, fixed_iv, fixed_iv_len);
8957901324dSJerome Forissier 
8967901324dSJerome Forissier     dst_iv += dst_iv_len - dynamic_iv_len;
89732b31808SJens Wiklander     mbedtls_xor(dst_iv, dst_iv, dynamic_iv, dynamic_iv_len);
8987901324dSJerome Forissier }
899b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
9007901324dSJerome Forissier 
90111fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
90211fa71b9SJerome Forissier                             mbedtls_ssl_transform *transform,
90311fa71b9SJerome Forissier                             mbedtls_record *rec,
90411fa71b9SJerome Forissier                             int (*f_rng)(void *, unsigned char *, size_t),
90511fa71b9SJerome Forissier                             void *p_rng)
90611fa71b9SJerome Forissier {
90732b31808SJens Wiklander     mbedtls_ssl_mode_t ssl_mode;
90811fa71b9SJerome Forissier     int auth_done = 0;
90911fa71b9SJerome Forissier     unsigned char *data;
91032b31808SJens Wiklander     /* For an explanation of the additional data length see
91132b31808SJens Wiklander      * the description of ssl_extract_add_data_from_record().
91232b31808SJens Wiklander      */
91332b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
91432b31808SJens Wiklander     unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
91532b31808SJens Wiklander #else
91632b31808SJens Wiklander     unsigned char add_data[13];
91732b31808SJens Wiklander #endif
91811fa71b9SJerome Forissier     size_t add_data_len;
91911fa71b9SJerome Forissier     size_t post_avail;
92011fa71b9SJerome Forissier 
92111fa71b9SJerome Forissier     /* The SSL context is only used for debugging purposes! */
92211fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
92311fa71b9SJerome Forissier     ssl = NULL; /* make sure we don't use it except for debug */
92411fa71b9SJerome Forissier     ((void) ssl);
92511fa71b9SJerome Forissier #endif
92611fa71b9SJerome Forissier 
92711fa71b9SJerome Forissier     /* The PRNG is used for dynamic IV generation that's used
92832b31808SJens Wiklander      * for CBC transformations in TLS 1.2. */
9297901324dSJerome Forissier #if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
93032b31808SJens Wiklander     defined(MBEDTLS_SSL_PROTO_TLS1_2))
93111fa71b9SJerome Forissier     ((void) f_rng);
93211fa71b9SJerome Forissier     ((void) p_rng);
93311fa71b9SJerome Forissier #endif
93411fa71b9SJerome Forissier 
93511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf"));
93611fa71b9SJerome Forissier 
93732b31808SJens Wiklander     if (transform == NULL) {
93811fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf"));
93932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
94011fa71b9SJerome Forissier     }
94111fa71b9SJerome Forissier     if (rec == NULL
94211fa71b9SJerome Forissier         || rec->buf == NULL
94311fa71b9SJerome Forissier         || rec->buf_len < rec->data_offset
94411fa71b9SJerome Forissier         || rec->buf_len - rec->data_offset < rec->data_len
94511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
94611fa71b9SJerome Forissier         || rec->cid_len != 0
94711fa71b9SJerome Forissier #endif
94832b31808SJens Wiklander         ) {
94911fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to encrypt_buf"));
95032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
95111fa71b9SJerome Forissier     }
95211fa71b9SJerome Forissier 
95332b31808SJens Wiklander     ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
95432b31808SJens Wiklander 
95511fa71b9SJerome Forissier     data = rec->buf + rec->data_offset;
95611fa71b9SJerome Forissier     post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
95711fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload",
95811fa71b9SJerome Forissier                           data, rec->data_len);
95911fa71b9SJerome Forissier 
96032b31808SJens Wiklander     if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
9617901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET
9627901324dSJerome Forissier                                   " too large, maximum %" MBEDTLS_PRINTF_SIZET,
9637901324dSJerome Forissier                                   rec->data_len,
9647901324dSJerome Forissier                                   (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
96532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
96611fa71b9SJerome Forissier     }
96711fa71b9SJerome Forissier 
9687901324dSJerome Forissier     /* The following two code paths implement the (D)TLSInnerPlaintext
9697901324dSJerome Forissier      * structure present in TLS 1.3 and DTLS 1.2 + CID.
9707901324dSJerome Forissier      *
9717901324dSJerome Forissier      * See ssl_build_inner_plaintext() for more information.
9727901324dSJerome Forissier      *
9737901324dSJerome Forissier      * Note that this changes `rec->data_len`, and hence
9747901324dSJerome Forissier      * `post_avail` needs to be recalculated afterwards.
9757901324dSJerome Forissier      *
9767901324dSJerome Forissier      * Note also that the two code paths cannot occur simultaneously
9777901324dSJerome Forissier      * since they apply to different versions of the protocol. There
9787901324dSJerome Forissier      * is hence no risk of double-addition of the inner plaintext.
9797901324dSJerome Forissier      */
98032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
98132b31808SJens Wiklander     if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
9827901324dSJerome Forissier         size_t padding =
9837901324dSJerome Forissier             ssl_compute_padding_length(rec->data_len,
98432b31808SJens Wiklander                                        MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
9857901324dSJerome Forissier         if (ssl_build_inner_plaintext(data,
9867901324dSJerome Forissier                                       &rec->data_len,
9877901324dSJerome Forissier                                       post_avail,
9887901324dSJerome Forissier                                       rec->type,
98932b31808SJens Wiklander                                       padding) != 0) {
99032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
9917901324dSJerome Forissier         }
9927901324dSJerome Forissier 
9937901324dSJerome Forissier         rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
9947901324dSJerome Forissier     }
99532b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
9967901324dSJerome Forissier 
99711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
99811fa71b9SJerome Forissier     /*
99911fa71b9SJerome Forissier      * Add CID information
100011fa71b9SJerome Forissier      */
100111fa71b9SJerome Forissier     rec->cid_len = transform->out_cid_len;
100211fa71b9SJerome Forissier     memcpy(rec->cid, transform->out_cid, transform->out_cid_len);
100311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len);
100411fa71b9SJerome Forissier 
100532b31808SJens Wiklander     if (rec->cid_len != 0) {
10067901324dSJerome Forissier         size_t padding =
10077901324dSJerome Forissier             ssl_compute_padding_length(rec->data_len,
100832b31808SJens Wiklander                                        MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
100911fa71b9SJerome Forissier         /*
101011fa71b9SJerome Forissier          * Wrap plaintext into DTLSInnerPlaintext structure.
10117901324dSJerome Forissier          * See ssl_build_inner_plaintext() for more information.
101211fa71b9SJerome Forissier          *
101311fa71b9SJerome Forissier          * Note that this changes `rec->data_len`, and hence
101411fa71b9SJerome Forissier          * `post_avail` needs to be recalculated afterwards.
101511fa71b9SJerome Forissier          */
10167901324dSJerome Forissier         if (ssl_build_inner_plaintext(data,
101711fa71b9SJerome Forissier                                       &rec->data_len,
101811fa71b9SJerome Forissier                                       post_avail,
10197901324dSJerome Forissier                                       rec->type,
102032b31808SJens Wiklander                                       padding) != 0) {
102132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
102211fa71b9SJerome Forissier         }
102311fa71b9SJerome Forissier 
102411fa71b9SJerome Forissier         rec->type = MBEDTLS_SSL_MSG_CID;
102511fa71b9SJerome Forissier     }
102611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
102711fa71b9SJerome Forissier 
102811fa71b9SJerome Forissier     post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
102911fa71b9SJerome Forissier 
103011fa71b9SJerome Forissier     /*
103111fa71b9SJerome Forissier      * Add MAC before if needed
103211fa71b9SJerome Forissier      */
103332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
103432b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_STREAM ||
103532b31808SJens Wiklander         ssl_mode == MBEDTLS_SSL_MODE_CBC) {
103632b31808SJens Wiklander         if (post_avail < transform->maclen) {
103711fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
103832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
103911fa71b9SJerome Forissier         }
104032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
104111fa71b9SJerome Forissier         unsigned char mac[MBEDTLS_SSL_MAC_ADD];
1042039e02dfSJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
104332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
104432b31808SJens Wiklander         psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
104532b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
104632b31808SJens Wiklander         size_t sign_mac_length = 0;
104732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
104811fa71b9SJerome Forissier 
10497901324dSJerome Forissier         ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
105032b31808SJens Wiklander                                          transform->tls_version,
105132b31808SJens Wiklander                                          transform->taglen);
105211fa71b9SJerome Forissier 
105332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
105432b31808SJens Wiklander         status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
105532b31808SJens Wiklander                                     transform->psa_mac_alg);
105632b31808SJens Wiklander         if (status != PSA_SUCCESS) {
1057039e02dfSJerome Forissier             goto hmac_failed_etm_disabled;
105832b31808SJens Wiklander         }
105932b31808SJens Wiklander 
106032b31808SJens Wiklander         status = psa_mac_update(&operation, add_data, add_data_len);
106132b31808SJens Wiklander         if (status != PSA_SUCCESS) {
1062039e02dfSJerome Forissier             goto hmac_failed_etm_disabled;
106332b31808SJens Wiklander         }
106432b31808SJens Wiklander 
106532b31808SJens Wiklander         status = psa_mac_update(&operation, data, rec->data_len);
106632b31808SJens Wiklander         if (status != PSA_SUCCESS) {
106732b31808SJens Wiklander             goto hmac_failed_etm_disabled;
106832b31808SJens Wiklander         }
106932b31808SJens Wiklander 
107032b31808SJens Wiklander         status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
107132b31808SJens Wiklander                                      &sign_mac_length);
107232b31808SJens Wiklander         if (status != PSA_SUCCESS) {
107332b31808SJens Wiklander             goto hmac_failed_etm_disabled;
107432b31808SJens Wiklander         }
107532b31808SJens Wiklander #else
107632b31808SJens Wiklander         ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
107732b31808SJens Wiklander                                      add_data_len);
107832b31808SJens Wiklander         if (ret != 0) {
107932b31808SJens Wiklander             goto hmac_failed_etm_disabled;
108032b31808SJens Wiklander         }
108132b31808SJens Wiklander         ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len);
108232b31808SJens Wiklander         if (ret != 0) {
108332b31808SJens Wiklander             goto hmac_failed_etm_disabled;
108432b31808SJens Wiklander         }
1085039e02dfSJerome Forissier         ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
108632b31808SJens Wiklander         if (ret != 0) {
1087039e02dfSJerome Forissier             goto hmac_failed_etm_disabled;
108832b31808SJens Wiklander         }
1089039e02dfSJerome Forissier         ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
109032b31808SJens Wiklander         if (ret != 0) {
1091039e02dfSJerome Forissier             goto hmac_failed_etm_disabled;
109232b31808SJens Wiklander         }
109332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
109411fa71b9SJerome Forissier 
109511fa71b9SJerome Forissier         memcpy(data + rec->data_len, mac, transform->maclen);
109611fa71b9SJerome Forissier #endif
109711fa71b9SJerome Forissier 
109811fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len,
109911fa71b9SJerome Forissier                               transform->maclen);
110011fa71b9SJerome Forissier 
110111fa71b9SJerome Forissier         rec->data_len += transform->maclen;
110211fa71b9SJerome Forissier         post_avail -= transform->maclen;
110311fa71b9SJerome Forissier         auth_done++;
110432b31808SJens Wiklander 
110532b31808SJens Wiklander hmac_failed_etm_disabled:
110632b31808SJens Wiklander         mbedtls_platform_zeroize(mac, transform->maclen);
110732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
110832b31808SJens Wiklander         ret = PSA_TO_MBEDTLS_ERR(status);
110932b31808SJens Wiklander         status = psa_mac_abort(&operation);
111032b31808SJens Wiklander         if (ret == 0 && status != PSA_SUCCESS) {
111132b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
111211fa71b9SJerome Forissier         }
111332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
111432b31808SJens Wiklander         if (ret != 0) {
111532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_hmac_xxx", ret);
111632b31808SJens Wiklander             return ret;
111732b31808SJens Wiklander         }
111832b31808SJens Wiklander     }
111932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
112011fa71b9SJerome Forissier 
112111fa71b9SJerome Forissier     /*
112211fa71b9SJerome Forissier      * Encrypt
112311fa71b9SJerome Forissier      */
112432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
112532b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
11267901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
112711fa71b9SJerome Forissier                                                                                     "including %d bytes of padding",
112811fa71b9SJerome Forissier                                   rec->data_len, 0));
112911fa71b9SJerome Forissier 
113032b31808SJens Wiklander         /* The only supported stream cipher is "NULL",
113132b31808SJens Wiklander          * so there's nothing to do here.*/
113232b31808SJens Wiklander     } else
113332b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
113411fa71b9SJerome Forissier 
1135b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
113632b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
113711fa71b9SJerome Forissier         unsigned char iv[12];
11387901324dSJerome Forissier         unsigned char *dynamic_iv;
11397901324dSJerome Forissier         size_t dynamic_iv_len;
11407901324dSJerome Forissier         int dynamic_iv_is_explicit =
11417901324dSJerome Forissier             ssl_transform_aead_dynamic_iv_is_explicit(transform);
114232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
114332b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
114432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
114532b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
114611fa71b9SJerome Forissier 
11477901324dSJerome Forissier         /* Check that there's space for the authentication tag. */
114832b31808SJens Wiklander         if (post_avail < transform->taglen) {
114911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
115032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
115111fa71b9SJerome Forissier         }
115211fa71b9SJerome Forissier 
115311fa71b9SJerome Forissier         /*
11547901324dSJerome Forissier          * Build nonce for AEAD encryption.
11557901324dSJerome Forissier          *
11567901324dSJerome Forissier          * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
11577901324dSJerome Forissier          *       part of the IV is prepended to the ciphertext and
11587901324dSJerome Forissier          *       can be chosen freely - in particular, it need not
11597901324dSJerome Forissier          *       agree with the record sequence number.
11607901324dSJerome Forissier          *       However, since ChaChaPoly as well as all AEAD modes
11617901324dSJerome Forissier          *       in TLS 1.3 use the record sequence number as the
11627901324dSJerome Forissier          *       dynamic part of the nonce, we uniformly use the
11637901324dSJerome Forissier          *       record sequence number here in all cases.
116411fa71b9SJerome Forissier          */
11657901324dSJerome Forissier         dynamic_iv     = rec->ctr;
11667901324dSJerome Forissier         dynamic_iv_len = sizeof(rec->ctr);
116711fa71b9SJerome Forissier 
11687901324dSJerome Forissier         ssl_build_record_nonce(iv, sizeof(iv),
11697901324dSJerome Forissier                                transform->iv_enc,
11707901324dSJerome Forissier                                transform->fixed_ivlen,
11717901324dSJerome Forissier                                dynamic_iv,
11727901324dSJerome Forissier                                dynamic_iv_len);
117311fa71b9SJerome Forissier 
11747901324dSJerome Forissier         /*
11757901324dSJerome Forissier          * Build additional data for AEAD encryption.
11767901324dSJerome Forissier          * This depends on the TLS version.
11777901324dSJerome Forissier          */
11787901324dSJerome Forissier         ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
117932b31808SJens Wiklander                                          transform->tls_version,
118032b31808SJens Wiklander                                          transform->taglen);
118111fa71b9SJerome Forissier 
118211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)",
118311fa71b9SJerome Forissier                               iv, transform->ivlen);
118411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)",
11857901324dSJerome Forissier                               dynamic_iv,
11867901324dSJerome Forissier                               dynamic_iv_is_explicit ? dynamic_iv_len : 0);
118711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
118811fa71b9SJerome Forissier                               add_data, add_data_len);
11897901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
119011fa71b9SJerome Forissier                                                                                     "including 0 bytes of padding",
119111fa71b9SJerome Forissier                                   rec->data_len));
119211fa71b9SJerome Forissier 
119311fa71b9SJerome Forissier         /*
119411fa71b9SJerome Forissier          * Encrypt and authenticate
119511fa71b9SJerome Forissier          */
119632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
119732b31808SJens Wiklander         status = psa_aead_encrypt(transform->psa_key_enc,
119832b31808SJens Wiklander                                   transform->psa_alg,
119932b31808SJens Wiklander                                   iv, transform->ivlen,
120032b31808SJens Wiklander                                   add_data, add_data_len,
120132b31808SJens Wiklander                                   data, rec->data_len,
120232b31808SJens Wiklander                                   data, rec->buf_len - (data - rec->buf),
120332b31808SJens Wiklander                                   &rec->data_len);
120411fa71b9SJerome Forissier 
120532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
120632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
120732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_encrypt_buf", ret);
120832b31808SJens Wiklander             return ret;
120932b31808SJens Wiklander         }
121032b31808SJens Wiklander #else
12117901324dSJerome Forissier         if ((ret = mbedtls_cipher_auth_encrypt_ext(&transform->cipher_ctx_enc,
121211fa71b9SJerome Forissier                                                    iv, transform->ivlen,
12137901324dSJerome Forissier                                                    add_data, add_data_len,
12147901324dSJerome Forissier                                                    data, rec->data_len, /* src */
1215b0563631STom Van Eyck                                                    data, rec->buf_len - (size_t) (data - rec->buf), /* dst */
12167901324dSJerome Forissier                                                    &rec->data_len,
121732b31808SJens Wiklander                                                    transform->taglen)) != 0) {
121832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret);
121932b31808SJens Wiklander             return ret;
122011fa71b9SJerome Forissier         }
122132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
122232b31808SJens Wiklander 
122311fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag",
12247901324dSJerome Forissier                               data + rec->data_len - transform->taglen,
12257901324dSJerome Forissier                               transform->taglen);
12267901324dSJerome Forissier         /* Account for authentication tag. */
122711fa71b9SJerome Forissier         post_avail -= transform->taglen;
12287901324dSJerome Forissier 
12297901324dSJerome Forissier         /*
12307901324dSJerome Forissier          * Prefix record content with dynamic IV in case it is explicit.
12317901324dSJerome Forissier          */
123232b31808SJens Wiklander         if (dynamic_iv_is_explicit != 0) {
123332b31808SJens Wiklander             if (rec->data_offset < dynamic_iv_len) {
12347901324dSJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
123532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
12367901324dSJerome Forissier             }
12377901324dSJerome Forissier 
12387901324dSJerome Forissier             memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len);
12397901324dSJerome Forissier             rec->data_offset -= dynamic_iv_len;
12407901324dSJerome Forissier             rec->data_len    += dynamic_iv_len;
12417901324dSJerome Forissier         }
12427901324dSJerome Forissier 
124311fa71b9SJerome Forissier         auth_done++;
124432b31808SJens Wiklander     } else
1245b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
12467901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
124732b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
124832b31808SJens Wiklander         ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
124911fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
125011fa71b9SJerome Forissier         size_t padlen, i;
125111fa71b9SJerome Forissier         size_t olen;
125232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
125332b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
125432b31808SJens Wiklander         size_t part_len;
125532b31808SJens Wiklander         psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
125632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
125711fa71b9SJerome Forissier 
125811fa71b9SJerome Forissier         /* Currently we're always using minimal padding
125911fa71b9SJerome Forissier          * (up to 255 bytes would be allowed). */
126011fa71b9SJerome Forissier         padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen;
126132b31808SJens Wiklander         if (padlen == transform->ivlen) {
126211fa71b9SJerome Forissier             padlen = 0;
126311fa71b9SJerome Forissier         }
126411fa71b9SJerome Forissier 
126532b31808SJens Wiklander         /* Check there's enough space in the buffer for the padding. */
126632b31808SJens Wiklander         if (post_avail < padlen + 1) {
126732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
126832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
126932b31808SJens Wiklander         }
127032b31808SJens Wiklander 
127132b31808SJens Wiklander         for (i = 0; i <= padlen; i++) {
127211fa71b9SJerome Forissier             data[rec->data_len + i] = (unsigned char) padlen;
127332b31808SJens Wiklander         }
127411fa71b9SJerome Forissier 
127511fa71b9SJerome Forissier         rec->data_len += padlen + 1;
127611fa71b9SJerome Forissier         post_avail -= padlen + 1;
127711fa71b9SJerome Forissier 
127832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
127911fa71b9SJerome Forissier         /*
128032b31808SJens Wiklander          * Prepend per-record IV for block cipher in TLS v1.2 as per
128111fa71b9SJerome Forissier          * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
128211fa71b9SJerome Forissier          */
128332b31808SJens Wiklander         if (f_rng == NULL) {
128411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("No PRNG provided to encrypt_record routine"));
128532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
128611fa71b9SJerome Forissier         }
128711fa71b9SJerome Forissier 
128832b31808SJens Wiklander         if (rec->data_offset < transform->ivlen) {
128911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
129032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
129111fa71b9SJerome Forissier         }
129211fa71b9SJerome Forissier 
129311fa71b9SJerome Forissier         /*
129411fa71b9SJerome Forissier          * Generate IV
129511fa71b9SJerome Forissier          */
129611fa71b9SJerome Forissier         ret = f_rng(p_rng, transform->iv_enc, transform->ivlen);
129732b31808SJens Wiklander         if (ret != 0) {
129832b31808SJens Wiklander             return ret;
129911fa71b9SJerome Forissier         }
130032b31808SJens Wiklander 
130132b31808SJens Wiklander         memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen);
130232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
130311fa71b9SJerome Forissier 
13047901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
130532b31808SJens Wiklander                                                                                     "including %"
130632b31808SJens Wiklander                                   MBEDTLS_PRINTF_SIZET
13077901324dSJerome Forissier                                   " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
130811fa71b9SJerome Forissier                                   rec->data_len, transform->ivlen,
130911fa71b9SJerome Forissier                                   padlen + 1));
131011fa71b9SJerome Forissier 
131132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
131232b31808SJens Wiklander         status = psa_cipher_encrypt_setup(&cipher_op,
131332b31808SJens Wiklander                                           transform->psa_key_enc, transform->psa_alg);
131432b31808SJens Wiklander 
131532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
131632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
131732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_encrypt_setup", ret);
131832b31808SJens Wiklander             return ret;
131932b31808SJens Wiklander         }
132032b31808SJens Wiklander 
132132b31808SJens Wiklander         status = psa_cipher_set_iv(&cipher_op, transform->iv_enc, transform->ivlen);
132232b31808SJens Wiklander 
132332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
132432b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
132532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
132632b31808SJens Wiklander             return ret;
132732b31808SJens Wiklander 
132832b31808SJens Wiklander         }
132932b31808SJens Wiklander 
133032b31808SJens Wiklander         status = psa_cipher_update(&cipher_op,
133132b31808SJens Wiklander                                    data, rec->data_len,
133232b31808SJens Wiklander                                    data, rec->data_len, &olen);
133332b31808SJens Wiklander 
133432b31808SJens Wiklander         if (status != PSA_SUCCESS) {
133532b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
133632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
133732b31808SJens Wiklander             return ret;
133832b31808SJens Wiklander 
133932b31808SJens Wiklander         }
134032b31808SJens Wiklander 
134132b31808SJens Wiklander         status = psa_cipher_finish(&cipher_op,
134232b31808SJens Wiklander                                    data + olen, rec->data_len - olen,
134332b31808SJens Wiklander                                    &part_len);
134432b31808SJens Wiklander 
134532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
134632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
134732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
134832b31808SJens Wiklander             return ret;
134932b31808SJens Wiklander 
135032b31808SJens Wiklander         }
135132b31808SJens Wiklander 
135232b31808SJens Wiklander         olen += part_len;
135332b31808SJens Wiklander #else
135411fa71b9SJerome Forissier         if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_enc,
135511fa71b9SJerome Forissier                                         transform->iv_enc,
135611fa71b9SJerome Forissier                                         transform->ivlen,
135711fa71b9SJerome Forissier                                         data, rec->data_len,
135832b31808SJens Wiklander                                         data, &olen)) != 0) {
135911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
136032b31808SJens Wiklander             return ret;
136111fa71b9SJerome Forissier         }
136232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
136311fa71b9SJerome Forissier 
136432b31808SJens Wiklander         if (rec->data_len != olen) {
136511fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
136632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
136711fa71b9SJerome Forissier         }
136811fa71b9SJerome Forissier 
136911fa71b9SJerome Forissier         data             -= transform->ivlen;
137011fa71b9SJerome Forissier         rec->data_offset -= transform->ivlen;
137111fa71b9SJerome Forissier         rec->data_len    += transform->ivlen;
137211fa71b9SJerome Forissier 
137311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
137432b31808SJens Wiklander         if (auth_done == 0) {
137511fa71b9SJerome Forissier             unsigned char mac[MBEDTLS_SSL_MAC_ADD];
137632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
137732b31808SJens Wiklander             psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
137832b31808SJens Wiklander             size_t sign_mac_length = 0;
137932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
138011fa71b9SJerome Forissier 
138132b31808SJens Wiklander             /* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length))
138211fa71b9SJerome Forissier              */
138311fa71b9SJerome Forissier 
138432b31808SJens Wiklander             if (post_avail < transform->maclen) {
138511fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
138632b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
138711fa71b9SJerome Forissier             }
138811fa71b9SJerome Forissier 
13897901324dSJerome Forissier             ssl_extract_add_data_from_record(add_data, &add_data_len,
139032b31808SJens Wiklander                                              rec, transform->tls_version,
139132b31808SJens Wiklander                                              transform->taglen);
139211fa71b9SJerome Forissier 
139311fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
139411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
139511fa71b9SJerome Forissier                                   add_data_len);
139632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
139732b31808SJens Wiklander             status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
139832b31808SJens Wiklander                                         transform->psa_mac_alg);
139932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
140032b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
140132b31808SJens Wiklander             }
140232b31808SJens Wiklander 
140332b31808SJens Wiklander             status = psa_mac_update(&operation, add_data, add_data_len);
140432b31808SJens Wiklander             if (status != PSA_SUCCESS) {
140532b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
140632b31808SJens Wiklander             }
140732b31808SJens Wiklander 
140832b31808SJens Wiklander             status = psa_mac_update(&operation, data, rec->data_len);
140932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
141032b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
141132b31808SJens Wiklander             }
141232b31808SJens Wiklander 
141332b31808SJens Wiklander             status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
141432b31808SJens Wiklander                                          &sign_mac_length);
141532b31808SJens Wiklander             if (status != PSA_SUCCESS) {
141632b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
141732b31808SJens Wiklander             }
141832b31808SJens Wiklander #else
141911fa71b9SJerome Forissier 
1420039e02dfSJerome Forissier             ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
142111fa71b9SJerome Forissier                                          add_data_len);
142232b31808SJens Wiklander             if (ret != 0) {
1423039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
142432b31808SJens Wiklander             }
1425039e02dfSJerome Forissier             ret = mbedtls_md_hmac_update(&transform->md_ctx_enc,
142611fa71b9SJerome Forissier                                          data, rec->data_len);
142732b31808SJens Wiklander             if (ret != 0) {
1428039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
142932b31808SJens Wiklander             }
1430039e02dfSJerome Forissier             ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
143132b31808SJens Wiklander             if (ret != 0) {
1432039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
143332b31808SJens Wiklander             }
1434039e02dfSJerome Forissier             ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
143532b31808SJens Wiklander             if (ret != 0) {
1436039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
143732b31808SJens Wiklander             }
143832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
143911fa71b9SJerome Forissier 
144011fa71b9SJerome Forissier             memcpy(data + rec->data_len, mac, transform->maclen);
144111fa71b9SJerome Forissier 
144211fa71b9SJerome Forissier             rec->data_len += transform->maclen;
144311fa71b9SJerome Forissier             post_avail -= transform->maclen;
144411fa71b9SJerome Forissier             auth_done++;
1445039e02dfSJerome Forissier 
1446039e02dfSJerome Forissier hmac_failed_etm_enabled:
1447039e02dfSJerome Forissier             mbedtls_platform_zeroize(mac, transform->maclen);
144832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
144932b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
145032b31808SJens Wiklander             status = psa_mac_abort(&operation);
145132b31808SJens Wiklander             if (ret == 0 && status != PSA_SUCCESS) {
145232b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
145332b31808SJens Wiklander             }
145432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
145532b31808SJens Wiklander             if (ret != 0) {
1456039e02dfSJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(1, "HMAC calculation failed", ret);
145732b31808SJens Wiklander                 return ret;
1458039e02dfSJerome Forissier             }
145911fa71b9SJerome Forissier         }
146011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
146132b31808SJens Wiklander     } else
14627901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
146311fa71b9SJerome Forissier     {
146411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
146532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
146611fa71b9SJerome Forissier     }
146711fa71b9SJerome Forissier 
146811fa71b9SJerome Forissier     /* Make extra sure authentication was performed, exactly once */
146932b31808SJens Wiklander     if (auth_done != 1) {
147011fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
147132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
147211fa71b9SJerome Forissier     }
147311fa71b9SJerome Forissier 
147411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf"));
147511fa71b9SJerome Forissier 
147632b31808SJens Wiklander     return 0;
147711fa71b9SJerome Forissier }
147811fa71b9SJerome Forissier 
147911fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
148011fa71b9SJerome Forissier                             mbedtls_ssl_transform *transform,
148111fa71b9SJerome Forissier                             mbedtls_record *rec)
148211fa71b9SJerome Forissier {
1483b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_SSL_HAVE_AEAD)
148411fa71b9SJerome Forissier     size_t olen;
1485b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_SSL_HAVE_AEAD */
148632b31808SJens Wiklander     mbedtls_ssl_mode_t ssl_mode;
148732b31808SJens Wiklander     int ret;
148832b31808SJens Wiklander 
148932b31808SJens Wiklander     int auth_done = 0;
149032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
1491b0563631STom Van Eyck     size_t padlen = 0;
1492b0563631STom Van Eyck     mbedtls_ct_condition_t correct = MBEDTLS_CT_TRUE;
149311fa71b9SJerome Forissier #endif
149411fa71b9SJerome Forissier     unsigned char *data;
149532b31808SJens Wiklander     /* For an explanation of the additional data length see
149632b31808SJens Wiklander      * the description of ssl_extract_add_data_from_record().
149732b31808SJens Wiklander      */
149832b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
149932b31808SJens Wiklander     unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX];
150032b31808SJens Wiklander #else
150132b31808SJens Wiklander     unsigned char add_data[13];
150232b31808SJens Wiklander #endif
150311fa71b9SJerome Forissier     size_t add_data_len;
150411fa71b9SJerome Forissier 
150511fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
150611fa71b9SJerome Forissier     ssl = NULL; /* make sure we don't use it except for debug */
150711fa71b9SJerome Forissier     ((void) ssl);
150811fa71b9SJerome Forissier #endif
150911fa71b9SJerome Forissier 
151011fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf"));
151111fa71b9SJerome Forissier     if (rec == NULL                     ||
151211fa71b9SJerome Forissier         rec->buf == NULL                ||
151311fa71b9SJerome Forissier         rec->buf_len < rec->data_offset ||
151432b31808SJens Wiklander         rec->buf_len - rec->data_offset < rec->data_len) {
151511fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to decrypt_buf"));
151632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
151711fa71b9SJerome Forissier     }
151811fa71b9SJerome Forissier 
151911fa71b9SJerome Forissier     data = rec->buf + rec->data_offset;
152032b31808SJens Wiklander     ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
152111fa71b9SJerome Forissier 
152211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
152311fa71b9SJerome Forissier     /*
152411fa71b9SJerome Forissier      * Match record's CID with incoming CID.
152511fa71b9SJerome Forissier      */
152611fa71b9SJerome Forissier     if (rec->cid_len != transform->in_cid_len ||
152732b31808SJens Wiklander         memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) {
152832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_CID;
152911fa71b9SJerome Forissier     }
153011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
153111fa71b9SJerome Forissier 
153232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
153332b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
1534b0563631STom Van Eyck         if (rec->data_len < transform->maclen) {
1535b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1,
1536b0563631STom Van Eyck                                   ("Record too short for MAC:"
1537b0563631STom Van Eyck                                    " %" MBEDTLS_PRINTF_SIZET " < %" MBEDTLS_PRINTF_SIZET,
1538b0563631STom Van Eyck                                    rec->data_len, transform->maclen));
1539b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_INVALID_MAC;
1540b0563631STom Van Eyck         }
1541b0563631STom Van Eyck 
154232b31808SJens Wiklander         /* The only supported stream cipher is "NULL",
1543b0563631STom Van Eyck          * so there's no encryption to do here.*/
154432b31808SJens Wiklander     } else
154532b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
1546b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
154732b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
154811fa71b9SJerome Forissier         unsigned char iv[12];
15497901324dSJerome Forissier         unsigned char *dynamic_iv;
15507901324dSJerome Forissier         size_t dynamic_iv_len;
155132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
155232b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
155332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
155411fa71b9SJerome Forissier 
155511fa71b9SJerome Forissier         /*
15567901324dSJerome Forissier          * Extract dynamic part of nonce for AEAD decryption.
15577901324dSJerome Forissier          *
15587901324dSJerome Forissier          * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
15597901324dSJerome Forissier          *       part of the IV is prepended to the ciphertext and
15607901324dSJerome Forissier          *       can be chosen freely - in particular, it need not
15617901324dSJerome Forissier          *       agree with the record sequence number.
156211fa71b9SJerome Forissier          */
15637901324dSJerome Forissier         dynamic_iv_len = sizeof(rec->ctr);
156432b31808SJens Wiklander         if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) {
156532b31808SJens Wiklander             if (rec->data_len < dynamic_iv_len) {
15667901324dSJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
15677901324dSJerome Forissier                                           " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
15687901324dSJerome Forissier                                           rec->data_len,
15697901324dSJerome Forissier                                           dynamic_iv_len));
157032b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INVALID_MAC;
157111fa71b9SJerome Forissier             }
15727901324dSJerome Forissier             dynamic_iv = data;
157311fa71b9SJerome Forissier 
15747901324dSJerome Forissier             data += dynamic_iv_len;
15757901324dSJerome Forissier             rec->data_offset += dynamic_iv_len;
15767901324dSJerome Forissier             rec->data_len    -= dynamic_iv_len;
157732b31808SJens Wiklander         } else {
15787901324dSJerome Forissier             dynamic_iv = rec->ctr;
157911fa71b9SJerome Forissier         }
158011fa71b9SJerome Forissier 
15817901324dSJerome Forissier         /* Check that there's space for the authentication tag. */
158232b31808SJens Wiklander         if (rec->data_len < transform->taglen) {
15837901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
15847901324dSJerome Forissier                                       ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
15857901324dSJerome Forissier                                       rec->data_len,
15867901324dSJerome Forissier                                       transform->taglen));
158732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_MAC;
15887901324dSJerome Forissier         }
15897901324dSJerome Forissier         rec->data_len -= transform->taglen;
159011fa71b9SJerome Forissier 
15917901324dSJerome Forissier         /*
15927901324dSJerome Forissier          * Prepare nonce from dynamic and static parts.
15937901324dSJerome Forissier          */
15947901324dSJerome Forissier         ssl_build_record_nonce(iv, sizeof(iv),
15957901324dSJerome Forissier                                transform->iv_dec,
15967901324dSJerome Forissier                                transform->fixed_ivlen,
15977901324dSJerome Forissier                                dynamic_iv,
15987901324dSJerome Forissier                                dynamic_iv_len);
15997901324dSJerome Forissier 
16007901324dSJerome Forissier         /*
16017901324dSJerome Forissier          * Build additional data for AEAD encryption.
16027901324dSJerome Forissier          * This depends on the TLS version.
16037901324dSJerome Forissier          */
16047901324dSJerome Forissier         ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
160532b31808SJens Wiklander                                          transform->tls_version,
160632b31808SJens Wiklander                                          transform->taglen);
160711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
160811fa71b9SJerome Forissier                               add_data, add_data_len);
160911fa71b9SJerome Forissier 
161011fa71b9SJerome Forissier         /* Because of the check above, we know that there are
1611039e02dfSJerome Forissier          * explicit_iv_len Bytes preceding data, and taglen
161211fa71b9SJerome Forissier          * bytes following data + data_len. This justifies
161311fa71b9SJerome Forissier          * the debug message and the invocation of
161432b31808SJens Wiklander          * mbedtls_cipher_auth_decrypt_ext() below. */
161511fa71b9SJerome Forissier 
161611fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen);
161711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len,
161811fa71b9SJerome Forissier                               transform->taglen);
161911fa71b9SJerome Forissier 
162011fa71b9SJerome Forissier         /*
162111fa71b9SJerome Forissier          * Decrypt and authenticate
162211fa71b9SJerome Forissier          */
162332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
162432b31808SJens Wiklander         status = psa_aead_decrypt(transform->psa_key_dec,
162532b31808SJens Wiklander                                   transform->psa_alg,
162632b31808SJens Wiklander                                   iv, transform->ivlen,
162732b31808SJens Wiklander                                   add_data, add_data_len,
162832b31808SJens Wiklander                                   data, rec->data_len + transform->taglen,
162932b31808SJens Wiklander                                   data, rec->buf_len - (data - rec->buf),
163032b31808SJens Wiklander                                   &olen);
163132b31808SJens Wiklander 
163232b31808SJens Wiklander         if (status != PSA_SUCCESS) {
163332b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
163432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_aead_decrypt", ret);
163532b31808SJens Wiklander             return ret;
163632b31808SJens Wiklander         }
163732b31808SJens Wiklander #else
1638b0563631STom Van Eyck         if ((ret = mbedtls_cipher_auth_decrypt_ext
1639b0563631STom Van Eyck                        (&transform->cipher_ctx_dec,
164011fa71b9SJerome Forissier                        iv, transform->ivlen,
164111fa71b9SJerome Forissier                        add_data, add_data_len,
16427901324dSJerome Forissier                        data, rec->data_len + transform->taglen, /* src */
1643b0563631STom Van Eyck                        data, rec->buf_len - (size_t) (data - rec->buf), &olen, /* dst */
164432b31808SJens Wiklander                        transform->taglen)) != 0) {
164532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret);
164611fa71b9SJerome Forissier 
164732b31808SJens Wiklander             if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
164832b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INVALID_MAC;
164911fa71b9SJerome Forissier             }
165032b31808SJens Wiklander 
165132b31808SJens Wiklander             return ret;
165232b31808SJens Wiklander         }
165332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
165432b31808SJens Wiklander 
165511fa71b9SJerome Forissier         auth_done++;
165611fa71b9SJerome Forissier 
165711fa71b9SJerome Forissier         /* Double-check that AEAD decryption doesn't change content length. */
165832b31808SJens Wiklander         if (olen != rec->data_len) {
165911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
166032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
166111fa71b9SJerome Forissier         }
166232b31808SJens Wiklander     } else
1663b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
16647901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
166532b31808SJens Wiklander     if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
166632b31808SJens Wiklander         ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
166711fa71b9SJerome Forissier         size_t minlen = 0;
166832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
166932b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
167032b31808SJens Wiklander         size_t part_len;
167132b31808SJens Wiklander         psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
167232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
167311fa71b9SJerome Forissier 
167411fa71b9SJerome Forissier         /*
167511fa71b9SJerome Forissier          * Check immediate ciphertext sanity
167611fa71b9SJerome Forissier          */
167732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
167811fa71b9SJerome Forissier         /* The ciphertext is prefixed with the CBC IV. */
167911fa71b9SJerome Forissier         minlen += transform->ivlen;
168011fa71b9SJerome Forissier #endif
168111fa71b9SJerome Forissier 
168211fa71b9SJerome Forissier         /* Size considerations:
168311fa71b9SJerome Forissier          *
168411fa71b9SJerome Forissier          * - The CBC cipher text must not be empty and hence
168511fa71b9SJerome Forissier          *   at least of size transform->ivlen.
168611fa71b9SJerome Forissier          *
168711fa71b9SJerome Forissier          * Together with the potential IV-prefix, this explains
168811fa71b9SJerome Forissier          * the first of the two checks below.
168911fa71b9SJerome Forissier          *
169011fa71b9SJerome Forissier          * - The record must contain a MAC, either in plain or
169111fa71b9SJerome Forissier          *   encrypted, depending on whether Encrypt-then-MAC
169211fa71b9SJerome Forissier          *   is used or not.
169311fa71b9SJerome Forissier          *   - If it is, the message contains the IV-prefix,
169411fa71b9SJerome Forissier          *     the CBC ciphertext, and the MAC.
169511fa71b9SJerome Forissier          *   - If it is not, the padded plaintext, and hence
169611fa71b9SJerome Forissier          *     the CBC ciphertext, has at least length maclen + 1
169711fa71b9SJerome Forissier          *     because there is at least the padding length byte.
169811fa71b9SJerome Forissier          *
169911fa71b9SJerome Forissier          * As the CBC ciphertext is not empty, both cases give the
170011fa71b9SJerome Forissier          * lower bound minlen + maclen + 1 on the record size, which
170111fa71b9SJerome Forissier          * we test for in the second check below.
170211fa71b9SJerome Forissier          */
170311fa71b9SJerome Forissier         if (rec->data_len < minlen + transform->ivlen ||
170432b31808SJens Wiklander             rec->data_len < minlen + transform->maclen + 1) {
17057901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
17067901324dSJerome Forissier                                       ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
17077901324dSJerome Forissier                                       "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
170832b31808SJens Wiklander                                                                           "+ 1 ) ( + expl IV )",
170932b31808SJens Wiklander                                       rec->data_len,
171011fa71b9SJerome Forissier                                       transform->ivlen,
171111fa71b9SJerome Forissier                                       transform->maclen));
171232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_MAC;
171311fa71b9SJerome Forissier         }
171411fa71b9SJerome Forissier 
171511fa71b9SJerome Forissier         /*
171611fa71b9SJerome Forissier          * Authenticate before decrypt if enabled
171711fa71b9SJerome Forissier          */
171811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
171932b31808SJens Wiklander         if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
172032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
172132b31808SJens Wiklander             psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
172232b31808SJens Wiklander #else
172311fa71b9SJerome Forissier             unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
172432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
172511fa71b9SJerome Forissier 
172611fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
172711fa71b9SJerome Forissier 
172811fa71b9SJerome Forissier             /* Update data_len in tandem with add_data.
172911fa71b9SJerome Forissier              *
173011fa71b9SJerome Forissier              * The subtraction is safe because of the previous check
173111fa71b9SJerome Forissier              * data_len >= minlen + maclen + 1.
173211fa71b9SJerome Forissier              *
173311fa71b9SJerome Forissier              * Afterwards, we know that data + data_len is followed by at
173411fa71b9SJerome Forissier              * least maclen Bytes, which justifies the call to
1735039e02dfSJerome Forissier              * mbedtls_ct_memcmp() below.
173611fa71b9SJerome Forissier              *
173711fa71b9SJerome Forissier              * Further, we still know that data_len > minlen */
173811fa71b9SJerome Forissier             rec->data_len -= transform->maclen;
17397901324dSJerome Forissier             ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
174032b31808SJens Wiklander                                              transform->tls_version,
174132b31808SJens Wiklander                                              transform->taglen);
174211fa71b9SJerome Forissier 
174311fa71b9SJerome Forissier             /* Calculate expected MAC. */
174411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
174511fa71b9SJerome Forissier                                   add_data_len);
174632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
174732b31808SJens Wiklander             status = psa_mac_verify_setup(&operation, transform->psa_mac_dec,
174832b31808SJens Wiklander                                           transform->psa_mac_alg);
174932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
175032b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
175132b31808SJens Wiklander             }
175232b31808SJens Wiklander 
175332b31808SJens Wiklander             status = psa_mac_update(&operation, add_data, add_data_len);
175432b31808SJens Wiklander             if (status != PSA_SUCCESS) {
175532b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
175632b31808SJens Wiklander             }
175732b31808SJens Wiklander 
175832b31808SJens Wiklander             status = psa_mac_update(&operation, data, rec->data_len);
175932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
176032b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
176132b31808SJens Wiklander             }
176232b31808SJens Wiklander 
176332b31808SJens Wiklander             /* Compare expected MAC with MAC at the end of the record. */
176432b31808SJens Wiklander             status = psa_mac_verify_finish(&operation, data + rec->data_len,
176532b31808SJens Wiklander                                            transform->maclen);
176632b31808SJens Wiklander             if (status != PSA_SUCCESS) {
176732b31808SJens Wiklander                 goto hmac_failed_etm_enabled;
176832b31808SJens Wiklander             }
176932b31808SJens Wiklander #else
1770039e02dfSJerome Forissier             ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data,
177111fa71b9SJerome Forissier                                          add_data_len);
177232b31808SJens Wiklander             if (ret != 0) {
1773039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
177432b31808SJens Wiklander             }
1775039e02dfSJerome Forissier             ret = mbedtls_md_hmac_update(&transform->md_ctx_dec,
177611fa71b9SJerome Forissier                                          data, rec->data_len);
177732b31808SJens Wiklander             if (ret != 0) {
1778039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
177932b31808SJens Wiklander             }
1780039e02dfSJerome Forissier             ret = mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect);
178132b31808SJens Wiklander             if (ret != 0) {
1782039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
178332b31808SJens Wiklander             }
1784039e02dfSJerome Forissier             ret = mbedtls_md_hmac_reset(&transform->md_ctx_dec);
178532b31808SJens Wiklander             if (ret != 0) {
1786039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
178732b31808SJens Wiklander             }
178811fa71b9SJerome Forissier 
178911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(4, "message  mac", data + rec->data_len,
179011fa71b9SJerome Forissier                                   transform->maclen);
179111fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect,
179211fa71b9SJerome Forissier                                   transform->maclen);
179311fa71b9SJerome Forissier 
179411fa71b9SJerome Forissier             /* Compare expected MAC with MAC at the end of the record. */
1795039e02dfSJerome Forissier             if (mbedtls_ct_memcmp(data + rec->data_len, mac_expect,
179632b31808SJens Wiklander                                   transform->maclen) != 0) {
179711fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
1798039e02dfSJerome Forissier                 ret = MBEDTLS_ERR_SSL_INVALID_MAC;
1799039e02dfSJerome Forissier                 goto hmac_failed_etm_enabled;
180011fa71b9SJerome Forissier             }
180132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
180211fa71b9SJerome Forissier             auth_done++;
1803039e02dfSJerome Forissier 
1804039e02dfSJerome Forissier hmac_failed_etm_enabled:
180532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
180632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
180732b31808SJens Wiklander             status = psa_mac_abort(&operation);
180832b31808SJens Wiklander             if (ret == 0 && status != PSA_SUCCESS) {
180932b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
181032b31808SJens Wiklander             }
181132b31808SJens Wiklander #else
1812039e02dfSJerome Forissier             mbedtls_platform_zeroize(mac_expect, transform->maclen);
181332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
181432b31808SJens Wiklander             if (ret != 0) {
181532b31808SJens Wiklander                 if (ret != MBEDTLS_ERR_SSL_INVALID_MAC) {
1816039e02dfSJerome Forissier                     MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_hmac_xxx", ret);
181732b31808SJens Wiklander                 }
181832b31808SJens Wiklander                 return ret;
1819039e02dfSJerome Forissier             }
182011fa71b9SJerome Forissier         }
182111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
182211fa71b9SJerome Forissier 
182311fa71b9SJerome Forissier         /*
182411fa71b9SJerome Forissier          * Check length sanity
182511fa71b9SJerome Forissier          */
182611fa71b9SJerome Forissier 
182711fa71b9SJerome Forissier         /* We know from above that data_len > minlen >= 0,
182811fa71b9SJerome Forissier          * so the following check in particular implies that
182911fa71b9SJerome Forissier          * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
183032b31808SJens Wiklander         if (rec->data_len % transform->ivlen != 0) {
18317901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
18327901324dSJerome Forissier                                       ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
183311fa71b9SJerome Forissier                                       rec->data_len, transform->ivlen));
183432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_MAC;
183511fa71b9SJerome Forissier         }
183611fa71b9SJerome Forissier 
183732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
183811fa71b9SJerome Forissier         /*
183932b31808SJens Wiklander          * Initialize for prepended IV for block cipher in TLS v1.2
184011fa71b9SJerome Forissier          */
184111fa71b9SJerome Forissier         /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
184211fa71b9SJerome Forissier         memcpy(transform->iv_dec, data, transform->ivlen);
184311fa71b9SJerome Forissier 
184411fa71b9SJerome Forissier         data += transform->ivlen;
184511fa71b9SJerome Forissier         rec->data_offset += transform->ivlen;
184611fa71b9SJerome Forissier         rec->data_len -= transform->ivlen;
184732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
184811fa71b9SJerome Forissier 
184911fa71b9SJerome Forissier         /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
185011fa71b9SJerome Forissier 
185132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
185232b31808SJens Wiklander         status = psa_cipher_decrypt_setup(&cipher_op,
185332b31808SJens Wiklander                                           transform->psa_key_dec, transform->psa_alg);
185432b31808SJens Wiklander 
185532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
185632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
185732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_decrypt_setup", ret);
185832b31808SJens Wiklander             return ret;
185932b31808SJens Wiklander         }
186032b31808SJens Wiklander 
186132b31808SJens Wiklander         status = psa_cipher_set_iv(&cipher_op, transform->iv_dec, transform->ivlen);
186232b31808SJens Wiklander 
186332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
186432b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
186532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
186632b31808SJens Wiklander             return ret;
186732b31808SJens Wiklander         }
186832b31808SJens Wiklander 
186932b31808SJens Wiklander         status = psa_cipher_update(&cipher_op,
187032b31808SJens Wiklander                                    data, rec->data_len,
187132b31808SJens Wiklander                                    data, rec->data_len, &olen);
187232b31808SJens Wiklander 
187332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
187432b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
187532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
187632b31808SJens Wiklander             return ret;
187732b31808SJens Wiklander         }
187832b31808SJens Wiklander 
187932b31808SJens Wiklander         status = psa_cipher_finish(&cipher_op,
188032b31808SJens Wiklander                                    data + olen, rec->data_len - olen,
188132b31808SJens Wiklander                                    &part_len);
188232b31808SJens Wiklander 
188332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
188432b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
188532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
188632b31808SJens Wiklander             return ret;
188732b31808SJens Wiklander         }
188832b31808SJens Wiklander 
188932b31808SJens Wiklander         olen += part_len;
189032b31808SJens Wiklander #else
189132b31808SJens Wiklander 
189211fa71b9SJerome Forissier         if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec,
189311fa71b9SJerome Forissier                                         transform->iv_dec, transform->ivlen,
189432b31808SJens Wiklander                                         data, rec->data_len, data, &olen)) != 0) {
189511fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
189632b31808SJens Wiklander             return ret;
189711fa71b9SJerome Forissier         }
189832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
189911fa71b9SJerome Forissier 
190011fa71b9SJerome Forissier         /* Double-check that length hasn't changed during decryption. */
190132b31808SJens Wiklander         if (rec->data_len != olen) {
190211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
190332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
190411fa71b9SJerome Forissier         }
190511fa71b9SJerome Forissier 
190611fa71b9SJerome Forissier         /* Safe since data_len >= minlen + maclen + 1, so after having
190711fa71b9SJerome Forissier          * subtracted at most minlen and maclen up to this point,
190811fa71b9SJerome Forissier          * data_len > 0 (because of data_len % ivlen == 0, it's actually
190911fa71b9SJerome Forissier          * >= ivlen ). */
191011fa71b9SJerome Forissier         padlen = data[rec->data_len - 1];
191111fa71b9SJerome Forissier 
191232b31808SJens Wiklander         if (auth_done == 1) {
1913b0563631STom Van Eyck             const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
19147901324dSJerome Forissier                 rec->data_len,
19157901324dSJerome Forissier                 padlen + 1);
1916b0563631STom Van Eyck             correct = mbedtls_ct_bool_and(ge, correct);
1917b0563631STom Van Eyck             padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
191832b31808SJens Wiklander         } else {
191911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
192032b31808SJens Wiklander             if (rec->data_len < transform->maclen + padlen + 1) {
19217901324dSJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
19227901324dSJerome Forissier                                           ") < maclen (%" MBEDTLS_PRINTF_SIZET
19237901324dSJerome Forissier                                           ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
192411fa71b9SJerome Forissier                                           rec->data_len,
192511fa71b9SJerome Forissier                                           transform->maclen,
192611fa71b9SJerome Forissier                                           padlen + 1));
192711fa71b9SJerome Forissier             }
192811fa71b9SJerome Forissier #endif
1929b0563631STom Van Eyck             const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
19307901324dSJerome Forissier                 rec->data_len,
19317901324dSJerome Forissier                 transform->maclen + padlen + 1);
1932b0563631STom Van Eyck             correct = mbedtls_ct_bool_and(ge, correct);
1933b0563631STom Van Eyck             padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
193411fa71b9SJerome Forissier         }
193511fa71b9SJerome Forissier 
193611fa71b9SJerome Forissier         padlen++;
193711fa71b9SJerome Forissier 
193811fa71b9SJerome Forissier         /* Regardless of the validity of the padding,
193911fa71b9SJerome Forissier          * we have data_len >= padlen here. */
194011fa71b9SJerome Forissier 
194132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
194211fa71b9SJerome Forissier         /* The padding check involves a series of up to 256
194311fa71b9SJerome Forissier          * consecutive memory reads at the end of the record
194411fa71b9SJerome Forissier          * plaintext buffer. In order to hide the length and
194511fa71b9SJerome Forissier          * validity of the padding, always perform exactly
194611fa71b9SJerome Forissier          * `min(256,plaintext_len)` reads (but take into account
194711fa71b9SJerome Forissier          * only the last `padlen` bytes for the padding check). */
194811fa71b9SJerome Forissier         size_t pad_count = 0;
194911fa71b9SJerome Forissier         volatile unsigned char * const check = data;
195011fa71b9SJerome Forissier 
195111fa71b9SJerome Forissier         /* Index of first padding byte; it has been ensured above
195211fa71b9SJerome Forissier          * that the subtraction is safe. */
195311fa71b9SJerome Forissier         size_t const padding_idx = rec->data_len - padlen;
195411fa71b9SJerome Forissier         size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
195511fa71b9SJerome Forissier         size_t const start_idx = rec->data_len - num_checks;
195611fa71b9SJerome Forissier         size_t idx;
195711fa71b9SJerome Forissier 
195832b31808SJens Wiklander         for (idx = start_idx; idx < rec->data_len; idx++) {
19597901324dSJerome Forissier             /* pad_count += (idx >= padding_idx) &&
19607901324dSJerome Forissier              *              (check[idx] == padlen - 1);
19617901324dSJerome Forissier              */
1962b0563631STom Van Eyck             const mbedtls_ct_condition_t a = mbedtls_ct_uint_ge(idx, padding_idx);
1963b0563631STom Van Eyck             size_t increment = mbedtls_ct_size_if_else_0(a, 1);
1964b0563631STom Van Eyck             const mbedtls_ct_condition_t b = mbedtls_ct_uint_eq(check[idx], padlen - 1);
1965b0563631STom Van Eyck             increment = mbedtls_ct_size_if_else_0(b, increment);
1966b0563631STom Van Eyck             pad_count += increment;
196711fa71b9SJerome Forissier         }
1968b0563631STom Van Eyck         correct = mbedtls_ct_bool_and(mbedtls_ct_uint_eq(pad_count, padlen), correct);
196911fa71b9SJerome Forissier 
197011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1971b0563631STom Van Eyck         if (padlen > 0 && correct == MBEDTLS_CT_FALSE) {
197211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
197332b31808SJens Wiklander         }
197411fa71b9SJerome Forissier #endif
1975b0563631STom Van Eyck         padlen = mbedtls_ct_size_if_else_0(correct, padlen);
197632b31808SJens Wiklander 
197732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
197811fa71b9SJerome Forissier 
197911fa71b9SJerome Forissier         /* If the padding was found to be invalid, padlen == 0
198011fa71b9SJerome Forissier          * and the subtraction is safe. If the padding was found valid,
198111fa71b9SJerome Forissier          * padlen hasn't been changed and the previous assertion
198211fa71b9SJerome Forissier          * data_len >= padlen still holds. */
198311fa71b9SJerome Forissier         rec->data_len -= padlen;
198432b31808SJens Wiklander     } else
19857901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
198611fa71b9SJerome Forissier     {
198711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
198832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
198911fa71b9SJerome Forissier     }
199011fa71b9SJerome Forissier 
199111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
199211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption",
199311fa71b9SJerome Forissier                           data, rec->data_len);
199411fa71b9SJerome Forissier #endif
199511fa71b9SJerome Forissier 
199611fa71b9SJerome Forissier     /*
199711fa71b9SJerome Forissier      * Authenticate if not done yet.
199811fa71b9SJerome Forissier      * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
199911fa71b9SJerome Forissier      */
200032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
200132b31808SJens Wiklander     if (auth_done == 0) {
2002039e02dfSJerome Forissier         unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
2003039e02dfSJerome Forissier         unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
200411fa71b9SJerome Forissier 
2005b0563631STom Van Eyck         /* For CBC+MAC, If the initial value of padlen was such that
200611fa71b9SJerome Forissier          * data_len < maclen + padlen + 1, then padlen
200711fa71b9SJerome Forissier          * got reset to 1, and the initial check
200811fa71b9SJerome Forissier          * data_len >= minlen + maclen + 1
200911fa71b9SJerome Forissier          * guarantees that at this point we still
201011fa71b9SJerome Forissier          * have at least data_len >= maclen.
201111fa71b9SJerome Forissier          *
201211fa71b9SJerome Forissier          * If the initial value of padlen was such that
201311fa71b9SJerome Forissier          * data_len >= maclen + padlen + 1, then we have
201411fa71b9SJerome Forissier          * subtracted either padlen + 1 (if the padding was correct)
201511fa71b9SJerome Forissier          * or 0 (if the padding was incorrect) since then,
201611fa71b9SJerome Forissier          * hence data_len >= maclen in any case.
2017b0563631STom Van Eyck          *
2018b0563631STom Van Eyck          * For stream ciphers, we checked above that
2019b0563631STom Van Eyck          * data_len >= maclen.
202011fa71b9SJerome Forissier          */
202111fa71b9SJerome Forissier         rec->data_len -= transform->maclen;
20227901324dSJerome Forissier         ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
202332b31808SJens Wiklander                                          transform->tls_version,
202432b31808SJens Wiklander                                          transform->taglen);
202511fa71b9SJerome Forissier 
202632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
202711fa71b9SJerome Forissier         /*
202811fa71b9SJerome Forissier          * The next two sizes are the minimum and maximum values of
20297901324dSJerome Forissier          * data_len over all padlen values.
203011fa71b9SJerome Forissier          *
203111fa71b9SJerome Forissier          * They're independent of padlen, since we previously did
203211fa71b9SJerome Forissier          * data_len -= padlen.
203311fa71b9SJerome Forissier          *
203411fa71b9SJerome Forissier          * Note that max_len + maclen is never more than the buffer
203511fa71b9SJerome Forissier          * length, as we previously did in_msglen -= maclen too.
203611fa71b9SJerome Forissier          */
203711fa71b9SJerome Forissier         const size_t max_len = rec->data_len + padlen;
203811fa71b9SJerome Forissier         const size_t min_len = (max_len > 256) ? max_len - 256 : 0;
203911fa71b9SJerome Forissier 
204032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
204132b31808SJens Wiklander         ret = mbedtls_ct_hmac(transform->psa_mac_dec,
204232b31808SJens Wiklander                               transform->psa_mac_alg,
204332b31808SJens Wiklander                               add_data, add_data_len,
204432b31808SJens Wiklander                               data, rec->data_len, min_len, max_len,
204532b31808SJens Wiklander                               mac_expect);
204632b31808SJens Wiklander #else
2047039e02dfSJerome Forissier         ret = mbedtls_ct_hmac(&transform->md_ctx_dec,
20487901324dSJerome Forissier                               add_data, add_data_len,
20497901324dSJerome Forissier                               data, rec->data_len, min_len, max_len,
20507901324dSJerome Forissier                               mac_expect);
205132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
205232b31808SJens Wiklander         if (ret != 0) {
2053039e02dfSJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ct_hmac", ret);
2054039e02dfSJerome Forissier             goto hmac_failed_etm_disabled;
205511fa71b9SJerome Forissier         }
205611fa71b9SJerome Forissier 
2057039e02dfSJerome Forissier         mbedtls_ct_memcpy_offset(mac_peer, data,
20587901324dSJerome Forissier                                  rec->data_len,
20597901324dSJerome Forissier                                  min_len, max_len,
20607901324dSJerome Forissier                                  transform->maclen);
206132b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
206211fa71b9SJerome Forissier 
206311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
206411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen);
20657901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "message  mac", mac_peer, transform->maclen);
206611fa71b9SJerome Forissier #endif
206711fa71b9SJerome Forissier 
2068039e02dfSJerome Forissier         if (mbedtls_ct_memcmp(mac_peer, mac_expect,
206932b31808SJens Wiklander                               transform->maclen) != 0) {
207011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
207111fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
207211fa71b9SJerome Forissier #endif
2073b0563631STom Van Eyck             correct = MBEDTLS_CT_FALSE;
207411fa71b9SJerome Forissier         }
207511fa71b9SJerome Forissier         auth_done++;
2076039e02dfSJerome Forissier 
2077039e02dfSJerome Forissier hmac_failed_etm_disabled:
2078039e02dfSJerome Forissier         mbedtls_platform_zeroize(mac_peer, transform->maclen);
2079039e02dfSJerome Forissier         mbedtls_platform_zeroize(mac_expect, transform->maclen);
208032b31808SJens Wiklander         if (ret != 0) {
208132b31808SJens Wiklander             return ret;
208232b31808SJens Wiklander         }
208311fa71b9SJerome Forissier     }
208411fa71b9SJerome Forissier 
208511fa71b9SJerome Forissier     /*
208611fa71b9SJerome Forissier      * Finally check the correct flag
208711fa71b9SJerome Forissier      */
2088b0563631STom Van Eyck     if (correct == MBEDTLS_CT_FALSE) {
208932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_MAC;
209032b31808SJens Wiklander     }
209132b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
209211fa71b9SJerome Forissier 
209311fa71b9SJerome Forissier     /* Make extra sure authentication was performed, exactly once */
209432b31808SJens Wiklander     if (auth_done != 1) {
209511fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
209632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
209711fa71b9SJerome Forissier     }
209811fa71b9SJerome Forissier 
209932b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
210032b31808SJens Wiklander     if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
21017901324dSJerome Forissier         /* Remove inner padding and infer true content type. */
21027901324dSJerome Forissier         ret = ssl_parse_inner_plaintext(data, &rec->data_len,
21037901324dSJerome Forissier                                         &rec->type);
21047901324dSJerome Forissier 
210532b31808SJens Wiklander         if (ret != 0) {
210632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
21077901324dSJerome Forissier         }
210832b31808SJens Wiklander     }
210932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
21107901324dSJerome Forissier 
211111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
211232b31808SJens Wiklander     if (rec->cid_len != 0) {
21137901324dSJerome Forissier         ret = ssl_parse_inner_plaintext(data, &rec->data_len,
211411fa71b9SJerome Forissier                                         &rec->type);
211532b31808SJens Wiklander         if (ret != 0) {
211632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
211732b31808SJens Wiklander         }
211811fa71b9SJerome Forissier     }
211911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
212011fa71b9SJerome Forissier 
212111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf"));
212211fa71b9SJerome Forissier 
212332b31808SJens Wiklander     return 0;
212411fa71b9SJerome Forissier }
212511fa71b9SJerome Forissier 
212611fa71b9SJerome Forissier #undef MAC_NONE
212711fa71b9SJerome Forissier #undef MAC_PLAINTEXT
212811fa71b9SJerome Forissier #undef MAC_CIPHERTEXT
212911fa71b9SJerome Forissier 
213011fa71b9SJerome Forissier /*
213111fa71b9SJerome Forissier  * Fill the input message buffer by appending data to it.
213211fa71b9SJerome Forissier  * The amount of data already fetched is in ssl->in_left.
213311fa71b9SJerome Forissier  *
213411fa71b9SJerome Forissier  * If we return 0, is it guaranteed that (at least) nb_want bytes are
213511fa71b9SJerome Forissier  * available (from this read and/or a previous one). Otherwise, an error code
213611fa71b9SJerome Forissier  * is returned (possibly EOF or WANT_READ).
213711fa71b9SJerome Forissier  *
213811fa71b9SJerome Forissier  * With stream transport (TLS) on success ssl->in_left == nb_want, but
213911fa71b9SJerome Forissier  * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
214011fa71b9SJerome Forissier  * since we always read a whole datagram at once.
214111fa71b9SJerome Forissier  *
214211fa71b9SJerome Forissier  * For DTLS, it is up to the caller to set ssl->next_record_offset when
214311fa71b9SJerome Forissier  * they're done reading a record.
214411fa71b9SJerome Forissier  */
214511fa71b9SJerome Forissier int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
214611fa71b9SJerome Forissier {
214711fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
214811fa71b9SJerome Forissier     size_t len;
214911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
215011fa71b9SJerome Forissier     size_t in_buf_len = ssl->in_buf_len;
215111fa71b9SJerome Forissier #else
215211fa71b9SJerome Forissier     size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
215311fa71b9SJerome Forissier #endif
215411fa71b9SJerome Forissier 
215511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input"));
215611fa71b9SJerome Forissier 
215732b31808SJens Wiklander     if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) {
215832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
215932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
216011fa71b9SJerome Forissier     }
216111fa71b9SJerome Forissier 
216232b31808SJens Wiklander     if (nb_want > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
216311fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits"));
216432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
216511fa71b9SJerome Forissier     }
216611fa71b9SJerome Forissier 
216711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
216832b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
216911fa71b9SJerome Forissier         uint32_t timeout;
217011fa71b9SJerome Forissier 
217111fa71b9SJerome Forissier         /*
217211fa71b9SJerome Forissier          * The point is, we need to always read a full datagram at once, so we
217311fa71b9SJerome Forissier          * sometimes read more then requested, and handle the additional data.
217411fa71b9SJerome Forissier          * It could be the rest of the current record (while fetching the
217511fa71b9SJerome Forissier          * header) and/or some other records in the same datagram.
217611fa71b9SJerome Forissier          */
217711fa71b9SJerome Forissier 
217811fa71b9SJerome Forissier         /*
217911fa71b9SJerome Forissier          * Move to the next record in the already read datagram if applicable
218011fa71b9SJerome Forissier          */
218132b31808SJens Wiklander         if (ssl->next_record_offset != 0) {
218232b31808SJens Wiklander             if (ssl->in_left < ssl->next_record_offset) {
218311fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
218432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
218511fa71b9SJerome Forissier             }
218611fa71b9SJerome Forissier 
218711fa71b9SJerome Forissier             ssl->in_left -= ssl->next_record_offset;
218811fa71b9SJerome Forissier 
218932b31808SJens Wiklander             if (ssl->in_left != 0) {
21907901324dSJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("next record in same datagram, offset: %"
21917901324dSJerome Forissier                                           MBEDTLS_PRINTF_SIZET,
219211fa71b9SJerome Forissier                                           ssl->next_record_offset));
219311fa71b9SJerome Forissier                 memmove(ssl->in_hdr,
219411fa71b9SJerome Forissier                         ssl->in_hdr + ssl->next_record_offset,
219511fa71b9SJerome Forissier                         ssl->in_left);
219611fa71b9SJerome Forissier             }
219711fa71b9SJerome Forissier 
219811fa71b9SJerome Forissier             ssl->next_record_offset = 0;
219911fa71b9SJerome Forissier         }
220011fa71b9SJerome Forissier 
22017901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
22027901324dSJerome Forissier                                   ", nb_want: %" MBEDTLS_PRINTF_SIZET,
220311fa71b9SJerome Forissier                                   ssl->in_left, nb_want));
220411fa71b9SJerome Forissier 
220511fa71b9SJerome Forissier         /*
220611fa71b9SJerome Forissier          * Done if we already have enough data.
220711fa71b9SJerome Forissier          */
220832b31808SJens Wiklander         if (nb_want <= ssl->in_left) {
220911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
221032b31808SJens Wiklander             return 0;
221111fa71b9SJerome Forissier         }
221211fa71b9SJerome Forissier 
221311fa71b9SJerome Forissier         /*
221411fa71b9SJerome Forissier          * A record can't be split across datagrams. If we need to read but
221511fa71b9SJerome Forissier          * are not at the beginning of a new record, the caller did something
221611fa71b9SJerome Forissier          * wrong.
221711fa71b9SJerome Forissier          */
221832b31808SJens Wiklander         if (ssl->in_left != 0) {
221911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
222032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
222111fa71b9SJerome Forissier         }
222211fa71b9SJerome Forissier 
222311fa71b9SJerome Forissier         /*
222411fa71b9SJerome Forissier          * Don't even try to read if time's out already.
222511fa71b9SJerome Forissier          * This avoids by-passing the timer when repeatedly receiving messages
222611fa71b9SJerome Forissier          * that will end up being dropped.
222711fa71b9SJerome Forissier          */
222832b31808SJens Wiklander         if (mbedtls_ssl_check_timer(ssl) != 0) {
222911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired"));
223011fa71b9SJerome Forissier             ret = MBEDTLS_ERR_SSL_TIMEOUT;
223132b31808SJens Wiklander         } else {
2232b0563631STom Van Eyck             len = in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf);
223311fa71b9SJerome Forissier 
223432b31808SJens Wiklander             if (mbedtls_ssl_is_handshake_over(ssl) == 0) {
223511fa71b9SJerome Forissier                 timeout = ssl->handshake->retransmit_timeout;
223632b31808SJens Wiklander             } else {
223711fa71b9SJerome Forissier                 timeout = ssl->conf->read_timeout;
223832b31808SJens Wiklander             }
223911fa71b9SJerome Forissier 
22407901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms", (unsigned long) timeout));
224111fa71b9SJerome Forissier 
224232b31808SJens Wiklander             if (ssl->f_recv_timeout != NULL) {
224311fa71b9SJerome Forissier                 ret = ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len,
224411fa71b9SJerome Forissier                                           timeout);
224532b31808SJens Wiklander             } else {
224611fa71b9SJerome Forissier                 ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len);
224732b31808SJens Wiklander             }
224811fa71b9SJerome Forissier 
224911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
225011fa71b9SJerome Forissier 
225132b31808SJens Wiklander             if (ret == 0) {
225232b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_CONN_EOF;
225332b31808SJens Wiklander             }
225411fa71b9SJerome Forissier         }
225511fa71b9SJerome Forissier 
225632b31808SJens Wiklander         if (ret == MBEDTLS_ERR_SSL_TIMEOUT) {
225711fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("timeout"));
225811fa71b9SJerome Forissier             mbedtls_ssl_set_timer(ssl, 0);
225911fa71b9SJerome Forissier 
226032b31808SJens Wiklander             if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
226132b31808SJens Wiklander                 if (ssl_double_retransmit_timeout(ssl) != 0) {
226211fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout"));
226332b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_TIMEOUT;
226411fa71b9SJerome Forissier                 }
226511fa71b9SJerome Forissier 
226632b31808SJens Wiklander                 if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
226711fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
226832b31808SJens Wiklander                     return ret;
226911fa71b9SJerome Forissier                 }
227011fa71b9SJerome Forissier 
227132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_WANT_READ;
227211fa71b9SJerome Forissier             }
227311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
227411fa71b9SJerome Forissier             else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
227532b31808SJens Wiklander                      ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
227632b31808SJens Wiklander                 if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
227711fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
227811fa71b9SJerome Forissier                                           ret);
227932b31808SJens Wiklander                     return ret;
228011fa71b9SJerome Forissier                 }
228111fa71b9SJerome Forissier 
228232b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_WANT_READ;
228311fa71b9SJerome Forissier             }
228411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
228511fa71b9SJerome Forissier         }
228611fa71b9SJerome Forissier 
228732b31808SJens Wiklander         if (ret < 0) {
228832b31808SJens Wiklander             return ret;
228932b31808SJens Wiklander         }
229011fa71b9SJerome Forissier 
229111fa71b9SJerome Forissier         ssl->in_left = ret;
229232b31808SJens Wiklander     } else
229311fa71b9SJerome Forissier #endif
229411fa71b9SJerome Forissier     {
22957901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
22967901324dSJerome Forissier                                   ", nb_want: %" MBEDTLS_PRINTF_SIZET,
229711fa71b9SJerome Forissier                                   ssl->in_left, nb_want));
229811fa71b9SJerome Forissier 
229932b31808SJens Wiklander         while (ssl->in_left < nb_want) {
230011fa71b9SJerome Forissier             len = nb_want - ssl->in_left;
230111fa71b9SJerome Forissier 
230232b31808SJens Wiklander             if (mbedtls_ssl_check_timer(ssl) != 0) {
230311fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_TIMEOUT;
230432b31808SJens Wiklander             } else {
230532b31808SJens Wiklander                 if (ssl->f_recv_timeout != NULL) {
230611fa71b9SJerome Forissier                     ret = ssl->f_recv_timeout(ssl->p_bio,
230711fa71b9SJerome Forissier                                               ssl->in_hdr + ssl->in_left, len,
230811fa71b9SJerome Forissier                                               ssl->conf->read_timeout);
230932b31808SJens Wiklander                 } else {
231011fa71b9SJerome Forissier                     ret = ssl->f_recv(ssl->p_bio,
231111fa71b9SJerome Forissier                                       ssl->in_hdr + ssl->in_left, len);
231211fa71b9SJerome Forissier                 }
231311fa71b9SJerome Forissier             }
231411fa71b9SJerome Forissier 
23157901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
23167901324dSJerome Forissier                                       ", nb_want: %" MBEDTLS_PRINTF_SIZET,
231711fa71b9SJerome Forissier                                       ssl->in_left, nb_want));
231811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
231911fa71b9SJerome Forissier 
232032b31808SJens Wiklander             if (ret == 0) {
232132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_CONN_EOF;
232232b31808SJens Wiklander             }
232311fa71b9SJerome Forissier 
232432b31808SJens Wiklander             if (ret < 0) {
232532b31808SJens Wiklander                 return ret;
232632b31808SJens Wiklander             }
232711fa71b9SJerome Forissier 
232832b31808SJens Wiklander             if ((size_t) ret > len) {
232911fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1,
233032b31808SJens Wiklander                                       ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
233132b31808SJens Wiklander                                        " were requested",
23327901324dSJerome Forissier                                        ret, len));
233332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
233411fa71b9SJerome Forissier             }
233511fa71b9SJerome Forissier 
233611fa71b9SJerome Forissier             ssl->in_left += ret;
233711fa71b9SJerome Forissier         }
233811fa71b9SJerome Forissier     }
233911fa71b9SJerome Forissier 
234011fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
234111fa71b9SJerome Forissier 
234232b31808SJens Wiklander     return 0;
234311fa71b9SJerome Forissier }
234411fa71b9SJerome Forissier 
234511fa71b9SJerome Forissier /*
234611fa71b9SJerome Forissier  * Flush any data not yet written
234711fa71b9SJerome Forissier  */
234811fa71b9SJerome Forissier int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
234911fa71b9SJerome Forissier {
235011fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
235111fa71b9SJerome Forissier     unsigned char *buf;
235211fa71b9SJerome Forissier 
235311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output"));
235411fa71b9SJerome Forissier 
235532b31808SJens Wiklander     if (ssl->f_send == NULL) {
235632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
235732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
235811fa71b9SJerome Forissier     }
235911fa71b9SJerome Forissier 
236011fa71b9SJerome Forissier     /* Avoid incrementing counter if data is flushed */
236132b31808SJens Wiklander     if (ssl->out_left == 0) {
236211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
236332b31808SJens Wiklander         return 0;
236411fa71b9SJerome Forissier     }
236511fa71b9SJerome Forissier 
236632b31808SJens Wiklander     while (ssl->out_left > 0) {
23677901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("message length: %" MBEDTLS_PRINTF_SIZET
23687901324dSJerome Forissier                                   ", out_left: %" MBEDTLS_PRINTF_SIZET,
236911fa71b9SJerome Forissier                                   mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left));
237011fa71b9SJerome Forissier 
237111fa71b9SJerome Forissier         buf = ssl->out_hdr - ssl->out_left;
237211fa71b9SJerome Forissier         ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left);
237311fa71b9SJerome Forissier 
237411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret);
237511fa71b9SJerome Forissier 
237632b31808SJens Wiklander         if (ret <= 0) {
237732b31808SJens Wiklander             return ret;
237832b31808SJens Wiklander         }
237911fa71b9SJerome Forissier 
238032b31808SJens Wiklander         if ((size_t) ret > ssl->out_left) {
238111fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1,
238232b31808SJens Wiklander                                   ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
238332b31808SJens Wiklander                                    " bytes were sent",
23847901324dSJerome Forissier                                    ret, ssl->out_left));
238532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
238611fa71b9SJerome Forissier         }
238711fa71b9SJerome Forissier 
238811fa71b9SJerome Forissier         ssl->out_left -= ret;
238911fa71b9SJerome Forissier     }
239011fa71b9SJerome Forissier 
239111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
239232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
239311fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf;
239432b31808SJens Wiklander     } else
239511fa71b9SJerome Forissier #endif
239611fa71b9SJerome Forissier     {
239711fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf + 8;
239811fa71b9SJerome Forissier     }
239911fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
240011fa71b9SJerome Forissier 
240111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
240211fa71b9SJerome Forissier 
240332b31808SJens Wiklander     return 0;
240411fa71b9SJerome Forissier }
240511fa71b9SJerome Forissier 
240611fa71b9SJerome Forissier /*
240711fa71b9SJerome Forissier  * Functions to handle the DTLS retransmission state machine
240811fa71b9SJerome Forissier  */
240911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
241011fa71b9SJerome Forissier /*
241111fa71b9SJerome Forissier  * Append current handshake message to current outgoing flight
241211fa71b9SJerome Forissier  */
2413039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
241411fa71b9SJerome Forissier static int ssl_flight_append(mbedtls_ssl_context *ssl)
241511fa71b9SJerome Forissier {
241611fa71b9SJerome Forissier     mbedtls_ssl_flight_item *msg;
241711fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append"));
241811fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight",
241911fa71b9SJerome Forissier                           ssl->out_msg, ssl->out_msglen);
242011fa71b9SJerome Forissier 
242111fa71b9SJerome Forissier     /* Allocate space for current message */
242232b31808SJens Wiklander     if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) {
24237901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
242411fa71b9SJerome Forissier                                   sizeof(mbedtls_ssl_flight_item)));
242532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
242611fa71b9SJerome Forissier     }
242711fa71b9SJerome Forissier 
242832b31808SJens Wiklander     if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) {
24297901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
24307901324dSJerome Forissier                                   ssl->out_msglen));
243111fa71b9SJerome Forissier         mbedtls_free(msg);
243232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
243311fa71b9SJerome Forissier     }
243411fa71b9SJerome Forissier 
243511fa71b9SJerome Forissier     /* Copy current handshake message with headers */
243611fa71b9SJerome Forissier     memcpy(msg->p, ssl->out_msg, ssl->out_msglen);
243711fa71b9SJerome Forissier     msg->len = ssl->out_msglen;
243811fa71b9SJerome Forissier     msg->type = ssl->out_msgtype;
243911fa71b9SJerome Forissier     msg->next = NULL;
244011fa71b9SJerome Forissier 
244111fa71b9SJerome Forissier     /* Append to the current flight */
244232b31808SJens Wiklander     if (ssl->handshake->flight == NULL) {
244311fa71b9SJerome Forissier         ssl->handshake->flight = msg;
244432b31808SJens Wiklander     } else {
244511fa71b9SJerome Forissier         mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
244632b31808SJens Wiklander         while (cur->next != NULL) {
244711fa71b9SJerome Forissier             cur = cur->next;
244832b31808SJens Wiklander         }
244911fa71b9SJerome Forissier         cur->next = msg;
245011fa71b9SJerome Forissier     }
245111fa71b9SJerome Forissier 
245211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append"));
245332b31808SJens Wiklander     return 0;
245411fa71b9SJerome Forissier }
245511fa71b9SJerome Forissier 
245611fa71b9SJerome Forissier /*
245711fa71b9SJerome Forissier  * Free the current flight of handshake messages
245811fa71b9SJerome Forissier  */
245911fa71b9SJerome Forissier void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight)
246011fa71b9SJerome Forissier {
246111fa71b9SJerome Forissier     mbedtls_ssl_flight_item *cur = flight;
246211fa71b9SJerome Forissier     mbedtls_ssl_flight_item *next;
246311fa71b9SJerome Forissier 
246432b31808SJens Wiklander     while (cur != NULL) {
246511fa71b9SJerome Forissier         next = cur->next;
246611fa71b9SJerome Forissier 
246711fa71b9SJerome Forissier         mbedtls_free(cur->p);
246811fa71b9SJerome Forissier         mbedtls_free(cur);
246911fa71b9SJerome Forissier 
247011fa71b9SJerome Forissier         cur = next;
247111fa71b9SJerome Forissier     }
247211fa71b9SJerome Forissier }
247311fa71b9SJerome Forissier 
247411fa71b9SJerome Forissier /*
247511fa71b9SJerome Forissier  * Swap transform_out and out_ctr with the alternative ones
247611fa71b9SJerome Forissier  */
2477039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
247811fa71b9SJerome Forissier static int ssl_swap_epochs(mbedtls_ssl_context *ssl)
247911fa71b9SJerome Forissier {
248011fa71b9SJerome Forissier     mbedtls_ssl_transform *tmp_transform;
248132b31808SJens Wiklander     unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
248211fa71b9SJerome Forissier 
248332b31808SJens Wiklander     if (ssl->transform_out == ssl->handshake->alt_transform_out) {
248411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs"));
248532b31808SJens Wiklander         return 0;
248611fa71b9SJerome Forissier     }
248711fa71b9SJerome Forissier 
248811fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs"));
248911fa71b9SJerome Forissier 
249011fa71b9SJerome Forissier     /* Swap transforms */
249111fa71b9SJerome Forissier     tmp_transform                     = ssl->transform_out;
249211fa71b9SJerome Forissier     ssl->transform_out                = ssl->handshake->alt_transform_out;
249311fa71b9SJerome Forissier     ssl->handshake->alt_transform_out = tmp_transform;
249411fa71b9SJerome Forissier 
249511fa71b9SJerome Forissier     /* Swap epoch + sequence_number */
249632b31808SJens Wiklander     memcpy(tmp_out_ctr, ssl->cur_out_ctr, sizeof(tmp_out_ctr));
249732b31808SJens Wiklander     memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
249832b31808SJens Wiklander            sizeof(ssl->cur_out_ctr));
249932b31808SJens Wiklander     memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr,
250032b31808SJens Wiklander            sizeof(ssl->handshake->alt_out_ctr));
250111fa71b9SJerome Forissier 
250211fa71b9SJerome Forissier     /* Adjust to the newly activated transform */
250311fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
250411fa71b9SJerome Forissier 
250532b31808SJens Wiklander     return 0;
250611fa71b9SJerome Forissier }
250711fa71b9SJerome Forissier 
250811fa71b9SJerome Forissier /*
250911fa71b9SJerome Forissier  * Retransmit the current flight of messages.
251011fa71b9SJerome Forissier  */
251111fa71b9SJerome Forissier int mbedtls_ssl_resend(mbedtls_ssl_context *ssl)
251211fa71b9SJerome Forissier {
251311fa71b9SJerome Forissier     int ret = 0;
251411fa71b9SJerome Forissier 
251511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend"));
251611fa71b9SJerome Forissier 
251711fa71b9SJerome Forissier     ret = mbedtls_ssl_flight_transmit(ssl);
251811fa71b9SJerome Forissier 
251911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend"));
252011fa71b9SJerome Forissier 
252132b31808SJens Wiklander     return ret;
252211fa71b9SJerome Forissier }
252311fa71b9SJerome Forissier 
252411fa71b9SJerome Forissier /*
252511fa71b9SJerome Forissier  * Transmit or retransmit the current flight of messages.
252611fa71b9SJerome Forissier  *
252711fa71b9SJerome Forissier  * Need to remember the current message in case flush_output returns
252811fa71b9SJerome Forissier  * WANT_WRITE, causing us to exit this function and come back later.
252911fa71b9SJerome Forissier  * This function must be called until state is no longer SENDING.
253011fa71b9SJerome Forissier  */
253111fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl)
253211fa71b9SJerome Forissier {
253311fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
253411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit"));
253511fa71b9SJerome Forissier 
253632b31808SJens Wiklander     if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) {
253711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission"));
253811fa71b9SJerome Forissier 
253911fa71b9SJerome Forissier         ssl->handshake->cur_msg = ssl->handshake->flight;
254011fa71b9SJerome Forissier         ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
254111fa71b9SJerome Forissier         ret = ssl_swap_epochs(ssl);
254232b31808SJens Wiklander         if (ret != 0) {
254332b31808SJens Wiklander             return ret;
254432b31808SJens Wiklander         }
254511fa71b9SJerome Forissier 
254611fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
254711fa71b9SJerome Forissier     }
254811fa71b9SJerome Forissier 
254932b31808SJens Wiklander     while (ssl->handshake->cur_msg != NULL) {
255011fa71b9SJerome Forissier         size_t max_frag_len;
255111fa71b9SJerome Forissier         const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
255211fa71b9SJerome Forissier 
255311fa71b9SJerome Forissier         int const is_finished =
255411fa71b9SJerome Forissier             (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
255511fa71b9SJerome Forissier              cur->p[0] == MBEDTLS_SSL_HS_FINISHED);
255611fa71b9SJerome Forissier 
255732b31808SJens Wiklander         int const force_flush = ssl->disable_datagram_packing == 1 ?
255811fa71b9SJerome Forissier                                 SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
255911fa71b9SJerome Forissier 
256011fa71b9SJerome Forissier         /* Swap epochs before sending Finished: we can't do it after
256111fa71b9SJerome Forissier          * sending ChangeCipherSpec, in case write returns WANT_READ.
256211fa71b9SJerome Forissier          * Must be done before copying, may change out_msg pointer */
256332b31808SJens Wiklander         if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) {
256411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message"));
256511fa71b9SJerome Forissier             ret = ssl_swap_epochs(ssl);
256632b31808SJens Wiklander             if (ret != 0) {
256732b31808SJens Wiklander                 return ret;
256832b31808SJens Wiklander             }
256911fa71b9SJerome Forissier         }
257011fa71b9SJerome Forissier 
257111fa71b9SJerome Forissier         ret = ssl_get_remaining_payload_in_datagram(ssl);
257232b31808SJens Wiklander         if (ret < 0) {
257332b31808SJens Wiklander             return ret;
257432b31808SJens Wiklander         }
257511fa71b9SJerome Forissier         max_frag_len = (size_t) ret;
257611fa71b9SJerome Forissier 
257711fa71b9SJerome Forissier         /* CCS is copied as is, while HS messages may need fragmentation */
257832b31808SJens Wiklander         if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
257932b31808SJens Wiklander             if (max_frag_len == 0) {
258032b31808SJens Wiklander                 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
258132b31808SJens Wiklander                     return ret;
258232b31808SJens Wiklander                 }
258311fa71b9SJerome Forissier 
258411fa71b9SJerome Forissier                 continue;
258511fa71b9SJerome Forissier             }
258611fa71b9SJerome Forissier 
258711fa71b9SJerome Forissier             memcpy(ssl->out_msg, cur->p, cur->len);
258811fa71b9SJerome Forissier             ssl->out_msglen  = cur->len;
258911fa71b9SJerome Forissier             ssl->out_msgtype = cur->type;
259011fa71b9SJerome Forissier 
259111fa71b9SJerome Forissier             /* Update position inside current message */
259211fa71b9SJerome Forissier             ssl->handshake->cur_msg_p += cur->len;
259332b31808SJens Wiklander         } else {
259411fa71b9SJerome Forissier             const unsigned char * const p = ssl->handshake->cur_msg_p;
259511fa71b9SJerome Forissier             const size_t hs_len = cur->len - 12;
2596b0563631STom Van Eyck             const size_t frag_off = (size_t) (p - (cur->p + 12));
259711fa71b9SJerome Forissier             const size_t rem_len = hs_len - frag_off;
259811fa71b9SJerome Forissier             size_t cur_hs_frag_len, max_hs_frag_len;
259911fa71b9SJerome Forissier 
260032b31808SJens Wiklander             if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) {
260132b31808SJens Wiklander                 if (is_finished) {
260211fa71b9SJerome Forissier                     ret = ssl_swap_epochs(ssl);
260332b31808SJens Wiklander                     if (ret != 0) {
260432b31808SJens Wiklander                         return ret;
260532b31808SJens Wiklander                     }
260611fa71b9SJerome Forissier                 }
260711fa71b9SJerome Forissier 
260832b31808SJens Wiklander                 if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
260932b31808SJens Wiklander                     return ret;
261032b31808SJens Wiklander                 }
261111fa71b9SJerome Forissier 
261211fa71b9SJerome Forissier                 continue;
261311fa71b9SJerome Forissier             }
261411fa71b9SJerome Forissier             max_hs_frag_len = max_frag_len - 12;
261511fa71b9SJerome Forissier 
261611fa71b9SJerome Forissier             cur_hs_frag_len = rem_len > max_hs_frag_len ?
261711fa71b9SJerome Forissier                               max_hs_frag_len : rem_len;
261811fa71b9SJerome Forissier 
261932b31808SJens Wiklander             if (frag_off == 0 && cur_hs_frag_len != hs_len) {
262011fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting handshake message (%u > %u)",
262111fa71b9SJerome Forissier                                           (unsigned) cur_hs_frag_len,
262211fa71b9SJerome Forissier                                           (unsigned) max_hs_frag_len));
262311fa71b9SJerome Forissier             }
262411fa71b9SJerome Forissier 
262511fa71b9SJerome Forissier             /* Messages are stored with handshake headers as if not fragmented,
262611fa71b9SJerome Forissier              * copy beginning of headers then fill fragmentation fields.
262711fa71b9SJerome Forissier              * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
262811fa71b9SJerome Forissier             memcpy(ssl->out_msg, cur->p, 6);
262911fa71b9SJerome Forissier 
2630039e02dfSJerome Forissier             ssl->out_msg[6] = MBEDTLS_BYTE_2(frag_off);
2631039e02dfSJerome Forissier             ssl->out_msg[7] = MBEDTLS_BYTE_1(frag_off);
2632039e02dfSJerome Forissier             ssl->out_msg[8] = MBEDTLS_BYTE_0(frag_off);
263311fa71b9SJerome Forissier 
2634039e02dfSJerome Forissier             ssl->out_msg[9] = MBEDTLS_BYTE_2(cur_hs_frag_len);
2635039e02dfSJerome Forissier             ssl->out_msg[10] = MBEDTLS_BYTE_1(cur_hs_frag_len);
2636039e02dfSJerome Forissier             ssl->out_msg[11] = MBEDTLS_BYTE_0(cur_hs_frag_len);
263711fa71b9SJerome Forissier 
263811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12);
263911fa71b9SJerome Forissier 
264011fa71b9SJerome Forissier             /* Copy the handshake message content and set records fields */
264111fa71b9SJerome Forissier             memcpy(ssl->out_msg + 12, p, cur_hs_frag_len);
264211fa71b9SJerome Forissier             ssl->out_msglen = cur_hs_frag_len + 12;
264311fa71b9SJerome Forissier             ssl->out_msgtype = cur->type;
264411fa71b9SJerome Forissier 
264511fa71b9SJerome Forissier             /* Update position inside current message */
264611fa71b9SJerome Forissier             ssl->handshake->cur_msg_p += cur_hs_frag_len;
264711fa71b9SJerome Forissier         }
264811fa71b9SJerome Forissier 
264911fa71b9SJerome Forissier         /* If done with the current message move to the next one if any */
265032b31808SJens Wiklander         if (ssl->handshake->cur_msg_p >= cur->p + cur->len) {
265132b31808SJens Wiklander             if (cur->next != NULL) {
265211fa71b9SJerome Forissier                 ssl->handshake->cur_msg = cur->next;
265311fa71b9SJerome Forissier                 ssl->handshake->cur_msg_p = cur->next->p + 12;
265432b31808SJens Wiklander             } else {
265511fa71b9SJerome Forissier                 ssl->handshake->cur_msg = NULL;
265611fa71b9SJerome Forissier                 ssl->handshake->cur_msg_p = NULL;
265711fa71b9SJerome Forissier             }
265811fa71b9SJerome Forissier         }
265911fa71b9SJerome Forissier 
266011fa71b9SJerome Forissier         /* Actually send the message out */
266132b31808SJens Wiklander         if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
266211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
266332b31808SJens Wiklander             return ret;
266411fa71b9SJerome Forissier         }
266511fa71b9SJerome Forissier     }
266611fa71b9SJerome Forissier 
266732b31808SJens Wiklander     if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
266832b31808SJens Wiklander         return ret;
266932b31808SJens Wiklander     }
267011fa71b9SJerome Forissier 
267111fa71b9SJerome Forissier     /* Update state and set timer */
267232b31808SJens Wiklander     if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
267311fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
267432b31808SJens Wiklander     } else {
267511fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
267611fa71b9SJerome Forissier         mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
267711fa71b9SJerome Forissier     }
267811fa71b9SJerome Forissier 
267911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit"));
268011fa71b9SJerome Forissier 
268132b31808SJens Wiklander     return 0;
268211fa71b9SJerome Forissier }
268311fa71b9SJerome Forissier 
268411fa71b9SJerome Forissier /*
268511fa71b9SJerome Forissier  * To be called when the last message of an incoming flight is received.
268611fa71b9SJerome Forissier  */
268711fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl)
268811fa71b9SJerome Forissier {
268911fa71b9SJerome Forissier     /* We won't need to resend that one any more */
269011fa71b9SJerome Forissier     mbedtls_ssl_flight_free(ssl->handshake->flight);
269111fa71b9SJerome Forissier     ssl->handshake->flight = NULL;
269211fa71b9SJerome Forissier     ssl->handshake->cur_msg = NULL;
269311fa71b9SJerome Forissier 
269411fa71b9SJerome Forissier     /* The next incoming flight will start with this msg_seq */
269511fa71b9SJerome Forissier     ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
269611fa71b9SJerome Forissier 
269711fa71b9SJerome Forissier     /* We don't want to remember CCS's across flight boundaries. */
269811fa71b9SJerome Forissier     ssl->handshake->buffering.seen_ccs = 0;
269911fa71b9SJerome Forissier 
270011fa71b9SJerome Forissier     /* Clear future message buffering structure. */
270111fa71b9SJerome Forissier     mbedtls_ssl_buffering_free(ssl);
270211fa71b9SJerome Forissier 
270311fa71b9SJerome Forissier     /* Cancel timer */
270411fa71b9SJerome Forissier     mbedtls_ssl_set_timer(ssl, 0);
270511fa71b9SJerome Forissier 
270611fa71b9SJerome Forissier     if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
270732b31808SJens Wiklander         ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
270811fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
270932b31808SJens Wiklander     } else {
271011fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
271111fa71b9SJerome Forissier     }
271232b31808SJens Wiklander }
271311fa71b9SJerome Forissier 
271411fa71b9SJerome Forissier /*
271511fa71b9SJerome Forissier  * To be called when the last message of an outgoing flight is send.
271611fa71b9SJerome Forissier  */
271711fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl)
271811fa71b9SJerome Forissier {
271911fa71b9SJerome Forissier     ssl_reset_retransmit_timeout(ssl);
272011fa71b9SJerome Forissier     mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
272111fa71b9SJerome Forissier 
272211fa71b9SJerome Forissier     if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
272332b31808SJens Wiklander         ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
272411fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
272532b31808SJens Wiklander     } else {
272611fa71b9SJerome Forissier         ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
272711fa71b9SJerome Forissier     }
272832b31808SJens Wiklander }
272911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
273011fa71b9SJerome Forissier 
273111fa71b9SJerome Forissier /*
273211fa71b9SJerome Forissier  * Handshake layer functions
273311fa71b9SJerome Forissier  */
2734b0563631STom Van Eyck int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
273532b31808SJens Wiklander                                     unsigned char **buf, size_t *buf_len)
273632b31808SJens Wiklander {
273732b31808SJens Wiklander     /*
273832b31808SJens Wiklander      * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 )
273932b31808SJens Wiklander      *    ...
274032b31808SJens Wiklander      *    HandshakeType msg_type;
274132b31808SJens Wiklander      *    uint24 length;
274232b31808SJens Wiklander      *    ...
274332b31808SJens Wiklander      */
274432b31808SJens Wiklander     *buf = ssl->out_msg + 4;
274532b31808SJens Wiklander     *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
274632b31808SJens Wiklander 
274732b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
274832b31808SJens Wiklander     ssl->out_msg[0]  = hs_type;
274932b31808SJens Wiklander 
275032b31808SJens Wiklander     return 0;
275132b31808SJens Wiklander }
275211fa71b9SJerome Forissier 
275311fa71b9SJerome Forissier /*
275411fa71b9SJerome Forissier  * Write (DTLS: or queue) current handshake (including CCS) message.
275511fa71b9SJerome Forissier  *
275611fa71b9SJerome Forissier  *  - fill in handshake headers
275711fa71b9SJerome Forissier  *  - update handshake checksum
275811fa71b9SJerome Forissier  *  - DTLS: save message for resending
275911fa71b9SJerome Forissier  *  - then pass to the record layer
276011fa71b9SJerome Forissier  *
276111fa71b9SJerome Forissier  * DTLS: except for HelloRequest, messages are only queued, and will only be
276211fa71b9SJerome Forissier  * actually sent when calling flight_transmit() or resend().
276311fa71b9SJerome Forissier  *
276411fa71b9SJerome Forissier  * Inputs:
276511fa71b9SJerome Forissier  *  - ssl->out_msglen: 4 + actual handshake message len
276611fa71b9SJerome Forissier  *      (4 is the size of handshake headers for TLS)
276711fa71b9SJerome Forissier  *  - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
276811fa71b9SJerome Forissier  *  - ssl->out_msg + 4: the handshake message body
276911fa71b9SJerome Forissier  *
277011fa71b9SJerome Forissier  * Outputs, ie state before passing to flight_append() or write_record():
277111fa71b9SJerome Forissier  *   - ssl->out_msglen: the length of the record contents
277211fa71b9SJerome Forissier  *      (including handshake headers but excluding record headers)
277311fa71b9SJerome Forissier  *   - ssl->out_msg: the record contents (handshake headers + content)
277411fa71b9SJerome Forissier  */
277532b31808SJens Wiklander int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl,
277632b31808SJens Wiklander                                         int update_checksum,
277732b31808SJens Wiklander                                         int force_flush)
277811fa71b9SJerome Forissier {
277911fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
278011fa71b9SJerome Forissier     const size_t hs_len = ssl->out_msglen - 4;
278111fa71b9SJerome Forissier     const unsigned char hs_type = ssl->out_msg[0];
278211fa71b9SJerome Forissier 
278311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message"));
278411fa71b9SJerome Forissier 
278511fa71b9SJerome Forissier     /*
278611fa71b9SJerome Forissier      * Sanity checks
278711fa71b9SJerome Forissier      */
278811fa71b9SJerome Forissier     if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE          &&
278932b31808SJens Wiklander         ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
279011fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
279132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
279211fa71b9SJerome Forissier     }
279311fa71b9SJerome Forissier 
279411fa71b9SJerome Forissier     /* Whenever we send anything different from a
279511fa71b9SJerome Forissier      * HelloRequest we should be in a handshake - double check. */
279611fa71b9SJerome Forissier     if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
279711fa71b9SJerome Forissier           hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST) &&
279832b31808SJens Wiklander         ssl->handshake == NULL) {
279911fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
280032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
280111fa71b9SJerome Forissier     }
280211fa71b9SJerome Forissier 
280311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
280411fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
280511fa71b9SJerome Forissier         ssl->handshake != NULL &&
280632b31808SJens Wiklander         ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
280711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
280832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
280911fa71b9SJerome Forissier     }
281011fa71b9SJerome Forissier #endif
281111fa71b9SJerome Forissier 
281211fa71b9SJerome Forissier     /* Double-check that we did not exceed the bounds
281311fa71b9SJerome Forissier      * of the outgoing record buffer.
281411fa71b9SJerome Forissier      * This should never fail as the various message
281511fa71b9SJerome Forissier      * writing functions must obey the bounds of the
281611fa71b9SJerome Forissier      * outgoing record buffer, but better be safe.
281711fa71b9SJerome Forissier      *
281811fa71b9SJerome Forissier      * Note: We deliberately do not check for the MTU or MFL here.
281911fa71b9SJerome Forissier      */
282032b31808SJens Wiklander     if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) {
282111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: "
28227901324dSJerome Forissier                                   "size %" MBEDTLS_PRINTF_SIZET
28237901324dSJerome Forissier                                   ", maximum %" MBEDTLS_PRINTF_SIZET,
28247901324dSJerome Forissier                                   ssl->out_msglen,
28257901324dSJerome Forissier                                   (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
282632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
282711fa71b9SJerome Forissier     }
282811fa71b9SJerome Forissier 
282911fa71b9SJerome Forissier     /*
283011fa71b9SJerome Forissier      * Fill handshake headers
283111fa71b9SJerome Forissier      */
283232b31808SJens Wiklander     if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
2833039e02dfSJerome Forissier         ssl->out_msg[1] = MBEDTLS_BYTE_2(hs_len);
2834039e02dfSJerome Forissier         ssl->out_msg[2] = MBEDTLS_BYTE_1(hs_len);
2835039e02dfSJerome Forissier         ssl->out_msg[3] = MBEDTLS_BYTE_0(hs_len);
283611fa71b9SJerome Forissier 
283711fa71b9SJerome Forissier         /*
283811fa71b9SJerome Forissier          * DTLS has additional fields in the Handshake layer,
283911fa71b9SJerome Forissier          * between the length field and the actual payload:
284011fa71b9SJerome Forissier          *      uint16 message_seq;
284111fa71b9SJerome Forissier          *      uint24 fragment_offset;
284211fa71b9SJerome Forissier          *      uint24 fragment_length;
284311fa71b9SJerome Forissier          */
284411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
284532b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
284611fa71b9SJerome Forissier             /* Make room for the additional DTLS fields */
284732b31808SJens Wiklander             if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) {
284811fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS handshake message too large: "
284932b31808SJens Wiklander                                           "size %" MBEDTLS_PRINTF_SIZET ", maximum %"
285032b31808SJens Wiklander                                           MBEDTLS_PRINTF_SIZET,
28517901324dSJerome Forissier                                           hs_len,
28527901324dSJerome Forissier                                           (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - 12)));
285332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
285411fa71b9SJerome Forissier             }
285511fa71b9SJerome Forissier 
285611fa71b9SJerome Forissier             memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len);
285711fa71b9SJerome Forissier             ssl->out_msglen += 8;
285811fa71b9SJerome Forissier 
285911fa71b9SJerome Forissier             /* Write message_seq and update it, except for HelloRequest */
286032b31808SJens Wiklander             if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) {
2861039e02dfSJerome Forissier                 MBEDTLS_PUT_UINT16_BE(ssl->handshake->out_msg_seq, ssl->out_msg, 4);
286211fa71b9SJerome Forissier                 ++(ssl->handshake->out_msg_seq);
286332b31808SJens Wiklander             } else {
286411fa71b9SJerome Forissier                 ssl->out_msg[4] = 0;
286511fa71b9SJerome Forissier                 ssl->out_msg[5] = 0;
286611fa71b9SJerome Forissier             }
286711fa71b9SJerome Forissier 
286811fa71b9SJerome Forissier             /* Handshake hashes are computed without fragmentation,
286911fa71b9SJerome Forissier              * so set frag_offset = 0 and frag_len = hs_len for now */
287011fa71b9SJerome Forissier             memset(ssl->out_msg + 6, 0x00, 3);
287111fa71b9SJerome Forissier             memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3);
287211fa71b9SJerome Forissier         }
287311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
287411fa71b9SJerome Forissier 
287511fa71b9SJerome Forissier         /* Update running hashes of handshake messages seen */
287632b31808SJens Wiklander         if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) {
287732b31808SJens Wiklander             ret = ssl->handshake->update_checksum(ssl, ssl->out_msg,
287832b31808SJens Wiklander                                                   ssl->out_msglen);
287932b31808SJens Wiklander             if (ret != 0) {
288032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
288132b31808SJens Wiklander                 return ret;
288232b31808SJens Wiklander             }
288332b31808SJens Wiklander         }
288411fa71b9SJerome Forissier     }
288511fa71b9SJerome Forissier 
288611fa71b9SJerome Forissier     /* Either send now, or just save to be sent (and resent) later */
288711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
288811fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
288911fa71b9SJerome Forissier         !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
289032b31808SJens Wiklander           hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST)) {
289132b31808SJens Wiklander         if ((ret = ssl_flight_append(ssl)) != 0) {
289211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret);
289332b31808SJens Wiklander             return ret;
289411fa71b9SJerome Forissier         }
289532b31808SJens Wiklander     } else
289611fa71b9SJerome Forissier #endif
289711fa71b9SJerome Forissier     {
289832b31808SJens Wiklander         if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
289911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret);
290032b31808SJens Wiklander             return ret;
290111fa71b9SJerome Forissier         }
290211fa71b9SJerome Forissier     }
290311fa71b9SJerome Forissier 
290411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message"));
290511fa71b9SJerome Forissier 
290632b31808SJens Wiklander     return 0;
290732b31808SJens Wiklander }
290832b31808SJens Wiklander 
290932b31808SJens Wiklander int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl,
291032b31808SJens Wiklander                                      size_t buf_len, size_t msg_len)
291132b31808SJens Wiklander {
291232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
291332b31808SJens Wiklander     size_t msg_with_header_len;
291432b31808SJens Wiklander     ((void) buf_len);
291532b31808SJens Wiklander 
291632b31808SJens Wiklander     /* Add reserved 4 bytes for handshake header */
291732b31808SJens Wiklander     msg_with_header_len = msg_len + 4;
291832b31808SJens Wiklander     ssl->out_msglen = msg_with_header_len;
291932b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_handshake_msg_ext(ssl, 0, 0));
292032b31808SJens Wiklander 
292132b31808SJens Wiklander cleanup:
292232b31808SJens Wiklander     return ret;
292311fa71b9SJerome Forissier }
292411fa71b9SJerome Forissier 
292511fa71b9SJerome Forissier /*
292611fa71b9SJerome Forissier  * Record layer functions
292711fa71b9SJerome Forissier  */
292811fa71b9SJerome Forissier 
292911fa71b9SJerome Forissier /*
293011fa71b9SJerome Forissier  * Write current record.
293111fa71b9SJerome Forissier  *
293211fa71b9SJerome Forissier  * Uses:
293311fa71b9SJerome Forissier  *  - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
293411fa71b9SJerome Forissier  *  - ssl->out_msglen: length of the record content (excl headers)
293511fa71b9SJerome Forissier  *  - ssl->out_msg: record content
293611fa71b9SJerome Forissier  */
293732b31808SJens Wiklander int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush)
293811fa71b9SJerome Forissier {
293911fa71b9SJerome Forissier     int ret, done = 0;
294011fa71b9SJerome Forissier     size_t len = ssl->out_msglen;
294132b31808SJens Wiklander     int flush = force_flush;
294211fa71b9SJerome Forissier 
294311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record"));
294411fa71b9SJerome Forissier 
294532b31808SJens Wiklander     if (!done) {
294611fa71b9SJerome Forissier         unsigned i;
294711fa71b9SJerome Forissier         size_t protected_record_size;
294811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
294911fa71b9SJerome Forissier         size_t out_buf_len = ssl->out_buf_len;
295011fa71b9SJerome Forissier #else
295111fa71b9SJerome Forissier         size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
295211fa71b9SJerome Forissier #endif
295311fa71b9SJerome Forissier         /* Skip writing the record content type to after the encryption,
295411fa71b9SJerome Forissier          * as it may change when using the CID extension. */
295532b31808SJens Wiklander         mbedtls_ssl_protocol_version tls_ver = ssl->tls_version;
295632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
295732b31808SJens Wiklander         /* TLS 1.3 still uses the TLS 1.2 version identifier
295832b31808SJens Wiklander          * for backwards compatibility. */
295932b31808SJens Wiklander         if (tls_ver == MBEDTLS_SSL_VERSION_TLS1_3) {
296032b31808SJens Wiklander             tls_ver = MBEDTLS_SSL_VERSION_TLS1_2;
296132b31808SJens Wiklander         }
296232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
296332b31808SJens Wiklander         mbedtls_ssl_write_version(ssl->out_hdr + 1, ssl->conf->transport,
296432b31808SJens Wiklander                                   tls_ver);
296511fa71b9SJerome Forissier 
296632b31808SJens Wiklander         memcpy(ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
2967039e02dfSJerome Forissier         MBEDTLS_PUT_UINT16_BE(len, ssl->out_len, 0);
296811fa71b9SJerome Forissier 
296932b31808SJens Wiklander         if (ssl->transform_out != NULL) {
297011fa71b9SJerome Forissier             mbedtls_record rec;
297111fa71b9SJerome Forissier 
297211fa71b9SJerome Forissier             rec.buf         = ssl->out_iv;
2973b0563631STom Van Eyck             rec.buf_len     = out_buf_len - (size_t) (ssl->out_iv - ssl->out_buf);
297411fa71b9SJerome Forissier             rec.data_len    = ssl->out_msglen;
2975b0563631STom Van Eyck             rec.data_offset = (size_t) (ssl->out_msg - rec.buf);
297611fa71b9SJerome Forissier 
297732b31808SJens Wiklander             memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr));
297832b31808SJens Wiklander             mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver);
297911fa71b9SJerome Forissier             rec.type = ssl->out_msgtype;
298011fa71b9SJerome Forissier 
298111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
298211fa71b9SJerome Forissier             /* The CID is set by mbedtls_ssl_encrypt_buf(). */
298311fa71b9SJerome Forissier             rec.cid_len = 0;
298411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
298511fa71b9SJerome Forissier 
298611fa71b9SJerome Forissier             if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec,
298732b31808SJens Wiklander                                                ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
298811fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret);
298932b31808SJens Wiklander                 return ret;
299011fa71b9SJerome Forissier             }
299111fa71b9SJerome Forissier 
299232b31808SJens Wiklander             if (rec.data_offset != 0) {
299311fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
299432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
299511fa71b9SJerome Forissier             }
299611fa71b9SJerome Forissier 
299711fa71b9SJerome Forissier             /* Update the record content type and CID. */
299811fa71b9SJerome Forissier             ssl->out_msgtype = rec.type;
299911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
300011fa71b9SJerome Forissier             memcpy(ssl->out_cid, rec.cid, rec.cid_len);
300111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
300211fa71b9SJerome Forissier             ssl->out_msglen = len = rec.data_len;
3003039e02dfSJerome Forissier             MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->out_len, 0);
300411fa71b9SJerome Forissier         }
300511fa71b9SJerome Forissier 
300611fa71b9SJerome Forissier         protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl);
300711fa71b9SJerome Forissier 
300811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
300911fa71b9SJerome Forissier         /* In case of DTLS, double-check that we don't exceed
301011fa71b9SJerome Forissier          * the remaining space in the datagram. */
301132b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
301211fa71b9SJerome Forissier             ret = ssl_get_remaining_space_in_datagram(ssl);
301332b31808SJens Wiklander             if (ret < 0) {
301432b31808SJens Wiklander                 return ret;
301532b31808SJens Wiklander             }
301611fa71b9SJerome Forissier 
301732b31808SJens Wiklander             if (protected_record_size > (size_t) ret) {
301811fa71b9SJerome Forissier                 /* Should never happen */
301932b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
302011fa71b9SJerome Forissier             }
302111fa71b9SJerome Forissier         }
302211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
302311fa71b9SJerome Forissier 
302411fa71b9SJerome Forissier         /* Now write the potentially updated record content type. */
302511fa71b9SJerome Forissier         ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
302611fa71b9SJerome Forissier 
30277901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("output record: msgtype = %u, "
30287901324dSJerome Forissier                                   "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
302911fa71b9SJerome Forissier                                   ssl->out_hdr[0], ssl->out_hdr[1],
303011fa71b9SJerome Forissier                                   ssl->out_hdr[2], len));
303111fa71b9SJerome Forissier 
303211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
303311fa71b9SJerome Forissier                               ssl->out_hdr, protected_record_size);
303411fa71b9SJerome Forissier 
303511fa71b9SJerome Forissier         ssl->out_left += protected_record_size;
303611fa71b9SJerome Forissier         ssl->out_hdr  += protected_record_size;
303711fa71b9SJerome Forissier         mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
303811fa71b9SJerome Forissier 
303932b31808SJens Wiklander         for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--) {
304032b31808SJens Wiklander             if (++ssl->cur_out_ctr[i - 1] != 0) {
304111fa71b9SJerome Forissier                 break;
304232b31808SJens Wiklander             }
304332b31808SJens Wiklander         }
304411fa71b9SJerome Forissier 
304532b31808SJens Wiklander         /* The loop goes to its end if the counter is wrapping */
304632b31808SJens Wiklander         if (i == mbedtls_ssl_ep_len(ssl)) {
304711fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap"));
304832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
304911fa71b9SJerome Forissier         }
305011fa71b9SJerome Forissier     }
305111fa71b9SJerome Forissier 
305211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
305311fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
305432b31808SJens Wiklander         flush == SSL_DONT_FORCE_FLUSH) {
305511fa71b9SJerome Forissier         size_t remaining;
305611fa71b9SJerome Forissier         ret = ssl_get_remaining_payload_in_datagram(ssl);
305732b31808SJens Wiklander         if (ret < 0) {
305811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram",
305911fa71b9SJerome Forissier                                   ret);
306032b31808SJens Wiklander             return ret;
306111fa71b9SJerome Forissier         }
306211fa71b9SJerome Forissier 
306311fa71b9SJerome Forissier         remaining = (size_t) ret;
306432b31808SJens Wiklander         if (remaining == 0) {
306511fa71b9SJerome Forissier             flush = SSL_FORCE_FLUSH;
306632b31808SJens Wiklander         } else {
306732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2,
306832b31808SJens Wiklander                                   ("Still %u bytes available in current datagram",
306932b31808SJens Wiklander                                    (unsigned) remaining));
307011fa71b9SJerome Forissier         }
307111fa71b9SJerome Forissier     }
307211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
307311fa71b9SJerome Forissier 
307411fa71b9SJerome Forissier     if ((flush == SSL_FORCE_FLUSH) &&
307532b31808SJens Wiklander         (ret = mbedtls_ssl_flush_output(ssl)) != 0) {
307611fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
307732b31808SJens Wiklander         return ret;
307811fa71b9SJerome Forissier     }
307911fa71b9SJerome Forissier 
308011fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record"));
308111fa71b9SJerome Forissier 
308232b31808SJens Wiklander     return 0;
308311fa71b9SJerome Forissier }
308411fa71b9SJerome Forissier 
308511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
308611fa71b9SJerome Forissier 
3087039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
308811fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl)
308911fa71b9SJerome Forissier {
309011fa71b9SJerome Forissier     if (ssl->in_msglen < ssl->in_hslen ||
309111fa71b9SJerome Forissier         memcmp(ssl->in_msg + 6, "\0\0\0",        3) != 0 ||
309232b31808SJens Wiklander         memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) {
309332b31808SJens Wiklander         return 1;
309411fa71b9SJerome Forissier     }
309532b31808SJens Wiklander     return 0;
309611fa71b9SJerome Forissier }
309711fa71b9SJerome Forissier 
309811fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
309911fa71b9SJerome Forissier {
3100b0563631STom Van Eyck     return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
310111fa71b9SJerome Forissier }
310211fa71b9SJerome Forissier 
310311fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
310411fa71b9SJerome Forissier {
3105b0563631STom Van Eyck     return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
310611fa71b9SJerome Forissier }
310711fa71b9SJerome Forissier 
3108039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
310911fa71b9SJerome Forissier static int ssl_check_hs_header(mbedtls_ssl_context const *ssl)
311011fa71b9SJerome Forissier {
311111fa71b9SJerome Forissier     uint32_t msg_len, frag_off, frag_len;
311211fa71b9SJerome Forissier 
311311fa71b9SJerome Forissier     msg_len  = ssl_get_hs_total_len(ssl);
311411fa71b9SJerome Forissier     frag_off = ssl_get_hs_frag_off(ssl);
311511fa71b9SJerome Forissier     frag_len = ssl_get_hs_frag_len(ssl);
311611fa71b9SJerome Forissier 
311732b31808SJens Wiklander     if (frag_off > msg_len) {
311832b31808SJens Wiklander         return -1;
311932b31808SJens Wiklander     }
312011fa71b9SJerome Forissier 
312132b31808SJens Wiklander     if (frag_len > msg_len - frag_off) {
312232b31808SJens Wiklander         return -1;
312332b31808SJens Wiklander     }
312411fa71b9SJerome Forissier 
312532b31808SJens Wiklander     if (frag_len + 12 > ssl->in_msglen) {
312632b31808SJens Wiklander         return -1;
312732b31808SJens Wiklander     }
312811fa71b9SJerome Forissier 
312932b31808SJens Wiklander     return 0;
313011fa71b9SJerome Forissier }
313111fa71b9SJerome Forissier 
313211fa71b9SJerome Forissier /*
313311fa71b9SJerome Forissier  * Mark bits in bitmask (used for DTLS HS reassembly)
313411fa71b9SJerome Forissier  */
313511fa71b9SJerome Forissier static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len)
313611fa71b9SJerome Forissier {
313711fa71b9SJerome Forissier     unsigned int start_bits, end_bits;
313811fa71b9SJerome Forissier 
313911fa71b9SJerome Forissier     start_bits = 8 - (offset % 8);
314032b31808SJens Wiklander     if (start_bits != 8) {
314111fa71b9SJerome Forissier         size_t first_byte_idx = offset / 8;
314211fa71b9SJerome Forissier 
314311fa71b9SJerome Forissier         /* Special case */
314432b31808SJens Wiklander         if (len <= start_bits) {
314532b31808SJens Wiklander             for (; len != 0; len--) {
314611fa71b9SJerome Forissier                 mask[first_byte_idx] |= 1 << (start_bits - len);
314732b31808SJens Wiklander             }
314811fa71b9SJerome Forissier 
314911fa71b9SJerome Forissier             /* Avoid potential issues with offset or len becoming invalid */
315011fa71b9SJerome Forissier             return;
315111fa71b9SJerome Forissier         }
315211fa71b9SJerome Forissier 
315311fa71b9SJerome Forissier         offset += start_bits; /* Now offset % 8 == 0 */
315411fa71b9SJerome Forissier         len -= start_bits;
315511fa71b9SJerome Forissier 
315632b31808SJens Wiklander         for (; start_bits != 0; start_bits--) {
315711fa71b9SJerome Forissier             mask[first_byte_idx] |= 1 << (start_bits - 1);
315811fa71b9SJerome Forissier         }
315932b31808SJens Wiklander     }
316011fa71b9SJerome Forissier 
316111fa71b9SJerome Forissier     end_bits = len % 8;
316232b31808SJens Wiklander     if (end_bits != 0) {
316311fa71b9SJerome Forissier         size_t last_byte_idx = (offset + len) / 8;
316411fa71b9SJerome Forissier 
316511fa71b9SJerome Forissier         len -= end_bits; /* Now len % 8 == 0 */
316611fa71b9SJerome Forissier 
316732b31808SJens Wiklander         for (; end_bits != 0; end_bits--) {
316811fa71b9SJerome Forissier             mask[last_byte_idx] |= 1 << (8 - end_bits);
316911fa71b9SJerome Forissier         }
317032b31808SJens Wiklander     }
317111fa71b9SJerome Forissier 
317211fa71b9SJerome Forissier     memset(mask + offset / 8, 0xFF, len / 8);
317311fa71b9SJerome Forissier }
317411fa71b9SJerome Forissier 
317511fa71b9SJerome Forissier /*
317611fa71b9SJerome Forissier  * Check that bitmask is full
317711fa71b9SJerome Forissier  */
3178039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
317911fa71b9SJerome Forissier static int ssl_bitmask_check(unsigned char *mask, size_t len)
318011fa71b9SJerome Forissier {
318111fa71b9SJerome Forissier     size_t i;
318211fa71b9SJerome Forissier 
318332b31808SJens Wiklander     for (i = 0; i < len / 8; i++) {
318432b31808SJens Wiklander         if (mask[i] != 0xFF) {
318532b31808SJens Wiklander             return -1;
318632b31808SJens Wiklander         }
318732b31808SJens Wiklander     }
318811fa71b9SJerome Forissier 
318932b31808SJens Wiklander     for (i = 0; i < len % 8; i++) {
319032b31808SJens Wiklander         if ((mask[len / 8] & (1 << (7 - i))) == 0) {
319132b31808SJens Wiklander             return -1;
319232b31808SJens Wiklander         }
319332b31808SJens Wiklander     }
319411fa71b9SJerome Forissier 
319532b31808SJens Wiklander     return 0;
319611fa71b9SJerome Forissier }
319711fa71b9SJerome Forissier 
319811fa71b9SJerome Forissier /* msg_len does not include the handshake header */
319911fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size(size_t msg_len,
320011fa71b9SJerome Forissier                                              unsigned add_bitmap)
320111fa71b9SJerome Forissier {
320211fa71b9SJerome Forissier     size_t alloc_len;
320311fa71b9SJerome Forissier 
320411fa71b9SJerome Forissier     alloc_len  = 12;                                 /* Handshake header */
320511fa71b9SJerome Forissier     alloc_len += msg_len;                            /* Content buffer   */
320611fa71b9SJerome Forissier 
320732b31808SJens Wiklander     if (add_bitmap) {
320811fa71b9SJerome Forissier         alloc_len += msg_len / 8 + (msg_len % 8 != 0);   /* Bitmap       */
320911fa71b9SJerome Forissier 
321032b31808SJens Wiklander     }
321132b31808SJens Wiklander     return alloc_len;
321211fa71b9SJerome Forissier }
321311fa71b9SJerome Forissier 
321411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
321511fa71b9SJerome Forissier 
321611fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
321711fa71b9SJerome Forissier {
3218b0563631STom Van Eyck     return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
321911fa71b9SJerome Forissier }
322011fa71b9SJerome Forissier 
322111fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
322211fa71b9SJerome Forissier {
322332b31808SJens Wiklander     if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
32247901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
322511fa71b9SJerome Forissier                                   ssl->in_msglen));
322632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
322711fa71b9SJerome Forissier     }
322811fa71b9SJerome Forissier 
322911fa71b9SJerome Forissier     ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
323011fa71b9SJerome Forissier 
323111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
323232b31808SJens Wiklander                               " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
323332b31808SJens Wiklander                               MBEDTLS_PRINTF_SIZET,
323411fa71b9SJerome Forissier                               ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
323511fa71b9SJerome Forissier 
323611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
323732b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
323811fa71b9SJerome Forissier         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3239b0563631STom Van Eyck         unsigned int recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
324011fa71b9SJerome Forissier 
324132b31808SJens Wiklander         if (ssl_check_hs_header(ssl) != 0) {
324211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header"));
324332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
324411fa71b9SJerome Forissier         }
324511fa71b9SJerome Forissier 
324611fa71b9SJerome Forissier         if (ssl->handshake != NULL &&
324732b31808SJens Wiklander             ((mbedtls_ssl_is_handshake_over(ssl) == 0 &&
324811fa71b9SJerome Forissier               recv_msg_seq != ssl->handshake->in_msg_seq) ||
324932b31808SJens Wiklander              (mbedtls_ssl_is_handshake_over(ssl) == 1 &&
325032b31808SJens Wiklander               ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) {
325132b31808SJens Wiklander             if (recv_msg_seq > ssl->handshake->in_msg_seq) {
325232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2,
325332b31808SJens Wiklander                                       (
325432b31808SJens Wiklander                                           "received future handshake message of sequence number %u (next %u)",
325511fa71b9SJerome Forissier                                           recv_msg_seq,
325611fa71b9SJerome Forissier                                           ssl->handshake->in_msg_seq));
325732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
325811fa71b9SJerome Forissier             }
325911fa71b9SJerome Forissier 
326011fa71b9SJerome Forissier             /* Retransmit only on last message from previous flight, to avoid
326111fa71b9SJerome Forissier              * too many retransmissions.
326211fa71b9SJerome Forissier              * Besides, No sane server ever retransmits HelloVerifyRequest */
326311fa71b9SJerome Forissier             if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
326432b31808SJens Wiklander                 ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
326511fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("received message from last flight, "
32667901324dSJerome Forissier                                           "message_seq = %u, start_of_flight = %u",
326711fa71b9SJerome Forissier                                           recv_msg_seq,
326811fa71b9SJerome Forissier                                           ssl->handshake->in_flight_start_seq));
326911fa71b9SJerome Forissier 
327032b31808SJens Wiklander                 if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
327111fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
327232b31808SJens Wiklander                     return ret;
327311fa71b9SJerome Forissier                 }
327432b31808SJens Wiklander             } else {
327511fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: "
32767901324dSJerome Forissier                                           "message_seq = %u, expected = %u",
327711fa71b9SJerome Forissier                                           recv_msg_seq,
327811fa71b9SJerome Forissier                                           ssl->handshake->in_msg_seq));
327911fa71b9SJerome Forissier             }
328011fa71b9SJerome Forissier 
328132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
328211fa71b9SJerome Forissier         }
328311fa71b9SJerome Forissier         /* Wait until message completion to increment in_msg_seq */
328411fa71b9SJerome Forissier 
328511fa71b9SJerome Forissier         /* Message reassembly is handled alongside buffering of future
328611fa71b9SJerome Forissier          * messages; the commonality is that both handshake fragments and
328711fa71b9SJerome Forissier          * future messages cannot be forwarded immediately to the
328811fa71b9SJerome Forissier          * handshake logic layer. */
328932b31808SJens Wiklander         if (ssl_hs_is_proper_fragment(ssl) == 1) {
329011fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("found fragmented DTLS handshake message"));
329132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
329211fa71b9SJerome Forissier         }
329332b31808SJens Wiklander     } else
329411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
329511fa71b9SJerome Forissier     /* With TLS we don't handle fragmentation (for now) */
329632b31808SJens Wiklander     if (ssl->in_msglen < ssl->in_hslen) {
329711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported"));
329832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
329911fa71b9SJerome Forissier     }
330011fa71b9SJerome Forissier 
330132b31808SJens Wiklander     return 0;
330211fa71b9SJerome Forissier }
330311fa71b9SJerome Forissier 
330432b31808SJens Wiklander int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
330511fa71b9SJerome Forissier {
330632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
330711fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
330811fa71b9SJerome Forissier 
330932b31808SJens Wiklander     if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) {
331032b31808SJens Wiklander         ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
331132b31808SJens Wiklander         if (ret != 0) {
331232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
331332b31808SJens Wiklander             return ret;
331432b31808SJens Wiklander         }
331511fa71b9SJerome Forissier     }
331611fa71b9SJerome Forissier 
331711fa71b9SJerome Forissier     /* Handshake message is complete, increment counter */
331811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
331911fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
332032b31808SJens Wiklander         ssl->handshake != NULL) {
332111fa71b9SJerome Forissier         unsigned offset;
332211fa71b9SJerome Forissier         mbedtls_ssl_hs_buffer *hs_buf;
332311fa71b9SJerome Forissier 
332411fa71b9SJerome Forissier         /* Increment handshake sequence number */
332511fa71b9SJerome Forissier         hs->in_msg_seq++;
332611fa71b9SJerome Forissier 
332711fa71b9SJerome Forissier         /*
332811fa71b9SJerome Forissier          * Clear up handshake buffering and reassembly structure.
332911fa71b9SJerome Forissier          */
333011fa71b9SJerome Forissier 
333111fa71b9SJerome Forissier         /* Free first entry */
333211fa71b9SJerome Forissier         ssl_buffering_free_slot(ssl, 0);
333311fa71b9SJerome Forissier 
333411fa71b9SJerome Forissier         /* Shift all other entries */
333511fa71b9SJerome Forissier         for (offset = 0, hs_buf = &hs->buffering.hs[0];
333611fa71b9SJerome Forissier              offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
333732b31808SJens Wiklander              offset++, hs_buf++) {
333811fa71b9SJerome Forissier             *hs_buf = *(hs_buf + 1);
333911fa71b9SJerome Forissier         }
334011fa71b9SJerome Forissier 
334111fa71b9SJerome Forissier         /* Create a fresh last entry */
334211fa71b9SJerome Forissier         memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
334311fa71b9SJerome Forissier     }
334411fa71b9SJerome Forissier #endif
334532b31808SJens Wiklander     return 0;
334611fa71b9SJerome Forissier }
334711fa71b9SJerome Forissier 
334811fa71b9SJerome Forissier /*
334911fa71b9SJerome Forissier  * DTLS anti-replay: RFC 6347 4.1.2.6
335011fa71b9SJerome Forissier  *
335111fa71b9SJerome Forissier  * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
335211fa71b9SJerome Forissier  * Bit n is set iff record number in_window_top - n has been seen.
335311fa71b9SJerome Forissier  *
335411fa71b9SJerome Forissier  * Usually, in_window_top is the last record number seen and the lsb of
335511fa71b9SJerome Forissier  * in_window is set. The only exception is the initial state (record number 0
335611fa71b9SJerome Forissier  * not seen yet).
335711fa71b9SJerome Forissier  */
335811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
335911fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl)
336011fa71b9SJerome Forissier {
336111fa71b9SJerome Forissier     ssl->in_window_top = 0;
336211fa71b9SJerome Forissier     ssl->in_window = 0;
336311fa71b9SJerome Forissier }
336411fa71b9SJerome Forissier 
336511fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes(unsigned char *buf)
336611fa71b9SJerome Forissier {
336732b31808SJens Wiklander     return ((uint64_t) buf[0] << 40) |
336811fa71b9SJerome Forissier            ((uint64_t) buf[1] << 32) |
336911fa71b9SJerome Forissier            ((uint64_t) buf[2] << 24) |
337011fa71b9SJerome Forissier            ((uint64_t) buf[3] << 16) |
337111fa71b9SJerome Forissier            ((uint64_t) buf[4] <<  8) |
337232b31808SJens Wiklander            ((uint64_t) buf[5]);
337311fa71b9SJerome Forissier }
337411fa71b9SJerome Forissier 
3375039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
337611fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr)
337711fa71b9SJerome Forissier {
337811fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
337911fa71b9SJerome Forissier     unsigned char *original_in_ctr;
338011fa71b9SJerome Forissier 
338111fa71b9SJerome Forissier     // save original in_ctr
338211fa71b9SJerome Forissier     original_in_ctr = ssl->in_ctr;
338311fa71b9SJerome Forissier 
338411fa71b9SJerome Forissier     // use counter from record
338511fa71b9SJerome Forissier     ssl->in_ctr = record_in_ctr;
338611fa71b9SJerome Forissier 
338711fa71b9SJerome Forissier     ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *) ssl);
338811fa71b9SJerome Forissier 
338911fa71b9SJerome Forissier     // restore the counter
339011fa71b9SJerome Forissier     ssl->in_ctr = original_in_ctr;
339111fa71b9SJerome Forissier 
339211fa71b9SJerome Forissier     return ret;
339311fa71b9SJerome Forissier }
339411fa71b9SJerome Forissier 
339511fa71b9SJerome Forissier /*
339611fa71b9SJerome Forissier  * Return 0 if sequence number is acceptable, -1 otherwise
339711fa71b9SJerome Forissier  */
339811fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl)
339911fa71b9SJerome Forissier {
340011fa71b9SJerome Forissier     uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
340111fa71b9SJerome Forissier     uint64_t bit;
340211fa71b9SJerome Forissier 
340332b31808SJens Wiklander     if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
340432b31808SJens Wiklander         return 0;
340532b31808SJens Wiklander     }
340611fa71b9SJerome Forissier 
340732b31808SJens Wiklander     if (rec_seqnum > ssl->in_window_top) {
340832b31808SJens Wiklander         return 0;
340932b31808SJens Wiklander     }
341011fa71b9SJerome Forissier 
341111fa71b9SJerome Forissier     bit = ssl->in_window_top - rec_seqnum;
341211fa71b9SJerome Forissier 
341332b31808SJens Wiklander     if (bit >= 64) {
341432b31808SJens Wiklander         return -1;
341532b31808SJens Wiklander     }
341611fa71b9SJerome Forissier 
341732b31808SJens Wiklander     if ((ssl->in_window & ((uint64_t) 1 << bit)) != 0) {
341832b31808SJens Wiklander         return -1;
341932b31808SJens Wiklander     }
342011fa71b9SJerome Forissier 
342132b31808SJens Wiklander     return 0;
342211fa71b9SJerome Forissier }
342311fa71b9SJerome Forissier 
342411fa71b9SJerome Forissier /*
342511fa71b9SJerome Forissier  * Update replay window on new validated record
342611fa71b9SJerome Forissier  */
342711fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl)
342811fa71b9SJerome Forissier {
342911fa71b9SJerome Forissier     uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
343011fa71b9SJerome Forissier 
343132b31808SJens Wiklander     if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
343211fa71b9SJerome Forissier         return;
343332b31808SJens Wiklander     }
343411fa71b9SJerome Forissier 
343532b31808SJens Wiklander     if (rec_seqnum > ssl->in_window_top) {
343611fa71b9SJerome Forissier         /* Update window_top and the contents of the window */
343711fa71b9SJerome Forissier         uint64_t shift = rec_seqnum - ssl->in_window_top;
343811fa71b9SJerome Forissier 
343932b31808SJens Wiklander         if (shift >= 64) {
344011fa71b9SJerome Forissier             ssl->in_window = 1;
344132b31808SJens Wiklander         } else {
344211fa71b9SJerome Forissier             ssl->in_window <<= shift;
344311fa71b9SJerome Forissier             ssl->in_window |= 1;
344411fa71b9SJerome Forissier         }
344511fa71b9SJerome Forissier 
344611fa71b9SJerome Forissier         ssl->in_window_top = rec_seqnum;
344732b31808SJens Wiklander     } else {
344811fa71b9SJerome Forissier         /* Mark that number as seen in the current window */
344911fa71b9SJerome Forissier         uint64_t bit = ssl->in_window_top - rec_seqnum;
345011fa71b9SJerome Forissier 
345132b31808SJens Wiklander         if (bit < 64) { /* Always true, but be extra sure */
345211fa71b9SJerome Forissier             ssl->in_window |= (uint64_t) 1 << bit;
345311fa71b9SJerome Forissier         }
345411fa71b9SJerome Forissier     }
345532b31808SJens Wiklander }
345611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
345711fa71b9SJerome Forissier 
345811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
345911fa71b9SJerome Forissier /*
3460039e02dfSJerome Forissier  * Check if a datagram looks like a ClientHello with a valid cookie,
3461039e02dfSJerome Forissier  * and if it doesn't, generate a HelloVerifyRequest message.
346211fa71b9SJerome Forissier  * Both input and output include full DTLS headers.
346311fa71b9SJerome Forissier  *
346411fa71b9SJerome Forissier  * - if cookie is valid, return 0
346511fa71b9SJerome Forissier  * - if ClientHello looks superficially valid but cookie is not,
346611fa71b9SJerome Forissier  *   fill obuf and set olen, then
346711fa71b9SJerome Forissier  *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
346811fa71b9SJerome Forissier  * - otherwise return a specific error code
346911fa71b9SJerome Forissier  */
3470039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
3471039e02dfSJerome Forissier MBEDTLS_STATIC_TESTABLE
3472039e02dfSJerome Forissier int mbedtls_ssl_check_dtls_clihlo_cookie(
3473039e02dfSJerome Forissier     mbedtls_ssl_context *ssl,
347411fa71b9SJerome Forissier     const unsigned char *cli_id, size_t cli_id_len,
347511fa71b9SJerome Forissier     const unsigned char *in, size_t in_len,
347611fa71b9SJerome Forissier     unsigned char *obuf, size_t buf_len, size_t *olen)
347711fa71b9SJerome Forissier {
347832b31808SJens Wiklander     size_t sid_len, cookie_len, epoch, fragment_offset;
347911fa71b9SJerome Forissier     unsigned char *p;
348011fa71b9SJerome Forissier 
348111fa71b9SJerome Forissier     /*
348211fa71b9SJerome Forissier      * Structure of ClientHello with record and handshake headers,
348311fa71b9SJerome Forissier      * and expected values. We don't need to check a lot, more checks will be
348411fa71b9SJerome Forissier      * done when actually parsing the ClientHello - skipping those checks
348511fa71b9SJerome Forissier      * avoids code duplication and does not make cookie forging any easier.
348611fa71b9SJerome Forissier      *
348711fa71b9SJerome Forissier      *  0-0  ContentType type;                  copied, must be handshake
348811fa71b9SJerome Forissier      *  1-2  ProtocolVersion version;           copied
348911fa71b9SJerome Forissier      *  3-4  uint16 epoch;                      copied, must be 0
349011fa71b9SJerome Forissier      *  5-10 uint48 sequence_number;            copied
349111fa71b9SJerome Forissier      * 11-12 uint16 length;                     (ignored)
349211fa71b9SJerome Forissier      *
349311fa71b9SJerome Forissier      * 13-13 HandshakeType msg_type;            (ignored)
349411fa71b9SJerome Forissier      * 14-16 uint24 length;                     (ignored)
349511fa71b9SJerome Forissier      * 17-18 uint16 message_seq;                copied
349611fa71b9SJerome Forissier      * 19-21 uint24 fragment_offset;            copied, must be 0
349711fa71b9SJerome Forissier      * 22-24 uint24 fragment_length;            (ignored)
349811fa71b9SJerome Forissier      *
349911fa71b9SJerome Forissier      * 25-26 ProtocolVersion client_version;    (ignored)
350011fa71b9SJerome Forissier      * 27-58 Random random;                     (ignored)
350111fa71b9SJerome Forissier      * 59-xx SessionID session_id;              1 byte len + sid_len content
350211fa71b9SJerome Forissier      * 60+   opaque cookie<0..2^8-1>;           1 byte len + content
350311fa71b9SJerome Forissier      *       ...
350411fa71b9SJerome Forissier      *
350511fa71b9SJerome Forissier      * Minimum length is 61 bytes.
350611fa71b9SJerome Forissier      */
3507039e02dfSJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: in_len=%u",
3508039e02dfSJerome Forissier                               (unsigned) in_len));
3509039e02dfSJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "cli_id", cli_id, cli_id_len);
351032b31808SJens Wiklander     if (in_len < 61) {
3511039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: record too short"));
351232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3513039e02dfSJerome Forissier     }
351432b31808SJens Wiklander 
351532b31808SJens Wiklander     epoch = MBEDTLS_GET_UINT16_BE(in, 3);
351632b31808SJens Wiklander     fragment_offset = MBEDTLS_GET_UINT24_BE(in, 19);
351732b31808SJens Wiklander 
351832b31808SJens Wiklander     if (in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 ||
351932b31808SJens Wiklander         fragment_offset != 0) {
3520039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: not a good ClientHello"));
3521039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("    type=%u epoch=%u fragment_offset=%u",
352232b31808SJens Wiklander                                   in[0], (unsigned) epoch,
352332b31808SJens Wiklander                                   (unsigned) fragment_offset));
352432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
352511fa71b9SJerome Forissier     }
352611fa71b9SJerome Forissier 
352711fa71b9SJerome Forissier     sid_len = in[59];
352832b31808SJens Wiklander     if (59 + 1 + sid_len + 1 > in_len) {
3529039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: sid_len=%u > %u",
3530039e02dfSJerome Forissier                                   (unsigned) sid_len,
3531039e02dfSJerome Forissier                                   (unsigned) in_len - 61));
353232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3533039e02dfSJerome Forissier     }
3534039e02dfSJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "sid received from network",
3535039e02dfSJerome Forissier                           in + 60, sid_len);
353611fa71b9SJerome Forissier 
353711fa71b9SJerome Forissier     cookie_len = in[60 + sid_len];
353832b31808SJens Wiklander     if (59 + 1 + sid_len + 1 + cookie_len > in_len) {
3539039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: cookie_len=%u > %u",
3540039e02dfSJerome Forissier                                   (unsigned) cookie_len,
3541039e02dfSJerome Forissier                                   (unsigned) (in_len - sid_len - 61)));
354232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3543039e02dfSJerome Forissier     }
354411fa71b9SJerome Forissier 
3545039e02dfSJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "cookie received from network",
3546039e02dfSJerome Forissier                           in + sid_len + 61, cookie_len);
3547039e02dfSJerome Forissier     if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
3548039e02dfSJerome Forissier                                   in + sid_len + 61, cookie_len,
354932b31808SJens Wiklander                                   cli_id, cli_id_len) == 0) {
3550039e02dfSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: valid"));
355132b31808SJens Wiklander         return 0;
355211fa71b9SJerome Forissier     }
355311fa71b9SJerome Forissier 
355411fa71b9SJerome Forissier     /*
355511fa71b9SJerome Forissier      * If we get here, we've got an invalid cookie, let's prepare HVR.
355611fa71b9SJerome Forissier      *
355711fa71b9SJerome Forissier      *  0-0  ContentType type;                  copied
355811fa71b9SJerome Forissier      *  1-2  ProtocolVersion version;           copied
355911fa71b9SJerome Forissier      *  3-4  uint16 epoch;                      copied
356011fa71b9SJerome Forissier      *  5-10 uint48 sequence_number;            copied
356111fa71b9SJerome Forissier      * 11-12 uint16 length;                     olen - 13
356211fa71b9SJerome Forissier      *
356311fa71b9SJerome Forissier      * 13-13 HandshakeType msg_type;            hello_verify_request
356411fa71b9SJerome Forissier      * 14-16 uint24 length;                     olen - 25
356511fa71b9SJerome Forissier      * 17-18 uint16 message_seq;                copied
356611fa71b9SJerome Forissier      * 19-21 uint24 fragment_offset;            copied
356711fa71b9SJerome Forissier      * 22-24 uint24 fragment_length;            olen - 25
356811fa71b9SJerome Forissier      *
356911fa71b9SJerome Forissier      * 25-26 ProtocolVersion server_version;    0xfe 0xff
357011fa71b9SJerome Forissier      * 27-27 opaque cookie<0..2^8-1>;           cookie_len = olen - 27, cookie
357111fa71b9SJerome Forissier      *
357211fa71b9SJerome Forissier      * Minimum length is 28.
357311fa71b9SJerome Forissier      */
357432b31808SJens Wiklander     if (buf_len < 28) {
357532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
357632b31808SJens Wiklander     }
357711fa71b9SJerome Forissier 
357811fa71b9SJerome Forissier     /* Copy most fields and adapt others */
357911fa71b9SJerome Forissier     memcpy(obuf, in, 25);
358011fa71b9SJerome Forissier     obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
358111fa71b9SJerome Forissier     obuf[25] = 0xfe;
358211fa71b9SJerome Forissier     obuf[26] = 0xff;
358311fa71b9SJerome Forissier 
358411fa71b9SJerome Forissier     /* Generate and write actual cookie */
358511fa71b9SJerome Forissier     p = obuf + 28;
3586039e02dfSJerome Forissier     if (ssl->conf->f_cookie_write(ssl->conf->p_cookie,
3587039e02dfSJerome Forissier                                   &p, obuf + buf_len,
358832b31808SJens Wiklander                                   cli_id, cli_id_len) != 0) {
358932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
359011fa71b9SJerome Forissier     }
359111fa71b9SJerome Forissier 
3592b0563631STom Van Eyck     *olen = (size_t) (p - obuf);
359311fa71b9SJerome Forissier 
359411fa71b9SJerome Forissier     /* Go back and fill length fields */
359511fa71b9SJerome Forissier     obuf[27] = (unsigned char) (*olen - 28);
359611fa71b9SJerome Forissier 
3597039e02dfSJerome Forissier     obuf[14] = obuf[22] = MBEDTLS_BYTE_2(*olen - 25);
3598039e02dfSJerome Forissier     obuf[15] = obuf[23] = MBEDTLS_BYTE_1(*olen - 25);
3599039e02dfSJerome Forissier     obuf[16] = obuf[24] = MBEDTLS_BYTE_0(*olen - 25);
360011fa71b9SJerome Forissier 
3601039e02dfSJerome Forissier     MBEDTLS_PUT_UINT16_BE(*olen - 13, obuf, 11);
360211fa71b9SJerome Forissier 
360332b31808SJens Wiklander     return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
360411fa71b9SJerome Forissier }
360511fa71b9SJerome Forissier 
360611fa71b9SJerome Forissier /*
360711fa71b9SJerome Forissier  * Handle possible client reconnect with the same UDP quadruplet
360811fa71b9SJerome Forissier  * (RFC 6347 Section 4.2.8).
360911fa71b9SJerome Forissier  *
361011fa71b9SJerome Forissier  * Called by ssl_parse_record_header() in case we receive an epoch 0 record
361111fa71b9SJerome Forissier  * that looks like a ClientHello.
361211fa71b9SJerome Forissier  *
361311fa71b9SJerome Forissier  * - if the input looks like a ClientHello without cookies,
361411fa71b9SJerome Forissier  *   send back HelloVerifyRequest, then return 0
361511fa71b9SJerome Forissier  * - if the input looks like a ClientHello with a valid cookie,
361611fa71b9SJerome Forissier  *   reset the session of the current context, and
361711fa71b9SJerome Forissier  *   return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
361811fa71b9SJerome Forissier  * - if anything goes wrong, return a specific error code
361911fa71b9SJerome Forissier  *
362011fa71b9SJerome Forissier  * This function is called (through ssl_check_client_reconnect()) when an
362111fa71b9SJerome Forissier  * unexpected record is found in ssl_get_next_record(), which will discard the
362211fa71b9SJerome Forissier  * record if we return 0, and bubble up the return value otherwise (this
362311fa71b9SJerome Forissier  * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
362411fa71b9SJerome Forissier  * errors, and is the right thing to do in both cases).
362511fa71b9SJerome Forissier  */
3626039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
362711fa71b9SJerome Forissier static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl)
362811fa71b9SJerome Forissier {
362911fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3630b0563631STom Van Eyck     size_t len = 0;
363111fa71b9SJerome Forissier 
363211fa71b9SJerome Forissier     if (ssl->conf->f_cookie_write == NULL ||
363332b31808SJens Wiklander         ssl->conf->f_cookie_check == NULL) {
363411fa71b9SJerome Forissier         /* If we can't use cookies to verify reachability of the peer,
363511fa71b9SJerome Forissier          * drop the record. */
363611fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, "
363711fa71b9SJerome Forissier                                   "can't check reconnect validity"));
363832b31808SJens Wiklander         return 0;
363911fa71b9SJerome Forissier     }
364011fa71b9SJerome Forissier 
3641039e02dfSJerome Forissier     ret = mbedtls_ssl_check_dtls_clihlo_cookie(
3642039e02dfSJerome Forissier         ssl,
364311fa71b9SJerome Forissier         ssl->cli_id, ssl->cli_id_len,
364411fa71b9SJerome Forissier         ssl->in_buf, ssl->in_left,
364511fa71b9SJerome Forissier         ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len);
364611fa71b9SJerome Forissier 
3647039e02dfSJerome Forissier     MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret);
364811fa71b9SJerome Forissier 
364932b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
365011fa71b9SJerome Forissier         int send_ret;
365111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest"));
365211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
365311fa71b9SJerome Forissier                               ssl->out_buf, len);
365411fa71b9SJerome Forissier         /* Don't check write errors as we can't do anything here.
365511fa71b9SJerome Forissier          * If the error is permanent we'll catch it later,
365611fa71b9SJerome Forissier          * if it's not, then hopefully it'll work next time. */
365711fa71b9SJerome Forissier         send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len);
365811fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret);
365911fa71b9SJerome Forissier         (void) send_ret;
366011fa71b9SJerome Forissier 
366132b31808SJens Wiklander         return 0;
366211fa71b9SJerome Forissier     }
366311fa71b9SJerome Forissier 
366432b31808SJens Wiklander     if (ret == 0) {
366511fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context"));
366632b31808SJens Wiklander         if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) {
366711fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "reset", ret);
366832b31808SJens Wiklander             return ret;
366911fa71b9SJerome Forissier         }
367011fa71b9SJerome Forissier 
367132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_CLIENT_RECONNECT;
367211fa71b9SJerome Forissier     }
367311fa71b9SJerome Forissier 
367432b31808SJens Wiklander     return ret;
367511fa71b9SJerome Forissier }
367611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
367711fa71b9SJerome Forissier 
3678039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
367911fa71b9SJerome Forissier static int ssl_check_record_type(uint8_t record_type)
368011fa71b9SJerome Forissier {
368111fa71b9SJerome Forissier     if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
368211fa71b9SJerome Forissier         record_type != MBEDTLS_SSL_MSG_ALERT &&
368311fa71b9SJerome Forissier         record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
368432b31808SJens Wiklander         record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
368532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
368611fa71b9SJerome Forissier     }
368711fa71b9SJerome Forissier 
368832b31808SJens Wiklander     return 0;
368911fa71b9SJerome Forissier }
369011fa71b9SJerome Forissier 
369111fa71b9SJerome Forissier /*
369211fa71b9SJerome Forissier  * ContentType type;
369311fa71b9SJerome Forissier  * ProtocolVersion version;
369411fa71b9SJerome Forissier  * uint16 epoch;            // DTLS only
369511fa71b9SJerome Forissier  * uint48 sequence_number;  // DTLS only
369611fa71b9SJerome Forissier  * uint16 length;
369711fa71b9SJerome Forissier  *
369811fa71b9SJerome Forissier  * Return 0 if header looks sane (and, for DTLS, the record is expected)
369911fa71b9SJerome Forissier  * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
370011fa71b9SJerome Forissier  * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
370111fa71b9SJerome Forissier  *
370211fa71b9SJerome Forissier  * With DTLS, mbedtls_ssl_read_record() will:
370311fa71b9SJerome Forissier  * 1. proceed with the record if this function returns 0
370411fa71b9SJerome Forissier  * 2. drop only the current record if this function returns UNEXPECTED_RECORD
370511fa71b9SJerome Forissier  * 3. return CLIENT_RECONNECT if this function return that value
370611fa71b9SJerome Forissier  * 4. drop the whole datagram if this function returns anything else.
370711fa71b9SJerome Forissier  * Point 2 is needed when the peer is resending, and we have already received
370811fa71b9SJerome Forissier  * the first record from a datagram but are still waiting for the others.
370911fa71b9SJerome Forissier  */
3710039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
371111fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
371211fa71b9SJerome Forissier                                    unsigned char *buf,
371311fa71b9SJerome Forissier                                    size_t len,
371411fa71b9SJerome Forissier                                    mbedtls_record *rec)
371511fa71b9SJerome Forissier {
371632b31808SJens Wiklander     mbedtls_ssl_protocol_version tls_version;
371711fa71b9SJerome Forissier 
371811fa71b9SJerome Forissier     size_t const rec_hdr_type_offset    = 0;
371911fa71b9SJerome Forissier     size_t const rec_hdr_type_len       = 1;
372011fa71b9SJerome Forissier 
372111fa71b9SJerome Forissier     size_t const rec_hdr_version_offset = rec_hdr_type_offset +
372211fa71b9SJerome Forissier                                           rec_hdr_type_len;
372311fa71b9SJerome Forissier     size_t const rec_hdr_version_len    = 2;
372411fa71b9SJerome Forissier 
372511fa71b9SJerome Forissier     size_t const rec_hdr_ctr_len        = 8;
372611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
372711fa71b9SJerome Forissier     uint32_t     rec_epoch;
372811fa71b9SJerome Forissier     size_t const rec_hdr_ctr_offset     = rec_hdr_version_offset +
372911fa71b9SJerome Forissier                                           rec_hdr_version_len;
373011fa71b9SJerome Forissier 
373111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
373211fa71b9SJerome Forissier     size_t const rec_hdr_cid_offset     = rec_hdr_ctr_offset +
373311fa71b9SJerome Forissier                                           rec_hdr_ctr_len;
373411fa71b9SJerome Forissier     size_t       rec_hdr_cid_len        = 0;
373511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
373611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
373711fa71b9SJerome Forissier 
373811fa71b9SJerome Forissier     size_t       rec_hdr_len_offset; /* To be determined */
373911fa71b9SJerome Forissier     size_t const rec_hdr_len_len    = 2;
374011fa71b9SJerome Forissier 
374111fa71b9SJerome Forissier     /*
374211fa71b9SJerome Forissier      * Check minimum lengths for record header.
374311fa71b9SJerome Forissier      */
374411fa71b9SJerome Forissier 
374511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
374632b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
374711fa71b9SJerome Forissier         rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
374832b31808SJens Wiklander     } else
374911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
375011fa71b9SJerome Forissier     {
375111fa71b9SJerome Forissier         rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
375211fa71b9SJerome Forissier     }
375311fa71b9SJerome Forissier 
375432b31808SJens Wiklander     if (len < rec_hdr_len_offset + rec_hdr_len_len) {
375532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
375632b31808SJens Wiklander                               (
375732b31808SJens Wiklander                                   "datagram of length %u too small to hold DTLS record header of length %u",
375811fa71b9SJerome Forissier                                   (unsigned) len,
375911fa71b9SJerome Forissier                                   (unsigned) (rec_hdr_len_len + rec_hdr_len_len)));
376032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
376111fa71b9SJerome Forissier     }
376211fa71b9SJerome Forissier 
376311fa71b9SJerome Forissier     /*
376411fa71b9SJerome Forissier      * Parse and validate record content type
376511fa71b9SJerome Forissier      */
376611fa71b9SJerome Forissier 
376711fa71b9SJerome Forissier     rec->type = buf[rec_hdr_type_offset];
376811fa71b9SJerome Forissier 
376911fa71b9SJerome Forissier     /* Check record content type */
377011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
377111fa71b9SJerome Forissier     rec->cid_len = 0;
377211fa71b9SJerome Forissier 
377311fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
377411fa71b9SJerome Forissier         ssl->conf->cid_len != 0                                &&
377532b31808SJens Wiklander         rec->type == MBEDTLS_SSL_MSG_CID) {
377611fa71b9SJerome Forissier         /* Shift pointers to account for record header including CID
377711fa71b9SJerome Forissier          * struct {
377832b31808SJens Wiklander          *   ContentType outer_type = tls12_cid;
377911fa71b9SJerome Forissier          *   ProtocolVersion version;
378011fa71b9SJerome Forissier          *   uint16 epoch;
378111fa71b9SJerome Forissier          *   uint48 sequence_number;
378211fa71b9SJerome Forissier          *   opaque cid[cid_length]; // Additional field compared to
378311fa71b9SJerome Forissier          *                           // default DTLS record format
378411fa71b9SJerome Forissier          *   uint16 length;
378511fa71b9SJerome Forissier          *   opaque enc_content[DTLSCiphertext.length];
378611fa71b9SJerome Forissier          * } DTLSCiphertext;
378711fa71b9SJerome Forissier          */
378811fa71b9SJerome Forissier 
378911fa71b9SJerome Forissier         /* So far, we only support static CID lengths
379011fa71b9SJerome Forissier          * fixed in the configuration. */
379111fa71b9SJerome Forissier         rec_hdr_cid_len = ssl->conf->cid_len;
379211fa71b9SJerome Forissier         rec_hdr_len_offset += rec_hdr_cid_len;
379311fa71b9SJerome Forissier 
379432b31808SJens Wiklander         if (len < rec_hdr_len_offset + rec_hdr_len_len) {
379532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
379632b31808SJens Wiklander                                   (
379732b31808SJens Wiklander                                       "datagram of length %u too small to hold DTLS record header including CID, length %u",
379811fa71b9SJerome Forissier                                       (unsigned) len,
379911fa71b9SJerome Forissier                                       (unsigned) (rec_hdr_len_offset + rec_hdr_len_len)));
380032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
380111fa71b9SJerome Forissier         }
380211fa71b9SJerome Forissier 
380311fa71b9SJerome Forissier         /* configured CID len is guaranteed at most 255, see
380411fa71b9SJerome Forissier          * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
380511fa71b9SJerome Forissier         rec->cid_len = (uint8_t) rec_hdr_cid_len;
380611fa71b9SJerome Forissier         memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len);
380732b31808SJens Wiklander     } else
380811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
380911fa71b9SJerome Forissier     {
381032b31808SJens Wiklander         if (ssl_check_record_type(rec->type)) {
381111fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u",
381211fa71b9SJerome Forissier                                       (unsigned) rec->type));
381332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
381411fa71b9SJerome Forissier         }
381511fa71b9SJerome Forissier     }
381611fa71b9SJerome Forissier 
381711fa71b9SJerome Forissier     /*
381811fa71b9SJerome Forissier      * Parse and validate record version
381911fa71b9SJerome Forissier      */
382011fa71b9SJerome Forissier     rec->ver[0] = buf[rec_hdr_version_offset + 0];
382111fa71b9SJerome Forissier     rec->ver[1] = buf[rec_hdr_version_offset + 1];
3822b0563631STom Van Eyck     tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(
3823b0563631STom Van Eyck         buf + rec_hdr_version_offset,
382432b31808SJens Wiklander         ssl->conf->transport);
382511fa71b9SJerome Forissier 
382632b31808SJens Wiklander     if (tls_version > ssl->conf->max_tls_version) {
382732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u",
382832b31808SJens Wiklander                                   (unsigned) tls_version,
382932b31808SJens Wiklander                                   (unsigned) ssl->conf->max_tls_version));
383011fa71b9SJerome Forissier 
383132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
383211fa71b9SJerome Forissier     }
383311fa71b9SJerome Forissier     /*
383411fa71b9SJerome Forissier      * Parse/Copy record sequence number.
383511fa71b9SJerome Forissier      */
383611fa71b9SJerome Forissier 
383711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
383832b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
383911fa71b9SJerome Forissier         /* Copy explicit record sequence number from input buffer. */
384011fa71b9SJerome Forissier         memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset,
384111fa71b9SJerome Forissier                rec_hdr_ctr_len);
384232b31808SJens Wiklander     } else
384311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
384411fa71b9SJerome Forissier     {
384511fa71b9SJerome Forissier         /* Copy implicit record sequence number from SSL context structure. */
384611fa71b9SJerome Forissier         memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len);
384711fa71b9SJerome Forissier     }
384811fa71b9SJerome Forissier 
384911fa71b9SJerome Forissier     /*
385011fa71b9SJerome Forissier      * Parse record length.
385111fa71b9SJerome Forissier      */
385211fa71b9SJerome Forissier 
385311fa71b9SJerome Forissier     rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
3854b0563631STom Van Eyck     rec->data_len    = MBEDTLS_GET_UINT16_BE(buf, rec_hdr_len_offset);
385511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset);
385611fa71b9SJerome Forissier 
38577901324dSJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, "
385832b31808SJens Wiklander                               "version = [0x%x], msglen = %" MBEDTLS_PRINTF_SIZET,
385932b31808SJens Wiklander                               rec->type, (unsigned) tls_version, rec->data_len));
386011fa71b9SJerome Forissier 
386111fa71b9SJerome Forissier     rec->buf     = buf;
386211fa71b9SJerome Forissier     rec->buf_len = rec->data_offset + rec->data_len;
386311fa71b9SJerome Forissier 
386432b31808SJens Wiklander     if (rec->data_len == 0) {
386532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
386632b31808SJens Wiklander     }
386711fa71b9SJerome Forissier 
386811fa71b9SJerome Forissier     /*
386911fa71b9SJerome Forissier      * DTLS-related tests.
387011fa71b9SJerome Forissier      * Check epoch before checking length constraint because
387111fa71b9SJerome Forissier      * the latter varies with the epoch. E.g., if a ChangeCipherSpec
387211fa71b9SJerome Forissier      * message gets duplicated before the corresponding Finished message,
387311fa71b9SJerome Forissier      * the second ChangeCipherSpec should be discarded because it belongs
387411fa71b9SJerome Forissier      * to an old epoch, but not because its length is shorter than
387511fa71b9SJerome Forissier      * the minimum record length for packets using the new record transform.
387611fa71b9SJerome Forissier      * Note that these two kinds of failures are handled differently,
387711fa71b9SJerome Forissier      * as an unexpected record is silently skipped but an invalid
387811fa71b9SJerome Forissier      * record leads to the entire datagram being dropped.
387911fa71b9SJerome Forissier      */
388011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
388132b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3882b0563631STom Van Eyck         rec_epoch = MBEDTLS_GET_UINT16_BE(rec->ctr, 0);
388311fa71b9SJerome Forissier 
388411fa71b9SJerome Forissier         /* Check that the datagram is large enough to contain a record
388511fa71b9SJerome Forissier          * of the advertised length. */
388632b31808SJens Wiklander         if (len < rec->data_offset + rec->data_len) {
388732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
388832b31808SJens Wiklander                                   (
388932b31808SJens Wiklander                                       "Datagram of length %u too small to contain record of advertised length %u.",
389011fa71b9SJerome Forissier                                       (unsigned) len,
389111fa71b9SJerome Forissier                                       (unsigned) (rec->data_offset + rec->data_len)));
389232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
389311fa71b9SJerome Forissier         }
389411fa71b9SJerome Forissier 
389511fa71b9SJerome Forissier         /* Records from other, non-matching epochs are silently discarded.
389611fa71b9SJerome Forissier          * (The case of same-port Client reconnects must be considered in
389711fa71b9SJerome Forissier          *  the caller). */
389832b31808SJens Wiklander         if (rec_epoch != ssl->in_epoch) {
389911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: "
39007901324dSJerome Forissier                                       "expected %u, received %lu",
39017901324dSJerome Forissier                                       ssl->in_epoch, (unsigned long) rec_epoch));
390211fa71b9SJerome Forissier 
390311fa71b9SJerome Forissier             /* Records from the next epoch are considered for buffering
390411fa71b9SJerome Forissier              * (concretely: early Finished messages). */
390532b31808SJens Wiklander             if (rec_epoch == (unsigned) ssl->in_epoch + 1) {
390611fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering"));
390732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
390811fa71b9SJerome Forissier             }
390911fa71b9SJerome Forissier 
391032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
391111fa71b9SJerome Forissier         }
391211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
391311fa71b9SJerome Forissier         /* For records from the correct epoch, check whether their
391411fa71b9SJerome Forissier          * sequence number has been seen before. */
391511fa71b9SJerome Forissier         else if (mbedtls_ssl_dtls_record_replay_check((mbedtls_ssl_context *) ssl,
391632b31808SJens Wiklander                                                       &rec->ctr[0]) != 0) {
391711fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record"));
391832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
391911fa71b9SJerome Forissier         }
392011fa71b9SJerome Forissier #endif
392111fa71b9SJerome Forissier     }
392211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
392311fa71b9SJerome Forissier 
392432b31808SJens Wiklander     return 0;
392511fa71b9SJerome Forissier }
392611fa71b9SJerome Forissier 
392711fa71b9SJerome Forissier 
392811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
3929039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
393011fa71b9SJerome Forissier static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
393111fa71b9SJerome Forissier {
3932b0563631STom Van Eyck     unsigned int rec_epoch = MBEDTLS_GET_UINT16_BE(ssl->in_ctr, 0);
393311fa71b9SJerome Forissier 
393411fa71b9SJerome Forissier     /*
393511fa71b9SJerome Forissier      * Check for an epoch 0 ClientHello. We can't use in_msg here to
393611fa71b9SJerome Forissier      * access the first byte of record content (handshake type), as we
393711fa71b9SJerome Forissier      * have an active transform (possibly iv_len != 0), so use the
393811fa71b9SJerome Forissier      * fact that the record header len is 13 instead.
393911fa71b9SJerome Forissier      */
394011fa71b9SJerome Forissier     if (rec_epoch == 0 &&
394111fa71b9SJerome Forissier         ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
394232b31808SJens Wiklander         mbedtls_ssl_is_handshake_over(ssl) == 1 &&
394311fa71b9SJerome Forissier         ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
394411fa71b9SJerome Forissier         ssl->in_left > 13 &&
394532b31808SJens Wiklander         ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) {
394611fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect "
394711fa71b9SJerome Forissier                                   "from the same port"));
394832b31808SJens Wiklander         return ssl_handle_possible_reconnect(ssl);
394911fa71b9SJerome Forissier     }
395011fa71b9SJerome Forissier 
395132b31808SJens Wiklander     return 0;
395211fa71b9SJerome Forissier }
395311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
395411fa71b9SJerome Forissier 
395511fa71b9SJerome Forissier /*
395611fa71b9SJerome Forissier  * If applicable, decrypt record content
395711fa71b9SJerome Forissier  */
3958039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
395911fa71b9SJerome Forissier static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
396011fa71b9SJerome Forissier                                       mbedtls_record *rec)
396111fa71b9SJerome Forissier {
396211fa71b9SJerome Forissier     int ret, done = 0;
396311fa71b9SJerome Forissier 
396411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(4, "input record from network",
396511fa71b9SJerome Forissier                           rec->buf, rec->buf_len);
396611fa71b9SJerome Forissier 
396732b31808SJens Wiklander     /*
396832b31808SJens Wiklander      * In TLS 1.3, always treat ChangeCipherSpec records
396932b31808SJens Wiklander      * as unencrypted. The only thing we do with them is
397032b31808SJens Wiklander      * check the length and content and ignore them.
397132b31808SJens Wiklander      */
397232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
397332b31808SJens Wiklander     if (ssl->transform_in != NULL &&
397432b31808SJens Wiklander         ssl->transform_in->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
397532b31808SJens Wiklander         if (rec->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
397611fa71b9SJerome Forissier             done = 1;
397711fa71b9SJerome Forissier         }
397832b31808SJens Wiklander     }
397932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
398032b31808SJens Wiklander 
398132b31808SJens Wiklander     if (!done && ssl->transform_in != NULL) {
398211fa71b9SJerome Forissier         unsigned char const old_msg_type = rec->type;
398311fa71b9SJerome Forissier 
398411fa71b9SJerome Forissier         if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in,
398532b31808SJens Wiklander                                            rec)) != 0) {
398611fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret);
398711fa71b9SJerome Forissier 
3988b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
3989b0563631STom Van Eyck             /*
3990b0563631STom Van Eyck              * Although the server rejected early data, it might receive early
3991b0563631STom Van Eyck              * data as long as it has not received the client Finished message.
3992b0563631STom Van Eyck              * It is encrypted with early keys and should be ignored as stated
3993b0563631STom Van Eyck              * in section 4.2.10 of RFC 8446:
3994b0563631STom Van Eyck              *
3995b0563631STom Van Eyck              * "Ignore the extension and return a regular 1-RTT response. The
3996b0563631STom Van Eyck              * server then skips past early data by attempting to deprotect
3997b0563631STom Van Eyck              * received records using the handshake traffic key, discarding
3998b0563631STom Van Eyck              * records which fail deprotection (up to the configured
3999b0563631STom Van Eyck              * max_early_data_size). Once a record is deprotected successfully,
4000b0563631STom Van Eyck              * it is treated as the start of the client's second flight and the
4001b0563631STom Van Eyck              * server proceeds as with an ordinary 1-RTT handshake."
4002b0563631STom Van Eyck              */
4003b0563631STom Van Eyck             if ((old_msg_type == MBEDTLS_SSL_MSG_APPLICATION_DATA) &&
4004b0563631STom Van Eyck                 (ssl->discard_early_data_record ==
4005b0563631STom Van Eyck                  MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
4006b0563631STom Van Eyck                 MBEDTLS_SSL_DEBUG_MSG(
4007b0563631STom Van Eyck                     3, ("EarlyData: deprotect and discard app data records."));
4008b0563631STom Van Eyck 
4009b0563631STom Van Eyck                 ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4010b0563631STom Van Eyck                 if (ret != 0) {
4011b0563631STom Van Eyck                     return ret;
4012b0563631STom Van Eyck                 }
4013b0563631STom Van Eyck                 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4014b0563631STom Van Eyck             }
4015b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4016b0563631STom Van Eyck 
401711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
401811fa71b9SJerome Forissier             if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
401911fa71b9SJerome Forissier                 ssl->conf->ignore_unexpected_cid
402032b31808SJens Wiklander                 == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
402111fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID"));
402211fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
402311fa71b9SJerome Forissier             }
402411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
402511fa71b9SJerome Forissier 
4026b0563631STom Van Eyck             /*
4027b0563631STom Van Eyck              * The decryption of the record failed, no reason to ignore it,
4028b0563631STom Van Eyck              * return in error with the decryption error code.
4029b0563631STom Van Eyck              */
403032b31808SJens Wiklander             return ret;
403111fa71b9SJerome Forissier         }
403211fa71b9SJerome Forissier 
4033b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4034b0563631STom Van Eyck         /*
4035b0563631STom Van Eyck          * If the server were discarding protected records that it fails to
4036b0563631STom Van Eyck          * deprotect because it has rejected early data, as we have just
4037b0563631STom Van Eyck          * deprotected successfully a record, the server has to resume normal
4038b0563631STom Van Eyck          * operation and fail the connection if the deprotection of a record
4039b0563631STom Van Eyck          * fails.
4040b0563631STom Van Eyck          */
4041b0563631STom Van Eyck         if (ssl->discard_early_data_record ==
4042b0563631STom Van Eyck             MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD) {
4043b0563631STom Van Eyck             ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4044b0563631STom Van Eyck         }
4045b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4046b0563631STom Van Eyck 
404732b31808SJens Wiklander         if (old_msg_type != rec->type) {
404811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d",
404911fa71b9SJerome Forissier                                       old_msg_type, rec->type));
405011fa71b9SJerome Forissier         }
405111fa71b9SJerome Forissier 
405211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt",
405311fa71b9SJerome Forissier                               rec->buf + rec->data_offset, rec->data_len);
405411fa71b9SJerome Forissier 
405511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
405611fa71b9SJerome Forissier         /* We have already checked the record content type
405711fa71b9SJerome Forissier          * in ssl_parse_record_header(), failing or silently
405811fa71b9SJerome Forissier          * dropping the record in the case of an unknown type.
405911fa71b9SJerome Forissier          *
406011fa71b9SJerome Forissier          * Since with the use of CIDs, the record content type
406111fa71b9SJerome Forissier          * might change during decryption, re-check the record
406211fa71b9SJerome Forissier          * content type, but treat a failure as fatal this time. */
406332b31808SJens Wiklander         if (ssl_check_record_type(rec->type)) {
406411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type"));
406532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
406611fa71b9SJerome Forissier         }
406711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
406811fa71b9SJerome Forissier 
406932b31808SJens Wiklander         if (rec->data_len == 0) {
407011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
407132b31808SJens Wiklander             if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2
407232b31808SJens Wiklander                 && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
407311fa71b9SJerome Forissier                 /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
407411fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("invalid zero-length message type: %d", ssl->in_msgtype));
407532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INVALID_RECORD;
407611fa71b9SJerome Forissier             }
407711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
407811fa71b9SJerome Forissier 
407911fa71b9SJerome Forissier             ssl->nb_zero++;
408011fa71b9SJerome Forissier 
408111fa71b9SJerome Forissier             /*
408211fa71b9SJerome Forissier              * Three or more empty messages may be a DoS attack
408311fa71b9SJerome Forissier              * (excessive CPU consumption).
408411fa71b9SJerome Forissier              */
408532b31808SJens Wiklander             if (ssl->nb_zero > 3) {
408611fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty "
408711fa71b9SJerome Forissier                                           "messages, possible DoS attack"));
408811fa71b9SJerome Forissier                 /* Treat the records as if they were not properly authenticated,
408911fa71b9SJerome Forissier                  * thereby failing the connection if we see more than allowed
409011fa71b9SJerome Forissier                  * by the configured bad MAC threshold. */
409132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INVALID_MAC;
409211fa71b9SJerome Forissier             }
409332b31808SJens Wiklander         } else {
409411fa71b9SJerome Forissier             ssl->nb_zero = 0;
409532b31808SJens Wiklander         }
409611fa71b9SJerome Forissier 
409711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
409832b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
409911fa71b9SJerome Forissier             ; /* in_ctr read from peer, not maintained internally */
410032b31808SJens Wiklander         } else
410111fa71b9SJerome Forissier #endif
410211fa71b9SJerome Forissier         {
410311fa71b9SJerome Forissier             unsigned i;
410432b31808SJens Wiklander             for (i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
410532b31808SJens Wiklander                  i > mbedtls_ssl_ep_len(ssl); i--) {
410632b31808SJens Wiklander                 if (++ssl->in_ctr[i - 1] != 0) {
410711fa71b9SJerome Forissier                     break;
410832b31808SJens Wiklander                 }
410932b31808SJens Wiklander             }
411011fa71b9SJerome Forissier 
411111fa71b9SJerome Forissier             /* The loop goes to its end iff the counter is wrapping */
411232b31808SJens Wiklander             if (i == mbedtls_ssl_ep_len(ssl)) {
411311fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("incoming message counter would wrap"));
411432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
411511fa71b9SJerome Forissier             }
411611fa71b9SJerome Forissier         }
411711fa71b9SJerome Forissier 
411811fa71b9SJerome Forissier     }
411911fa71b9SJerome Forissier 
4120b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4121b0563631STom Van Eyck     /*
4122b0563631STom Van Eyck      * Although the server rejected early data because it needed to send an
4123b0563631STom Van Eyck      * HelloRetryRequest message, it might receive early data as long as it has
4124b0563631STom Van Eyck      * not received the client Finished message.
4125b0563631STom Van Eyck      * The early data is encrypted with early keys and should be ignored as
4126b0563631STom Van Eyck      * stated in section 4.2.10 of RFC 8446 (second case):
4127b0563631STom Van Eyck      *
4128b0563631STom Van Eyck      * "The server then ignores early data by skipping all records with an
4129b0563631STom Van Eyck      * external content type of "application_data" (indicating that they are
4130b0563631STom Van Eyck      * encrypted), up to the configured max_early_data_size. Ignore application
4131b0563631STom Van Eyck      * data message before 2nd ClientHello when early_data was received in 1st
4132b0563631STom Van Eyck      * ClientHello."
4133b0563631STom Van Eyck      */
4134b0563631STom Van Eyck     if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
4135b0563631STom Van Eyck         if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
4136b0563631STom Van Eyck 
4137b0563631STom Van Eyck             ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4138b0563631STom Van Eyck             if (ret != 0) {
4139b0563631STom Van Eyck                 return ret;
4140b0563631STom Van Eyck             }
4141b0563631STom Van Eyck 
4142b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(
4143b0563631STom Van Eyck                 3, ("EarlyData: Ignore application message before 2nd ClientHello"));
4144b0563631STom Van Eyck 
4145b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4146b0563631STom Van Eyck         } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
4147b0563631STom Van Eyck             ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4148b0563631STom Van Eyck         }
4149b0563631STom Van Eyck     }
4150b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4151b0563631STom Van Eyck 
415211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
415332b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
415411fa71b9SJerome Forissier         mbedtls_ssl_dtls_replay_update(ssl);
415511fa71b9SJerome Forissier     }
415611fa71b9SJerome Forissier #endif
415711fa71b9SJerome Forissier 
415811fa71b9SJerome Forissier     /* Check actual (decrypted) record content length against
415911fa71b9SJerome Forissier      * configured maximum. */
416032b31808SJens Wiklander     if (rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
416111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length"));
416232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INVALID_RECORD;
416311fa71b9SJerome Forissier     }
416411fa71b9SJerome Forissier 
416532b31808SJens Wiklander     return 0;
416611fa71b9SJerome Forissier }
416711fa71b9SJerome Forissier 
416811fa71b9SJerome Forissier /*
416911fa71b9SJerome Forissier  * Read a record.
417011fa71b9SJerome Forissier  *
417111fa71b9SJerome Forissier  * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
417211fa71b9SJerome Forissier  * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
417311fa71b9SJerome Forissier  *
417411fa71b9SJerome Forissier  */
417511fa71b9SJerome Forissier 
417611fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */
4177039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
417811fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl);
4179039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
418011fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl);
4181039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
418211fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl);
418311fa71b9SJerome Forissier 
418411fa71b9SJerome Forissier int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl,
418511fa71b9SJerome Forissier                             unsigned update_hs_digest)
418611fa71b9SJerome Forissier {
418711fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
418811fa71b9SJerome Forissier 
418911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record"));
419011fa71b9SJerome Forissier 
419132b31808SJens Wiklander     if (ssl->keep_current_message == 0) {
419211fa71b9SJerome Forissier         do {
419311fa71b9SJerome Forissier 
419411fa71b9SJerome Forissier             ret = ssl_consume_current_message(ssl);
419532b31808SJens Wiklander             if (ret != 0) {
419632b31808SJens Wiklander                 return ret;
419732b31808SJens Wiklander             }
419811fa71b9SJerome Forissier 
419932b31808SJens Wiklander             if (ssl_record_is_in_progress(ssl) == 0) {
420032b31808SJens Wiklander                 int dtls_have_buffered = 0;
420111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
420211fa71b9SJerome Forissier 
420311fa71b9SJerome Forissier                 /* We only check for buffered messages if the
420411fa71b9SJerome Forissier                  * current datagram is fully consumed. */
420511fa71b9SJerome Forissier                 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
420632b31808SJens Wiklander                     ssl_next_record_is_in_datagram(ssl) == 0) {
420732b31808SJens Wiklander                     if (ssl_load_buffered_message(ssl) == 0) {
420832b31808SJens Wiklander                         dtls_have_buffered = 1;
420932b31808SJens Wiklander                     }
421011fa71b9SJerome Forissier                 }
421111fa71b9SJerome Forissier 
421211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
421332b31808SJens Wiklander                 if (dtls_have_buffered == 0) {
421411fa71b9SJerome Forissier                     ret = ssl_get_next_record(ssl);
421532b31808SJens Wiklander                     if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) {
421611fa71b9SJerome Forissier                         continue;
421732b31808SJens Wiklander                     }
421811fa71b9SJerome Forissier 
421932b31808SJens Wiklander                     if (ret != 0) {
422011fa71b9SJerome Forissier                         MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret);
422132b31808SJens Wiklander                         return ret;
422211fa71b9SJerome Forissier                     }
422311fa71b9SJerome Forissier                 }
422411fa71b9SJerome Forissier             }
422511fa71b9SJerome Forissier 
422611fa71b9SJerome Forissier             ret = mbedtls_ssl_handle_message_type(ssl);
422711fa71b9SJerome Forissier 
422811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
422932b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
423011fa71b9SJerome Forissier                 /* Buffer future message */
423111fa71b9SJerome Forissier                 ret = ssl_buffer_message(ssl);
423232b31808SJens Wiklander                 if (ret != 0) {
423332b31808SJens Wiklander                     return ret;
423432b31808SJens Wiklander                 }
423511fa71b9SJerome Forissier 
423611fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
423711fa71b9SJerome Forissier             }
423811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
423911fa71b9SJerome Forissier 
424011fa71b9SJerome Forissier         } while (MBEDTLS_ERR_SSL_NON_FATAL           == ret  ||
424111fa71b9SJerome Forissier                  MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret);
424211fa71b9SJerome Forissier 
424332b31808SJens Wiklander         if (0 != ret) {
424411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret);
424532b31808SJens Wiklander             return ret;
424611fa71b9SJerome Forissier         }
424711fa71b9SJerome Forissier 
424811fa71b9SJerome Forissier         if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
424932b31808SJens Wiklander             update_hs_digest == 1) {
425032b31808SJens Wiklander             ret = mbedtls_ssl_update_handshake_status(ssl);
425132b31808SJens Wiklander             if (0 != ret) {
425232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
425332b31808SJens Wiklander                 return ret;
425411fa71b9SJerome Forissier             }
425511fa71b9SJerome Forissier         }
425632b31808SJens Wiklander     } else {
425711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message"));
425811fa71b9SJerome Forissier         ssl->keep_current_message = 0;
425911fa71b9SJerome Forissier     }
426011fa71b9SJerome Forissier 
426111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record"));
426211fa71b9SJerome Forissier 
426332b31808SJens Wiklander     return 0;
426411fa71b9SJerome Forissier }
426511fa71b9SJerome Forissier 
426611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4267039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
426811fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl)
426911fa71b9SJerome Forissier {
427032b31808SJens Wiklander     if (ssl->in_left > ssl->next_record_offset) {
427132b31808SJens Wiklander         return 1;
427232b31808SJens Wiklander     }
427311fa71b9SJerome Forissier 
427432b31808SJens Wiklander     return 0;
427511fa71b9SJerome Forissier }
427611fa71b9SJerome Forissier 
4277039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
427811fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl)
427911fa71b9SJerome Forissier {
428011fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
428111fa71b9SJerome Forissier     mbedtls_ssl_hs_buffer *hs_buf;
428211fa71b9SJerome Forissier     int ret = 0;
428311fa71b9SJerome Forissier 
428432b31808SJens Wiklander     if (hs == NULL) {
428532b31808SJens Wiklander         return -1;
428632b31808SJens Wiklander     }
428711fa71b9SJerome Forissier 
428832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_message"));
428911fa71b9SJerome Forissier 
429011fa71b9SJerome Forissier     if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
429132b31808SJens Wiklander         ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
429211fa71b9SJerome Forissier         /* Check if we have seen a ChangeCipherSpec before.
429311fa71b9SJerome Forissier          * If yes, synthesize a CCS record. */
429432b31808SJens Wiklander         if (!hs->buffering.seen_ccs) {
429511fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight"));
429611fa71b9SJerome Forissier             ret = -1;
429711fa71b9SJerome Forissier             goto exit;
429811fa71b9SJerome Forissier         }
429911fa71b9SJerome Forissier 
430011fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message"));
430111fa71b9SJerome Forissier         ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
430211fa71b9SJerome Forissier         ssl->in_msglen = 1;
430311fa71b9SJerome Forissier         ssl->in_msg[0] = 1;
430411fa71b9SJerome Forissier 
430511fa71b9SJerome Forissier         /* As long as they are equal, the exact value doesn't matter. */
430611fa71b9SJerome Forissier         ssl->in_left            = 0;
430711fa71b9SJerome Forissier         ssl->next_record_offset = 0;
430811fa71b9SJerome Forissier 
430911fa71b9SJerome Forissier         hs->buffering.seen_ccs = 0;
431011fa71b9SJerome Forissier         goto exit;
431111fa71b9SJerome Forissier     }
431211fa71b9SJerome Forissier 
431311fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C)
431411fa71b9SJerome Forissier     /* Debug only */
431511fa71b9SJerome Forissier     {
431611fa71b9SJerome Forissier         unsigned offset;
431732b31808SJens Wiklander         for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
431811fa71b9SJerome Forissier             hs_buf = &hs->buffering.hs[offset];
431932b31808SJens Wiklander             if (hs_buf->is_valid == 1) {
432011fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("Future message with sequence number %u %s buffered.",
432111fa71b9SJerome Forissier                                           hs->in_msg_seq + offset,
432211fa71b9SJerome Forissier                                           hs_buf->is_complete ? "fully" : "partially"));
432311fa71b9SJerome Forissier             }
432411fa71b9SJerome Forissier         }
432511fa71b9SJerome Forissier     }
432611fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */
432711fa71b9SJerome Forissier 
432811fa71b9SJerome Forissier     /* Check if we have buffered and/or fully reassembled the
432911fa71b9SJerome Forissier      * next handshake message. */
433011fa71b9SJerome Forissier     hs_buf = &hs->buffering.hs[0];
433132b31808SJens Wiklander     if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) {
433211fa71b9SJerome Forissier         /* Synthesize a record containing the buffered HS message. */
4333b0563631STom Van Eyck         size_t msg_len = MBEDTLS_GET_UINT24_BE(hs_buf->data, 1);
433411fa71b9SJerome Forissier 
433511fa71b9SJerome Forissier         /* Double-check that we haven't accidentally buffered
433611fa71b9SJerome Forissier          * a message that doesn't fit into the input buffer. */
433732b31808SJens Wiklander         if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
433811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
433932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
434011fa71b9SJerome Forissier         }
434111fa71b9SJerome Forissier 
434211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message has been buffered - load"));
434311fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)",
434411fa71b9SJerome Forissier                               hs_buf->data, msg_len + 12);
434511fa71b9SJerome Forissier 
434611fa71b9SJerome Forissier         ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
434711fa71b9SJerome Forissier         ssl->in_hslen   = msg_len + 12;
434811fa71b9SJerome Forissier         ssl->in_msglen  = msg_len + 12;
434911fa71b9SJerome Forissier         memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen);
435011fa71b9SJerome Forissier 
435111fa71b9SJerome Forissier         ret = 0;
435211fa71b9SJerome Forissier         goto exit;
435332b31808SJens Wiklander     } else {
435411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially bufffered",
435511fa71b9SJerome Forissier                                   hs->in_msg_seq));
435611fa71b9SJerome Forissier     }
435711fa71b9SJerome Forissier 
435811fa71b9SJerome Forissier     ret = -1;
435911fa71b9SJerome Forissier 
436011fa71b9SJerome Forissier exit:
436111fa71b9SJerome Forissier 
436211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message"));
436332b31808SJens Wiklander     return ret;
436411fa71b9SJerome Forissier }
436511fa71b9SJerome Forissier 
4366039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
436711fa71b9SJerome Forissier static int ssl_buffer_make_space(mbedtls_ssl_context *ssl,
436811fa71b9SJerome Forissier                                  size_t desired)
436911fa71b9SJerome Forissier {
437011fa71b9SJerome Forissier     int offset;
437111fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
437211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("Attempt to free buffered messages to have %u bytes available",
437311fa71b9SJerome Forissier                               (unsigned) desired));
437411fa71b9SJerome Forissier 
437511fa71b9SJerome Forissier     /* Get rid of future records epoch first, if such exist. */
437611fa71b9SJerome Forissier     ssl_free_buffered_record(ssl);
437711fa71b9SJerome Forissier 
437811fa71b9SJerome Forissier     /* Check if we have enough space available now. */
437911fa71b9SJerome Forissier     if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
438032b31808SJens Wiklander                     hs->buffering.total_bytes_buffered)) {
438111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing future epoch record"));
438232b31808SJens Wiklander         return 0;
438311fa71b9SJerome Forissier     }
438411fa71b9SJerome Forissier 
438511fa71b9SJerome Forissier     /* We don't have enough space to buffer the next expected handshake
438611fa71b9SJerome Forissier      * message. Remove buffers used for future messages to gain space,
438711fa71b9SJerome Forissier      * starting with the most distant one. */
438811fa71b9SJerome Forissier     for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
438932b31808SJens Wiklander          offset >= 0; offset--) {
439032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2,
439132b31808SJens Wiklander                               (
439232b31808SJens Wiklander                                   "Free buffering slot %d to make space for reassembly of next handshake message",
439311fa71b9SJerome Forissier                                   offset));
439411fa71b9SJerome Forissier 
439511fa71b9SJerome Forissier         ssl_buffering_free_slot(ssl, (uint8_t) offset);
439611fa71b9SJerome Forissier 
439711fa71b9SJerome Forissier         /* Check if we have enough space available now. */
439811fa71b9SJerome Forissier         if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
439932b31808SJens Wiklander                         hs->buffering.total_bytes_buffered)) {
440011fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing buffered HS messages"));
440132b31808SJens Wiklander             return 0;
440211fa71b9SJerome Forissier         }
440311fa71b9SJerome Forissier     }
440411fa71b9SJerome Forissier 
440532b31808SJens Wiklander     return -1;
440611fa71b9SJerome Forissier }
440711fa71b9SJerome Forissier 
4408039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
440911fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl)
441011fa71b9SJerome Forissier {
441111fa71b9SJerome Forissier     int ret = 0;
441211fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
441311fa71b9SJerome Forissier 
441432b31808SJens Wiklander     if (hs == NULL) {
441532b31808SJens Wiklander         return 0;
441632b31808SJens Wiklander     }
441711fa71b9SJerome Forissier 
441811fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message"));
441911fa71b9SJerome Forissier 
442032b31808SJens Wiklander     switch (ssl->in_msgtype) {
442111fa71b9SJerome Forissier         case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
442211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message"));
442311fa71b9SJerome Forissier 
442411fa71b9SJerome Forissier             hs->buffering.seen_ccs = 1;
442511fa71b9SJerome Forissier             break;
442611fa71b9SJerome Forissier 
442711fa71b9SJerome Forissier         case MBEDTLS_SSL_MSG_HANDSHAKE:
442811fa71b9SJerome Forissier         {
442911fa71b9SJerome Forissier             unsigned recv_msg_seq_offset;
4430b0563631STom Van Eyck             unsigned recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
443111fa71b9SJerome Forissier             mbedtls_ssl_hs_buffer *hs_buf;
443211fa71b9SJerome Forissier             size_t msg_len = ssl->in_hslen - 12;
443311fa71b9SJerome Forissier 
443411fa71b9SJerome Forissier             /* We should never receive an old handshake
443511fa71b9SJerome Forissier              * message - double-check nonetheless. */
443632b31808SJens Wiklander             if (recv_msg_seq < ssl->handshake->in_msg_seq) {
443711fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
443832b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
443911fa71b9SJerome Forissier             }
444011fa71b9SJerome Forissier 
444111fa71b9SJerome Forissier             recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
444232b31808SJens Wiklander             if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
444311fa71b9SJerome Forissier                 /* Silently ignore -- message too far in the future */
444411fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2,
444511fa71b9SJerome Forissier                                       ("Ignore future HS message with sequence number %u, "
444611fa71b9SJerome Forissier                                        "buffering window %u - %u",
444711fa71b9SJerome Forissier                                        recv_msg_seq, ssl->handshake->in_msg_seq,
444832b31808SJens Wiklander                                        ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS -
444932b31808SJens Wiklander                                        1));
445011fa71b9SJerome Forissier 
445111fa71b9SJerome Forissier                 goto exit;
445211fa71b9SJerome Forissier             }
445311fa71b9SJerome Forissier 
445411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering HS message with sequence number %u, offset %u ",
445511fa71b9SJerome Forissier                                       recv_msg_seq, recv_msg_seq_offset));
445611fa71b9SJerome Forissier 
445711fa71b9SJerome Forissier             hs_buf = &hs->buffering.hs[recv_msg_seq_offset];
445811fa71b9SJerome Forissier 
445911fa71b9SJerome Forissier             /* Check if the buffering for this seq nr has already commenced. */
446032b31808SJens Wiklander             if (!hs_buf->is_valid) {
446111fa71b9SJerome Forissier                 size_t reassembly_buf_sz;
446211fa71b9SJerome Forissier 
446311fa71b9SJerome Forissier                 hs_buf->is_fragmented =
446411fa71b9SJerome Forissier                     (ssl_hs_is_proper_fragment(ssl) == 1);
446511fa71b9SJerome Forissier 
446611fa71b9SJerome Forissier                 /* We copy the message back into the input buffer
446711fa71b9SJerome Forissier                  * after reassembly, so check that it's not too large.
446811fa71b9SJerome Forissier                  * This is an implementation-specific limitation
446911fa71b9SJerome Forissier                  * and not one from the standard, hence it is not
447011fa71b9SJerome Forissier                  * checked in ssl_check_hs_header(). */
447132b31808SJens Wiklander                 if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
447211fa71b9SJerome Forissier                     /* Ignore message */
447311fa71b9SJerome Forissier                     goto exit;
447411fa71b9SJerome Forissier                 }
447511fa71b9SJerome Forissier 
447611fa71b9SJerome Forissier                 /* Check if we have enough space to buffer the message. */
447711fa71b9SJerome Forissier                 if (hs->buffering.total_bytes_buffered >
447832b31808SJens Wiklander                     MBEDTLS_SSL_DTLS_MAX_BUFFERING) {
447911fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
448032b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
448111fa71b9SJerome Forissier                 }
448211fa71b9SJerome Forissier 
448311fa71b9SJerome Forissier                 reassembly_buf_sz = ssl_get_reassembly_buffer_size(msg_len,
448411fa71b9SJerome Forissier                                                                    hs_buf->is_fragmented);
448511fa71b9SJerome Forissier 
448611fa71b9SJerome Forissier                 if (reassembly_buf_sz > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
448732b31808SJens Wiklander                                          hs->buffering.total_bytes_buffered)) {
448832b31808SJens Wiklander                     if (recv_msg_seq_offset > 0) {
448911fa71b9SJerome Forissier                         /* If we can't buffer a future message because
449011fa71b9SJerome Forissier                          * of space limitations -- ignore. */
449132b31808SJens Wiklander                         MBEDTLS_SSL_DEBUG_MSG(2,
449232b31808SJens Wiklander                                               ("Buffering of future message of size %"
449332b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
449432b31808SJens Wiklander                                                " would exceed the compile-time limit %"
449532b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
44967901324dSJerome Forissier                                                " (already %" MBEDTLS_PRINTF_SIZET
44977901324dSJerome Forissier                                                " bytes buffered) -- ignore\n",
44987901324dSJerome Forissier                                                msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
44997901324dSJerome Forissier                                                hs->buffering.total_bytes_buffered));
450011fa71b9SJerome Forissier                         goto exit;
450132b31808SJens Wiklander                     } else {
450232b31808SJens Wiklander                         MBEDTLS_SSL_DEBUG_MSG(2,
450332b31808SJens Wiklander                                               ("Buffering of future message of size %"
450432b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
450532b31808SJens Wiklander                                                " would exceed the compile-time limit %"
450632b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
45077901324dSJerome Forissier                                                " (already %" MBEDTLS_PRINTF_SIZET
45087901324dSJerome Forissier                                                " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
45097901324dSJerome Forissier                                                msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
45107901324dSJerome Forissier                                                hs->buffering.total_bytes_buffered));
451111fa71b9SJerome Forissier                     }
451211fa71b9SJerome Forissier 
451332b31808SJens Wiklander                     if (ssl_buffer_make_space(ssl, reassembly_buf_sz) != 0) {
451432b31808SJens Wiklander                         MBEDTLS_SSL_DEBUG_MSG(2,
451532b31808SJens Wiklander                                               ("Reassembly of next message of size %"
451632b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
451732b31808SJens Wiklander                                                " (%" MBEDTLS_PRINTF_SIZET
451832b31808SJens Wiklander                                                " with bitmap) would exceed"
451932b31808SJens Wiklander                                                " the compile-time limit %"
452032b31808SJens Wiklander                                                MBEDTLS_PRINTF_SIZET
45217901324dSJerome Forissier                                                " (already %" MBEDTLS_PRINTF_SIZET
45227901324dSJerome Forissier                                                " bytes buffered) -- fail\n",
45237901324dSJerome Forissier                                                msg_len,
45247901324dSJerome Forissier                                                reassembly_buf_sz,
45257901324dSJerome Forissier                                                (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
45267901324dSJerome Forissier                                                hs->buffering.total_bytes_buffered));
452711fa71b9SJerome Forissier                         ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
452811fa71b9SJerome Forissier                         goto exit;
452911fa71b9SJerome Forissier                     }
453011fa71b9SJerome Forissier                 }
453111fa71b9SJerome Forissier 
453232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2,
453332b31808SJens Wiklander                                       ("initialize reassembly, total length = %"
453432b31808SJens Wiklander                                        MBEDTLS_PRINTF_SIZET,
453511fa71b9SJerome Forissier                                        msg_len));
453611fa71b9SJerome Forissier 
453711fa71b9SJerome Forissier                 hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz);
453832b31808SJens Wiklander                 if (hs_buf->data == NULL) {
453911fa71b9SJerome Forissier                     ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
454011fa71b9SJerome Forissier                     goto exit;
454111fa71b9SJerome Forissier                 }
454211fa71b9SJerome Forissier                 hs_buf->data_len = reassembly_buf_sz;
454311fa71b9SJerome Forissier 
454411fa71b9SJerome Forissier                 /* Prepare final header: copy msg_type, length and message_seq,
454511fa71b9SJerome Forissier                  * then add standardised fragment_offset and fragment_length */
454611fa71b9SJerome Forissier                 memcpy(hs_buf->data, ssl->in_msg, 6);
454711fa71b9SJerome Forissier                 memset(hs_buf->data + 6, 0, 3);
454811fa71b9SJerome Forissier                 memcpy(hs_buf->data + 9, hs_buf->data + 1, 3);
454911fa71b9SJerome Forissier 
455011fa71b9SJerome Forissier                 hs_buf->is_valid = 1;
455111fa71b9SJerome Forissier 
455211fa71b9SJerome Forissier                 hs->buffering.total_bytes_buffered += reassembly_buf_sz;
455332b31808SJens Wiklander             } else {
455411fa71b9SJerome Forissier                 /* Make sure msg_type and length are consistent */
455532b31808SJens Wiklander                 if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) {
455611fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG(1, ("Fragment header mismatch - ignore"));
455711fa71b9SJerome Forissier                     /* Ignore */
455811fa71b9SJerome Forissier                     goto exit;
455911fa71b9SJerome Forissier                 }
456011fa71b9SJerome Forissier             }
456111fa71b9SJerome Forissier 
456232b31808SJens Wiklander             if (!hs_buf->is_complete) {
456311fa71b9SJerome Forissier                 size_t frag_len, frag_off;
456411fa71b9SJerome Forissier                 unsigned char * const msg = hs_buf->data + 12;
456511fa71b9SJerome Forissier 
456611fa71b9SJerome Forissier                 /*
456711fa71b9SJerome Forissier                  * Check and copy current fragment
456811fa71b9SJerome Forissier                  */
456911fa71b9SJerome Forissier 
457011fa71b9SJerome Forissier                 /* Validation of header fields already done in
457111fa71b9SJerome Forissier                  * mbedtls_ssl_prepare_handshake_record(). */
457211fa71b9SJerome Forissier                 frag_off = ssl_get_hs_frag_off(ssl);
457311fa71b9SJerome Forissier                 frag_len = ssl_get_hs_frag_len(ssl);
457411fa71b9SJerome Forissier 
45757901324dSJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
45767901324dSJerome Forissier                                           ", length = %" MBEDTLS_PRINTF_SIZET,
457711fa71b9SJerome Forissier                                           frag_off, frag_len));
457811fa71b9SJerome Forissier                 memcpy(msg + frag_off, ssl->in_msg + 12, frag_len);
457911fa71b9SJerome Forissier 
458032b31808SJens Wiklander                 if (hs_buf->is_fragmented) {
458111fa71b9SJerome Forissier                     unsigned char * const bitmask = msg + msg_len;
458211fa71b9SJerome Forissier                     ssl_bitmask_set(bitmask, frag_off, frag_len);
458311fa71b9SJerome Forissier                     hs_buf->is_complete = (ssl_bitmask_check(bitmask,
458411fa71b9SJerome Forissier                                                              msg_len) == 0);
458532b31808SJens Wiklander                 } else {
458611fa71b9SJerome Forissier                     hs_buf->is_complete = 1;
458711fa71b9SJerome Forissier                 }
458811fa71b9SJerome Forissier 
458911fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(2, ("message %scomplete",
459011fa71b9SJerome Forissier                                           hs_buf->is_complete ? "" : "not yet "));
459111fa71b9SJerome Forissier             }
459211fa71b9SJerome Forissier 
459311fa71b9SJerome Forissier             break;
459411fa71b9SJerome Forissier         }
459511fa71b9SJerome Forissier 
459611fa71b9SJerome Forissier         default:
459711fa71b9SJerome Forissier             /* We don't buffer other types of messages. */
459811fa71b9SJerome Forissier             break;
459911fa71b9SJerome Forissier     }
460011fa71b9SJerome Forissier 
460111fa71b9SJerome Forissier exit:
460211fa71b9SJerome Forissier 
460311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message"));
460432b31808SJens Wiklander     return ret;
460511fa71b9SJerome Forissier }
460611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
460711fa71b9SJerome Forissier 
4608039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
460911fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
461011fa71b9SJerome Forissier {
461111fa71b9SJerome Forissier     /*
461211fa71b9SJerome Forissier      * Consume last content-layer message and potentially
461311fa71b9SJerome Forissier      * update in_msglen which keeps track of the contents'
461411fa71b9SJerome Forissier      * consumption state.
461511fa71b9SJerome Forissier      *
461611fa71b9SJerome Forissier      * (1) Handshake messages:
461711fa71b9SJerome Forissier      *     Remove last handshake message, move content
461811fa71b9SJerome Forissier      *     and adapt in_msglen.
461911fa71b9SJerome Forissier      *
462011fa71b9SJerome Forissier      * (2) Alert messages:
462111fa71b9SJerome Forissier      *     Consume whole record content, in_msglen = 0.
462211fa71b9SJerome Forissier      *
462311fa71b9SJerome Forissier      * (3) Change cipher spec:
462411fa71b9SJerome Forissier      *     Consume whole record content, in_msglen = 0.
462511fa71b9SJerome Forissier      *
462611fa71b9SJerome Forissier      * (4) Application data:
462711fa71b9SJerome Forissier      *     Don't do anything - the record layer provides
462811fa71b9SJerome Forissier      *     the application data as a stream transport
462911fa71b9SJerome Forissier      *     and consumes through mbedtls_ssl_read only.
463011fa71b9SJerome Forissier      *
463111fa71b9SJerome Forissier      */
463211fa71b9SJerome Forissier 
463311fa71b9SJerome Forissier     /* Case (1): Handshake messages */
463432b31808SJens Wiklander     if (ssl->in_hslen != 0) {
463511fa71b9SJerome Forissier         /* Hard assertion to be sure that no application data
463611fa71b9SJerome Forissier          * is in flight, as corrupting ssl->in_msglen during
463711fa71b9SJerome Forissier          * ssl->in_offt != NULL is fatal. */
463832b31808SJens Wiklander         if (ssl->in_offt != NULL) {
463911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
464032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
464111fa71b9SJerome Forissier         }
464211fa71b9SJerome Forissier 
464311fa71b9SJerome Forissier         /*
464411fa71b9SJerome Forissier          * Get next Handshake message in the current record
464511fa71b9SJerome Forissier          */
464611fa71b9SJerome Forissier 
464711fa71b9SJerome Forissier         /* Notes:
464811fa71b9SJerome Forissier          * (1) in_hslen is not necessarily the size of the
464911fa71b9SJerome Forissier          *     current handshake content: If DTLS handshake
465011fa71b9SJerome Forissier          *     fragmentation is used, that's the fragment
465111fa71b9SJerome Forissier          *     size instead. Using the total handshake message
465211fa71b9SJerome Forissier          *     size here is faulty and should be changed at
465311fa71b9SJerome Forissier          *     some point.
465411fa71b9SJerome Forissier          * (2) While it doesn't seem to cause problems, one
465511fa71b9SJerome Forissier          *     has to be very careful not to assume that in_hslen
465611fa71b9SJerome Forissier          *     is always <= in_msglen in a sensible communication.
465711fa71b9SJerome Forissier          *     Again, it's wrong for DTLS handshake fragmentation.
465811fa71b9SJerome Forissier          *     The following check is therefore mandatory, and
465911fa71b9SJerome Forissier          *     should not be treated as a silently corrected assertion.
466011fa71b9SJerome Forissier          *     Additionally, ssl->in_hslen might be arbitrarily out of
466111fa71b9SJerome Forissier          *     bounds after handling a DTLS message with an unexpected
466211fa71b9SJerome Forissier          *     sequence number, see mbedtls_ssl_prepare_handshake_record.
466311fa71b9SJerome Forissier          */
466432b31808SJens Wiklander         if (ssl->in_hslen < ssl->in_msglen) {
466511fa71b9SJerome Forissier             ssl->in_msglen -= ssl->in_hslen;
466611fa71b9SJerome Forissier             memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen,
466711fa71b9SJerome Forissier                     ssl->in_msglen);
466811fa71b9SJerome Forissier 
466911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record",
467011fa71b9SJerome Forissier                                   ssl->in_msg, ssl->in_msglen);
467132b31808SJens Wiklander         } else {
467211fa71b9SJerome Forissier             ssl->in_msglen = 0;
467311fa71b9SJerome Forissier         }
467411fa71b9SJerome Forissier 
467511fa71b9SJerome Forissier         ssl->in_hslen   = 0;
467611fa71b9SJerome Forissier     }
467711fa71b9SJerome Forissier     /* Case (4): Application data */
467832b31808SJens Wiklander     else if (ssl->in_offt != NULL) {
467932b31808SJens Wiklander         return 0;
468011fa71b9SJerome Forissier     }
468111fa71b9SJerome Forissier     /* Everything else (CCS & Alerts) */
468232b31808SJens Wiklander     else {
468311fa71b9SJerome Forissier         ssl->in_msglen = 0;
468411fa71b9SJerome Forissier     }
468511fa71b9SJerome Forissier 
468632b31808SJens Wiklander     return 0;
468711fa71b9SJerome Forissier }
468811fa71b9SJerome Forissier 
4689039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
469011fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl)
469111fa71b9SJerome Forissier {
469232b31808SJens Wiklander     if (ssl->in_msglen > 0) {
469332b31808SJens Wiklander         return 1;
469432b31808SJens Wiklander     }
469511fa71b9SJerome Forissier 
469632b31808SJens Wiklander     return 0;
469711fa71b9SJerome Forissier }
469811fa71b9SJerome Forissier 
469911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
470011fa71b9SJerome Forissier 
470111fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl)
470211fa71b9SJerome Forissier {
470311fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
470432b31808SJens Wiklander     if (hs == NULL) {
470511fa71b9SJerome Forissier         return;
470632b31808SJens Wiklander     }
470711fa71b9SJerome Forissier 
470832b31808SJens Wiklander     if (hs->buffering.future_record.data != NULL) {
470911fa71b9SJerome Forissier         hs->buffering.total_bytes_buffered -=
471011fa71b9SJerome Forissier             hs->buffering.future_record.len;
471111fa71b9SJerome Forissier 
471211fa71b9SJerome Forissier         mbedtls_free(hs->buffering.future_record.data);
471311fa71b9SJerome Forissier         hs->buffering.future_record.data = NULL;
471411fa71b9SJerome Forissier     }
471511fa71b9SJerome Forissier }
471611fa71b9SJerome Forissier 
4717039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
471811fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl)
471911fa71b9SJerome Forissier {
472011fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
472111fa71b9SJerome Forissier     unsigned char *rec;
472211fa71b9SJerome Forissier     size_t rec_len;
472311fa71b9SJerome Forissier     unsigned rec_epoch;
472411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
472511fa71b9SJerome Forissier     size_t in_buf_len = ssl->in_buf_len;
472611fa71b9SJerome Forissier #else
472711fa71b9SJerome Forissier     size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
472811fa71b9SJerome Forissier #endif
472932b31808SJens Wiklander     if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
473032b31808SJens Wiklander         return 0;
473132b31808SJens Wiklander     }
473211fa71b9SJerome Forissier 
473332b31808SJens Wiklander     if (hs == NULL) {
473432b31808SJens Wiklander         return 0;
473532b31808SJens Wiklander     }
473611fa71b9SJerome Forissier 
473711fa71b9SJerome Forissier     rec       = hs->buffering.future_record.data;
473811fa71b9SJerome Forissier     rec_len   = hs->buffering.future_record.len;
473911fa71b9SJerome Forissier     rec_epoch = hs->buffering.future_record.epoch;
474011fa71b9SJerome Forissier 
474132b31808SJens Wiklander     if (rec == NULL) {
474232b31808SJens Wiklander         return 0;
474332b31808SJens Wiklander     }
474411fa71b9SJerome Forissier 
474511fa71b9SJerome Forissier     /* Only consider loading future records if the
474611fa71b9SJerome Forissier      * input buffer is empty. */
474732b31808SJens Wiklander     if (ssl_next_record_is_in_datagram(ssl) == 1) {
474832b31808SJens Wiklander         return 0;
474932b31808SJens Wiklander     }
475011fa71b9SJerome Forissier 
475111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record"));
475211fa71b9SJerome Forissier 
475332b31808SJens Wiklander     if (rec_epoch != ssl->in_epoch) {
475411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch."));
475511fa71b9SJerome Forissier         goto exit;
475611fa71b9SJerome Forissier     }
475711fa71b9SJerome Forissier 
475811fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("Found buffered record from current epoch - load"));
475911fa71b9SJerome Forissier 
476011fa71b9SJerome Forissier     /* Double-check that the record is not too large */
476132b31808SJens Wiklander     if (rec_len > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
476211fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
476332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
476411fa71b9SJerome Forissier     }
476511fa71b9SJerome Forissier 
476611fa71b9SJerome Forissier     memcpy(ssl->in_hdr, rec, rec_len);
476711fa71b9SJerome Forissier     ssl->in_left = rec_len;
476811fa71b9SJerome Forissier     ssl->next_record_offset = 0;
476911fa71b9SJerome Forissier 
477011fa71b9SJerome Forissier     ssl_free_buffered_record(ssl);
477111fa71b9SJerome Forissier 
477211fa71b9SJerome Forissier exit:
477311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record"));
477432b31808SJens Wiklander     return 0;
477511fa71b9SJerome Forissier }
477611fa71b9SJerome Forissier 
4777039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
477811fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
477911fa71b9SJerome Forissier                                     mbedtls_record const *rec)
478011fa71b9SJerome Forissier {
478111fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
478211fa71b9SJerome Forissier 
478311fa71b9SJerome Forissier     /* Don't buffer future records outside handshakes. */
478432b31808SJens Wiklander     if (hs == NULL) {
478532b31808SJens Wiklander         return 0;
478632b31808SJens Wiklander     }
478711fa71b9SJerome Forissier 
478811fa71b9SJerome Forissier     /* Only buffer handshake records (we are only interested
478911fa71b9SJerome Forissier      * in Finished messages). */
479032b31808SJens Wiklander     if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE) {
479132b31808SJens Wiklander         return 0;
479232b31808SJens Wiklander     }
479311fa71b9SJerome Forissier 
479411fa71b9SJerome Forissier     /* Don't buffer more than one future epoch record. */
479532b31808SJens Wiklander     if (hs->buffering.future_record.data != NULL) {
479632b31808SJens Wiklander         return 0;
479732b31808SJens Wiklander     }
479811fa71b9SJerome Forissier 
479911fa71b9SJerome Forissier     /* Don't buffer record if there's not enough buffering space remaining. */
480011fa71b9SJerome Forissier     if (rec->buf_len > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
480132b31808SJens Wiklander                         hs->buffering.total_bytes_buffered)) {
48027901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
48037901324dSJerome Forissier                                   " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
48047901324dSJerome Forissier                                   " (already %" MBEDTLS_PRINTF_SIZET
48057901324dSJerome Forissier                                   " bytes buffered) -- ignore\n",
48067901324dSJerome Forissier                                   rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
48077901324dSJerome Forissier                                   hs->buffering.total_bytes_buffered));
480832b31808SJens Wiklander         return 0;
480911fa71b9SJerome Forissier     }
481011fa71b9SJerome Forissier 
481111fa71b9SJerome Forissier     /* Buffer record */
481211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("Buffer record from epoch %u",
48137901324dSJerome Forissier                               ssl->in_epoch + 1U));
481411fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len);
481511fa71b9SJerome Forissier 
481611fa71b9SJerome Forissier     /* ssl_parse_record_header() only considers records
481711fa71b9SJerome Forissier      * of the next epoch as candidates for buffering. */
481811fa71b9SJerome Forissier     hs->buffering.future_record.epoch = ssl->in_epoch + 1;
481911fa71b9SJerome Forissier     hs->buffering.future_record.len   = rec->buf_len;
482011fa71b9SJerome Forissier 
482111fa71b9SJerome Forissier     hs->buffering.future_record.data =
482211fa71b9SJerome Forissier         mbedtls_calloc(1, hs->buffering.future_record.len);
482332b31808SJens Wiklander     if (hs->buffering.future_record.data == NULL) {
482411fa71b9SJerome Forissier         /* If we run out of RAM trying to buffer a
482511fa71b9SJerome Forissier          * record from the next epoch, just ignore. */
482632b31808SJens Wiklander         return 0;
482711fa71b9SJerome Forissier     }
482811fa71b9SJerome Forissier 
482911fa71b9SJerome Forissier     memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len);
483011fa71b9SJerome Forissier 
483111fa71b9SJerome Forissier     hs->buffering.total_bytes_buffered += rec->buf_len;
483232b31808SJens Wiklander     return 0;
483311fa71b9SJerome Forissier }
483411fa71b9SJerome Forissier 
483511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
483611fa71b9SJerome Forissier 
4837039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
483811fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl)
483911fa71b9SJerome Forissier {
484011fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
484111fa71b9SJerome Forissier     mbedtls_record rec;
484211fa71b9SJerome Forissier 
484311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
484411fa71b9SJerome Forissier     /* We might have buffered a future record; if so,
484511fa71b9SJerome Forissier      * and if the epoch matches now, load it.
484611fa71b9SJerome Forissier      * On success, this call will set ssl->in_left to
484711fa71b9SJerome Forissier      * the length of the buffered record, so that
484811fa71b9SJerome Forissier      * the calls to ssl_fetch_input() below will
484911fa71b9SJerome Forissier      * essentially be no-ops. */
485011fa71b9SJerome Forissier     ret = ssl_load_buffered_record(ssl);
485132b31808SJens Wiklander     if (ret != 0) {
485232b31808SJens Wiklander         return ret;
485332b31808SJens Wiklander     }
485411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
485511fa71b9SJerome Forissier 
485611fa71b9SJerome Forissier     /* Ensure that we have enough space available for the default form
485711fa71b9SJerome Forissier      * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
485811fa71b9SJerome Forissier      * with no space for CIDs counted in). */
485911fa71b9SJerome Forissier     ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl));
486032b31808SJens Wiklander     if (ret != 0) {
486111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
486232b31808SJens Wiklander         return ret;
486311fa71b9SJerome Forissier     }
486411fa71b9SJerome Forissier 
486511fa71b9SJerome Forissier     ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec);
486632b31808SJens Wiklander     if (ret != 0) {
486711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
486832b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
486932b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
487011fa71b9SJerome Forissier                 ret = ssl_buffer_future_record(ssl, &rec);
487132b31808SJens Wiklander                 if (ret != 0) {
487232b31808SJens Wiklander                     return ret;
487332b31808SJens Wiklander                 }
487411fa71b9SJerome Forissier 
487511fa71b9SJerome Forissier                 /* Fall through to handling of unexpected records */
487611fa71b9SJerome Forissier                 ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
487711fa71b9SJerome Forissier             }
487811fa71b9SJerome Forissier 
487932b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) {
488011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
488111fa71b9SJerome Forissier                 /* Reset in pointers to default state for TLS/DTLS records,
488211fa71b9SJerome Forissier                  * assuming no CID and no offset between record content and
488311fa71b9SJerome Forissier                  * record plaintext. */
488411fa71b9SJerome Forissier                 mbedtls_ssl_update_in_pointers(ssl);
488511fa71b9SJerome Forissier 
488611fa71b9SJerome Forissier                 /* Setup internal message pointers from record structure. */
488711fa71b9SJerome Forissier                 ssl->in_msgtype = rec.type;
488811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
488911fa71b9SJerome Forissier                 ssl->in_len = ssl->in_cid + rec.cid_len;
489011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
489111fa71b9SJerome Forissier                 ssl->in_iv  = ssl->in_msg = ssl->in_len + 2;
489211fa71b9SJerome Forissier                 ssl->in_msglen = rec.data_len;
489311fa71b9SJerome Forissier 
489411fa71b9SJerome Forissier                 ret = ssl_check_client_reconnect(ssl);
489511fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret);
489632b31808SJens Wiklander                 if (ret != 0) {
489732b31808SJens Wiklander                     return ret;
489832b31808SJens Wiklander                 }
489911fa71b9SJerome Forissier #endif
490011fa71b9SJerome Forissier 
490111fa71b9SJerome Forissier                 /* Skip unexpected record (but not whole datagram) */
490211fa71b9SJerome Forissier                 ssl->next_record_offset = rec.buf_len;
490311fa71b9SJerome Forissier 
490411fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record "
490511fa71b9SJerome Forissier                                           "(header)"));
490632b31808SJens Wiklander             } else {
490711fa71b9SJerome Forissier                 /* Skip invalid record and the rest of the datagram */
490811fa71b9SJerome Forissier                 ssl->next_record_offset = 0;
490911fa71b9SJerome Forissier                 ssl->in_left = 0;
491011fa71b9SJerome Forissier 
491111fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record "
491211fa71b9SJerome Forissier                                           "(header)"));
491311fa71b9SJerome Forissier             }
491411fa71b9SJerome Forissier 
491511fa71b9SJerome Forissier             /* Get next record */
491632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
491732b31808SJens Wiklander         } else
491811fa71b9SJerome Forissier #endif
491911fa71b9SJerome Forissier         {
492032b31808SJens Wiklander             return ret;
492111fa71b9SJerome Forissier         }
492211fa71b9SJerome Forissier     }
492311fa71b9SJerome Forissier 
492411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
492532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
492611fa71b9SJerome Forissier         /* Remember offset of next record within datagram. */
492711fa71b9SJerome Forissier         ssl->next_record_offset = rec.buf_len;
492832b31808SJens Wiklander         if (ssl->next_record_offset < ssl->in_left) {
492911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram"));
493011fa71b9SJerome Forissier         }
493132b31808SJens Wiklander     } else
493211fa71b9SJerome Forissier #endif
493311fa71b9SJerome Forissier     {
493411fa71b9SJerome Forissier         /*
493511fa71b9SJerome Forissier          * Fetch record contents from underlying transport.
493611fa71b9SJerome Forissier          */
493711fa71b9SJerome Forissier         ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len);
493832b31808SJens Wiklander         if (ret != 0) {
493911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
494032b31808SJens Wiklander             return ret;
494111fa71b9SJerome Forissier         }
494211fa71b9SJerome Forissier 
494311fa71b9SJerome Forissier         ssl->in_left = 0;
494411fa71b9SJerome Forissier     }
494511fa71b9SJerome Forissier 
494611fa71b9SJerome Forissier     /*
494711fa71b9SJerome Forissier      * Decrypt record contents.
494811fa71b9SJerome Forissier      */
494911fa71b9SJerome Forissier 
495032b31808SJens Wiklander     if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) {
495111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
495232b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
495311fa71b9SJerome Forissier             /* Silently discard invalid records */
495432b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
495511fa71b9SJerome Forissier                 /* Except when waiting for Finished as a bad mac here
495611fa71b9SJerome Forissier                  * probably means something went wrong in the handshake
495711fa71b9SJerome Forissier                  * (eg wrong psk used, mitm downgrade attempt, etc.) */
495811fa71b9SJerome Forissier                 if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
495932b31808SJens Wiklander                     ssl->state == MBEDTLS_SSL_SERVER_FINISHED) {
496011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
496132b31808SJens Wiklander                     if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
496211fa71b9SJerome Forissier                         mbedtls_ssl_send_alert_message(ssl,
496311fa71b9SJerome Forissier                                                        MBEDTLS_SSL_ALERT_LEVEL_FATAL,
496411fa71b9SJerome Forissier                                                        MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
496511fa71b9SJerome Forissier                     }
496611fa71b9SJerome Forissier #endif
496732b31808SJens Wiklander                     return ret;
496811fa71b9SJerome Forissier                 }
496911fa71b9SJerome Forissier 
497011fa71b9SJerome Forissier                 if (ssl->conf->badmac_limit != 0 &&
497132b31808SJens Wiklander                     ++ssl->badmac_seen >= ssl->conf->badmac_limit) {
497211fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
497332b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_INVALID_MAC;
497411fa71b9SJerome Forissier                 }
497511fa71b9SJerome Forissier 
497611fa71b9SJerome Forissier                 /* As above, invalid records cause
497711fa71b9SJerome Forissier                  * dismissal of the whole datagram. */
497811fa71b9SJerome Forissier 
497911fa71b9SJerome Forissier                 ssl->next_record_offset = 0;
498011fa71b9SJerome Forissier                 ssl->in_left = 0;
498111fa71b9SJerome Forissier 
498211fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)"));
498332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
498411fa71b9SJerome Forissier             }
498511fa71b9SJerome Forissier 
498632b31808SJens Wiklander             return ret;
498732b31808SJens Wiklander         } else
498811fa71b9SJerome Forissier #endif
498911fa71b9SJerome Forissier         {
499011fa71b9SJerome Forissier             /* Error out (and send alert) on invalid records */
499111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
499232b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
499311fa71b9SJerome Forissier                 mbedtls_ssl_send_alert_message(ssl,
499411fa71b9SJerome Forissier                                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
499511fa71b9SJerome Forissier                                                MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
499611fa71b9SJerome Forissier             }
499711fa71b9SJerome Forissier #endif
499832b31808SJens Wiklander             return ret;
499911fa71b9SJerome Forissier         }
500011fa71b9SJerome Forissier     }
500111fa71b9SJerome Forissier 
500211fa71b9SJerome Forissier 
500311fa71b9SJerome Forissier     /* Reset in pointers to default state for TLS/DTLS records,
500411fa71b9SJerome Forissier      * assuming no CID and no offset between record content and
500511fa71b9SJerome Forissier      * record plaintext. */
500611fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers(ssl);
500711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
500811fa71b9SJerome Forissier     ssl->in_len = ssl->in_cid + rec.cid_len;
500911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
501011fa71b9SJerome Forissier     ssl->in_iv  = ssl->in_len + 2;
501111fa71b9SJerome Forissier 
501211fa71b9SJerome Forissier     /* The record content type may change during decryption,
501311fa71b9SJerome Forissier      * so re-read it. */
501411fa71b9SJerome Forissier     ssl->in_msgtype = rec.type;
501511fa71b9SJerome Forissier     /* Also update the input buffer, because unfortunately
501611fa71b9SJerome Forissier      * the server-side ssl_parse_client_hello() reparses the
501711fa71b9SJerome Forissier      * record header when receiving a ClientHello initiating
501811fa71b9SJerome Forissier      * a renegotiation. */
501911fa71b9SJerome Forissier     ssl->in_hdr[0] = rec.type;
502011fa71b9SJerome Forissier     ssl->in_msg    = rec.buf + rec.data_offset;
502111fa71b9SJerome Forissier     ssl->in_msglen = rec.data_len;
5022039e02dfSJerome Forissier     MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0);
502311fa71b9SJerome Forissier 
502432b31808SJens Wiklander     return 0;
502511fa71b9SJerome Forissier }
502611fa71b9SJerome Forissier 
502711fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
502811fa71b9SJerome Forissier {
502911fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
503011fa71b9SJerome Forissier 
503111fa71b9SJerome Forissier     /*
503211fa71b9SJerome Forissier      * Handle particular types of records
503311fa71b9SJerome Forissier      */
503432b31808SJens Wiklander     if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
503532b31808SJens Wiklander         if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) {
503632b31808SJens Wiklander             return ret;
503711fa71b9SJerome Forissier         }
503811fa71b9SJerome Forissier     }
503911fa71b9SJerome Forissier 
504032b31808SJens Wiklander     if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
504132b31808SJens Wiklander         if (ssl->in_msglen != 1) {
50427901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
504311fa71b9SJerome Forissier                                       ssl->in_msglen));
504432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
504511fa71b9SJerome Forissier         }
504611fa71b9SJerome Forissier 
504732b31808SJens Wiklander         if (ssl->in_msg[0] != 1) {
504811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x",
504911fa71b9SJerome Forissier                                       ssl->in_msg[0]));
505032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
505111fa71b9SJerome Forissier         }
505211fa71b9SJerome Forissier 
505311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
505411fa71b9SJerome Forissier         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
505511fa71b9SJerome Forissier             ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC    &&
505632b31808SJens Wiklander             ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
505732b31808SJens Wiklander             if (ssl->handshake == NULL) {
505811fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(1, ("dropping ChangeCipherSpec outside handshake"));
505932b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
506011fa71b9SJerome Forissier             }
506111fa71b9SJerome Forissier 
506211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("received out-of-order ChangeCipherSpec - remember"));
506332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
506411fa71b9SJerome Forissier         }
506511fa71b9SJerome Forissier #endif
506632b31808SJens Wiklander 
506732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
506832b31808SJens Wiklander         if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
506932b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
507032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
507132b31808SJens Wiklander                                   ("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"));
507232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
507332b31808SJens Wiklander #else
507432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
507532b31808SJens Wiklander                                   ("ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"));
507632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
507732b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
507832b31808SJens Wiklander         }
507932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
508011fa71b9SJerome Forissier     }
508111fa71b9SJerome Forissier 
508232b31808SJens Wiklander     if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
508332b31808SJens Wiklander         if (ssl->in_msglen != 2) {
508411fa71b9SJerome Forissier             /* Note: Standard allows for more than one 2 byte alert
508511fa71b9SJerome Forissier                to be packed in a single message, but Mbed TLS doesn't
508611fa71b9SJerome Forissier                currently support this. */
50877901324dSJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
508811fa71b9SJerome Forissier                                       ssl->in_msglen));
508932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INVALID_RECORD;
509011fa71b9SJerome Forissier         }
509111fa71b9SJerome Forissier 
50927901324dSJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]",
509311fa71b9SJerome Forissier                                   ssl->in_msg[0], ssl->in_msg[1]));
509411fa71b9SJerome Forissier 
509511fa71b9SJerome Forissier         /*
509611fa71b9SJerome Forissier          * Ignore non-fatal alerts, except close_notify and no_renegotiation
509711fa71b9SJerome Forissier          */
509832b31808SJens Wiklander         if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) {
509911fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)",
510011fa71b9SJerome Forissier                                       ssl->in_msg[1]));
510132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
510211fa71b9SJerome Forissier         }
510311fa71b9SJerome Forissier 
510411fa71b9SJerome Forissier         if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
510532b31808SJens Wiklander             ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) {
510611fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message"));
510732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
510811fa71b9SJerome Forissier         }
510911fa71b9SJerome Forissier 
511011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
511111fa71b9SJerome Forissier         if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
511232b31808SJens Wiklander             ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) {
511332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert"));
511411fa71b9SJerome Forissier             /* Will be handled when trying to parse ServerHello */
511532b31808SJens Wiklander             return 0;
511611fa71b9SJerome Forissier         }
511711fa71b9SJerome Forissier #endif
511811fa71b9SJerome Forissier         /* Silently ignore: fetch new message */
511911fa71b9SJerome Forissier         return MBEDTLS_ERR_SSL_NON_FATAL;
512011fa71b9SJerome Forissier     }
512111fa71b9SJerome Forissier 
512211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
512332b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
512411fa71b9SJerome Forissier         /* Drop unexpected ApplicationData records,
512511fa71b9SJerome Forissier          * except at the beginning of renegotiations */
512611fa71b9SJerome Forissier         if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
512732b31808SJens Wiklander             mbedtls_ssl_is_handshake_over(ssl) == 0
512811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
512911fa71b9SJerome Forissier             && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
513011fa71b9SJerome Forissier                  ssl->state == MBEDTLS_SSL_SERVER_HELLO)
513111fa71b9SJerome Forissier #endif
513232b31808SJens Wiklander             ) {
513311fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData"));
513432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_NON_FATAL;
513511fa71b9SJerome Forissier         }
513611fa71b9SJerome Forissier 
513711fa71b9SJerome Forissier         if (ssl->handshake != NULL &&
513832b31808SJens Wiklander             mbedtls_ssl_is_handshake_over(ssl) == 1) {
513911fa71b9SJerome Forissier             mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
514011fa71b9SJerome Forissier         }
514111fa71b9SJerome Forissier     }
514211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
514311fa71b9SJerome Forissier 
514432b31808SJens Wiklander     return 0;
514511fa71b9SJerome Forissier }
514611fa71b9SJerome Forissier 
514711fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl)
514811fa71b9SJerome Forissier {
514932b31808SJens Wiklander     return mbedtls_ssl_send_alert_message(ssl,
515011fa71b9SJerome Forissier                                           MBEDTLS_SSL_ALERT_LEVEL_FATAL,
515132b31808SJens Wiklander                                           MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
515211fa71b9SJerome Forissier }
515311fa71b9SJerome Forissier 
515411fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
515511fa71b9SJerome Forissier                                    unsigned char level,
515611fa71b9SJerome Forissier                                    unsigned char message)
515711fa71b9SJerome Forissier {
515811fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
515911fa71b9SJerome Forissier 
516032b31808SJens Wiklander     if (ssl == NULL || ssl->conf == NULL) {
516132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
516232b31808SJens Wiklander     }
516311fa71b9SJerome Forissier 
516432b31808SJens Wiklander     if (ssl->out_left != 0) {
516532b31808SJens Wiklander         return mbedtls_ssl_flush_output(ssl);
516632b31808SJens Wiklander     }
5167039e02dfSJerome Forissier 
516811fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message"));
516911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("send alert level=%u message=%u", level, message));
517011fa71b9SJerome Forissier 
517111fa71b9SJerome Forissier     ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
517211fa71b9SJerome Forissier     ssl->out_msglen = 2;
517311fa71b9SJerome Forissier     ssl->out_msg[0] = level;
517411fa71b9SJerome Forissier     ssl->out_msg[1] = message;
517511fa71b9SJerome Forissier 
517632b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
517711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
517832b31808SJens Wiklander         return ret;
517911fa71b9SJerome Forissier     }
518011fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message"));
518111fa71b9SJerome Forissier 
518232b31808SJens Wiklander     return 0;
518311fa71b9SJerome Forissier }
518411fa71b9SJerome Forissier 
518511fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
518611fa71b9SJerome Forissier {
518711fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
518811fa71b9SJerome Forissier 
518911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
519011fa71b9SJerome Forissier 
519111fa71b9SJerome Forissier     ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
519211fa71b9SJerome Forissier     ssl->out_msglen  = 1;
519311fa71b9SJerome Forissier     ssl->out_msg[0]  = 1;
519411fa71b9SJerome Forissier 
519511fa71b9SJerome Forissier     ssl->state++;
519611fa71b9SJerome Forissier 
519732b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
519811fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
519932b31808SJens Wiklander         return ret;
520011fa71b9SJerome Forissier     }
520111fa71b9SJerome Forissier 
520211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));
520311fa71b9SJerome Forissier 
520432b31808SJens Wiklander     return 0;
520511fa71b9SJerome Forissier }
520611fa71b9SJerome Forissier 
520711fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
520811fa71b9SJerome Forissier {
520911fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
521011fa71b9SJerome Forissier 
521111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec"));
521211fa71b9SJerome Forissier 
521332b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
521411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
521532b31808SJens Wiklander         return ret;
521611fa71b9SJerome Forissier     }
521711fa71b9SJerome Forissier 
521832b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
521911fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message"));
522011fa71b9SJerome Forissier         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
522111fa71b9SJerome Forissier                                        MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
522232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
522311fa71b9SJerome Forissier     }
522411fa71b9SJerome Forissier 
522511fa71b9SJerome Forissier     /* CCS records are only accepted if they have length 1 and content '1',
522611fa71b9SJerome Forissier      * so we don't need to check this here. */
522711fa71b9SJerome Forissier 
522811fa71b9SJerome Forissier     /*
522911fa71b9SJerome Forissier      * Switch to our negotiated transform and session parameters for inbound
523011fa71b9SJerome Forissier      * data.
523111fa71b9SJerome Forissier      */
523211fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for inbound data"));
523332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
523411fa71b9SJerome Forissier     ssl->transform_in = ssl->transform_negotiate;
523532b31808SJens Wiklander #endif
523611fa71b9SJerome Forissier     ssl->session_in = ssl->session_negotiate;
523711fa71b9SJerome Forissier 
523811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
523932b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
524011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
524111fa71b9SJerome Forissier         mbedtls_ssl_dtls_replay_reset(ssl);
524211fa71b9SJerome Forissier #endif
524311fa71b9SJerome Forissier 
524411fa71b9SJerome Forissier         /* Increment epoch */
524532b31808SJens Wiklander         if (++ssl->in_epoch == 0) {
524611fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
524711fa71b9SJerome Forissier             /* This is highly unlikely to happen for legitimate reasons, so
524811fa71b9SJerome Forissier                treat it as an attack and don't send an alert. */
524932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
525011fa71b9SJerome Forissier         }
525132b31808SJens Wiklander     } else
525211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
525332b31808SJens Wiklander     memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
525411fa71b9SJerome Forissier 
525511fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers(ssl);
525611fa71b9SJerome Forissier 
525711fa71b9SJerome Forissier     ssl->state++;
525811fa71b9SJerome Forissier 
525911fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec"));
526011fa71b9SJerome Forissier 
526132b31808SJens Wiklander     return 0;
526211fa71b9SJerome Forissier }
526311fa71b9SJerome Forissier 
526411fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the
526511fa71b9SJerome Forissier  * next outgoing record is set, deduce the other pointers.
526611fa71b9SJerome Forissier  *
526711fa71b9SJerome Forissier  * Note: For TLS, we save the implicit record sequence number
526811fa71b9SJerome Forissier  *       (entering MAC computation) in the 8 bytes before ssl->out_hdr,
526911fa71b9SJerome Forissier  *       and the caller has to make sure there's space for this.
527011fa71b9SJerome Forissier  */
527111fa71b9SJerome Forissier 
52727901324dSJerome Forissier static size_t ssl_transform_get_explicit_iv_len(
52737901324dSJerome Forissier     mbedtls_ssl_transform const *transform)
52747901324dSJerome Forissier {
527532b31808SJens Wiklander     return transform->ivlen - transform->fixed_ivlen;
52767901324dSJerome Forissier }
52777901324dSJerome Forissier 
527811fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
527911fa71b9SJerome Forissier                                      mbedtls_ssl_transform *transform)
528011fa71b9SJerome Forissier {
528111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
528232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
528311fa71b9SJerome Forissier         ssl->out_ctr = ssl->out_hdr +  3;
528411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
528532b31808SJens Wiklander         ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
528611fa71b9SJerome Forissier         ssl->out_len = ssl->out_cid;
528732b31808SJens Wiklander         if (transform != NULL) {
528811fa71b9SJerome Forissier             ssl->out_len += transform->out_cid_len;
528932b31808SJens Wiklander         }
529011fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
529132b31808SJens Wiklander         ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
529211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
529311fa71b9SJerome Forissier         ssl->out_iv  = ssl->out_len + 2;
529432b31808SJens Wiklander     } else
529511fa71b9SJerome Forissier #endif
529611fa71b9SJerome Forissier     {
529711fa71b9SJerome Forissier         ssl->out_len = ssl->out_hdr + 3;
529811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
529911fa71b9SJerome Forissier         ssl->out_cid = ssl->out_len;
530011fa71b9SJerome Forissier #endif
530111fa71b9SJerome Forissier         ssl->out_iv  = ssl->out_hdr + 5;
530211fa71b9SJerome Forissier     }
530311fa71b9SJerome Forissier 
530411fa71b9SJerome Forissier     ssl->out_msg = ssl->out_iv;
53057901324dSJerome Forissier     /* Adjust out_msg to make space for explicit IV, if used. */
530632b31808SJens Wiklander     if (transform != NULL) {
53077901324dSJerome Forissier         ssl->out_msg += ssl_transform_get_explicit_iv_len(transform);
530811fa71b9SJerome Forissier     }
530932b31808SJens Wiklander }
531011fa71b9SJerome Forissier 
531111fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the
531211fa71b9SJerome Forissier  * next incoming record is set, deduce the other pointers.
531311fa71b9SJerome Forissier  *
531411fa71b9SJerome Forissier  * Note: For TLS, we save the implicit record sequence number
531511fa71b9SJerome Forissier  *       (entering MAC computation) in the 8 bytes before ssl->in_hdr,
531611fa71b9SJerome Forissier  *       and the caller has to make sure there's space for this.
531711fa71b9SJerome Forissier  */
531811fa71b9SJerome Forissier 
531911fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
532011fa71b9SJerome Forissier {
532111fa71b9SJerome Forissier     /* This function sets the pointers to match the case
532211fa71b9SJerome Forissier      * of unprotected TLS/DTLS records, with both  ssl->in_iv
532311fa71b9SJerome Forissier      * and ssl->in_msg pointing to the beginning of the record
532411fa71b9SJerome Forissier      * content.
532511fa71b9SJerome Forissier      *
532611fa71b9SJerome Forissier      * When decrypting a protected record, ssl->in_msg
532711fa71b9SJerome Forissier      * will be shifted to point to the beginning of the
532811fa71b9SJerome Forissier      * record plaintext.
532911fa71b9SJerome Forissier      */
533011fa71b9SJerome Forissier 
533111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
533232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
533311fa71b9SJerome Forissier         /* This sets the header pointers to match records
533411fa71b9SJerome Forissier          * without CID. When we receive a record containing
533511fa71b9SJerome Forissier          * a CID, the fields are shifted accordingly in
533611fa71b9SJerome Forissier          * ssl_parse_record_header(). */
533711fa71b9SJerome Forissier         ssl->in_ctr = ssl->in_hdr +  3;
533811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
533932b31808SJens Wiklander         ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
534011fa71b9SJerome Forissier         ssl->in_len = ssl->in_cid; /* Default: no CID */
534111fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
534232b31808SJens Wiklander         ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
534311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
534411fa71b9SJerome Forissier         ssl->in_iv  = ssl->in_len + 2;
534532b31808SJens Wiklander     } else
534611fa71b9SJerome Forissier #endif
534711fa71b9SJerome Forissier     {
534832b31808SJens Wiklander         ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
534911fa71b9SJerome Forissier         ssl->in_len = ssl->in_hdr + 3;
535011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
535111fa71b9SJerome Forissier         ssl->in_cid = ssl->in_len;
535211fa71b9SJerome Forissier #endif
535311fa71b9SJerome Forissier         ssl->in_iv  = ssl->in_hdr + 5;
535411fa71b9SJerome Forissier     }
535511fa71b9SJerome Forissier 
535611fa71b9SJerome Forissier     /* This will be adjusted at record decryption time. */
535711fa71b9SJerome Forissier     ssl->in_msg = ssl->in_iv;
535811fa71b9SJerome Forissier }
535911fa71b9SJerome Forissier 
536011fa71b9SJerome Forissier /*
536111fa71b9SJerome Forissier  * Setup an SSL context
536211fa71b9SJerome Forissier  */
536311fa71b9SJerome Forissier 
536411fa71b9SJerome Forissier void mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
536511fa71b9SJerome Forissier {
536611fa71b9SJerome Forissier     /* Set the incoming and outgoing record pointers. */
536711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
536832b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
536911fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf;
537011fa71b9SJerome Forissier         ssl->in_hdr  = ssl->in_buf;
537132b31808SJens Wiklander     } else
537211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
537311fa71b9SJerome Forissier     {
537432b31808SJens Wiklander         ssl->out_ctr = ssl->out_buf;
537511fa71b9SJerome Forissier         ssl->out_hdr = ssl->out_buf + 8;
537611fa71b9SJerome Forissier         ssl->in_hdr  = ssl->in_buf  + 8;
537711fa71b9SJerome Forissier     }
537811fa71b9SJerome Forissier 
537911fa71b9SJerome Forissier     /* Derive other internal pointers. */
538011fa71b9SJerome Forissier     mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
538111fa71b9SJerome Forissier     mbedtls_ssl_update_in_pointers(ssl);
538211fa71b9SJerome Forissier }
538311fa71b9SJerome Forissier 
538411fa71b9SJerome Forissier /*
538511fa71b9SJerome Forissier  * SSL get accessors
538611fa71b9SJerome Forissier  */
538711fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl)
538811fa71b9SJerome Forissier {
538932b31808SJens Wiklander     return ssl->in_offt == NULL ? 0 : ssl->in_msglen;
539011fa71b9SJerome Forissier }
539111fa71b9SJerome Forissier 
539211fa71b9SJerome Forissier int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl)
539311fa71b9SJerome Forissier {
539411fa71b9SJerome Forissier     /*
539511fa71b9SJerome Forissier      * Case A: We're currently holding back
539611fa71b9SJerome Forissier      * a message for further processing.
539711fa71b9SJerome Forissier      */
539811fa71b9SJerome Forissier 
539932b31808SJens Wiklander     if (ssl->keep_current_message == 1) {
540011fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: record held back for processing"));
540132b31808SJens Wiklander         return 1;
540211fa71b9SJerome Forissier     }
540311fa71b9SJerome Forissier 
540411fa71b9SJerome Forissier     /*
540511fa71b9SJerome Forissier      * Case B: Further records are pending in the current datagram.
540611fa71b9SJerome Forissier      */
540711fa71b9SJerome Forissier 
540811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
540911fa71b9SJerome Forissier     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
541032b31808SJens Wiklander         ssl->in_left > ssl->next_record_offset) {
541111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: more records within current datagram"));
541232b31808SJens Wiklander         return 1;
541311fa71b9SJerome Forissier     }
541411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
541511fa71b9SJerome Forissier 
541611fa71b9SJerome Forissier     /*
541711fa71b9SJerome Forissier      * Case C: A handshake message is being processed.
541811fa71b9SJerome Forissier      */
541911fa71b9SJerome Forissier 
542032b31808SJens Wiklander     if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) {
542132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
542232b31808SJens Wiklander                               ("ssl_check_pending: more handshake messages within current record"));
542332b31808SJens Wiklander         return 1;
542411fa71b9SJerome Forissier     }
542511fa71b9SJerome Forissier 
542611fa71b9SJerome Forissier     /*
542711fa71b9SJerome Forissier      * Case D: An application data message is being processed
542811fa71b9SJerome Forissier      */
542932b31808SJens Wiklander     if (ssl->in_offt != NULL) {
543011fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: application data record is being processed"));
543132b31808SJens Wiklander         return 1;
543211fa71b9SJerome Forissier     }
543311fa71b9SJerome Forissier 
543411fa71b9SJerome Forissier     /*
543511fa71b9SJerome Forissier      * In all other cases, the rest of the message can be dropped.
543611fa71b9SJerome Forissier      * As in ssl_get_next_record, this needs to be adapted if
543711fa71b9SJerome Forissier      * we implement support for multiple alerts in single records.
543811fa71b9SJerome Forissier      */
543911fa71b9SJerome Forissier 
544011fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending"));
544132b31808SJens Wiklander     return 0;
544211fa71b9SJerome Forissier }
544311fa71b9SJerome Forissier 
544411fa71b9SJerome Forissier 
544511fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl)
544611fa71b9SJerome Forissier {
544711fa71b9SJerome Forissier     size_t transform_expansion = 0;
544811fa71b9SJerome Forissier     const mbedtls_ssl_transform *transform = ssl->transform_out;
544911fa71b9SJerome Forissier     unsigned block_size;
545032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
545132b31808SJens Wiklander     psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
545232b31808SJens Wiklander     psa_key_type_t key_type;
545332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
545411fa71b9SJerome Forissier 
545511fa71b9SJerome Forissier     size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl);
545611fa71b9SJerome Forissier 
545732b31808SJens Wiklander     if (transform == NULL) {
545832b31808SJens Wiklander         return (int) out_hdr_len;
545932b31808SJens Wiklander     }
546011fa71b9SJerome Forissier 
546111fa71b9SJerome Forissier 
546232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
546332b31808SJens Wiklander     if (transform->psa_alg == PSA_ALG_GCM ||
546432b31808SJens Wiklander         transform->psa_alg == PSA_ALG_CCM ||
546532b31808SJens Wiklander         transform->psa_alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 8) ||
546632b31808SJens Wiklander         transform->psa_alg == PSA_ALG_CHACHA20_POLY1305 ||
546732b31808SJens Wiklander         transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) {
546832b31808SJens Wiklander         transform_expansion = transform->minlen;
546932b31808SJens Wiklander     } else if (transform->psa_alg == PSA_ALG_CBC_NO_PADDING) {
547032b31808SJens Wiklander         (void) psa_get_key_attributes(transform->psa_key_enc, &attr);
547132b31808SJens Wiklander         key_type = psa_get_key_type(&attr);
547232b31808SJens Wiklander 
547332b31808SJens Wiklander         block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
547432b31808SJens Wiklander 
547532b31808SJens Wiklander         /* Expansion due to the addition of the MAC. */
547632b31808SJens Wiklander         transform_expansion += transform->maclen;
547732b31808SJens Wiklander 
547832b31808SJens Wiklander         /* Expansion due to the addition of CBC padding;
547932b31808SJens Wiklander          * Theoretically up to 256 bytes, but we never use
548032b31808SJens Wiklander          * more than the block size of the underlying cipher. */
548132b31808SJens Wiklander         transform_expansion += block_size;
548232b31808SJens Wiklander 
548332b31808SJens Wiklander         /* For TLS 1.2 or higher, an explicit IV is added
548432b31808SJens Wiklander          * after the record header. */
548532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
548632b31808SJens Wiklander         transform_expansion += block_size;
548732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
548832b31808SJens Wiklander     } else {
548932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
549032b31808SJens Wiklander                               ("Unsupported psa_alg spotted in mbedtls_ssl_get_record_expansion()"));
549132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
549232b31808SJens Wiklander     }
549332b31808SJens Wiklander #else
549432b31808SJens Wiklander     switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) {
549511fa71b9SJerome Forissier         case MBEDTLS_MODE_GCM:
549611fa71b9SJerome Forissier         case MBEDTLS_MODE_CCM:
549711fa71b9SJerome Forissier         case MBEDTLS_MODE_CHACHAPOLY:
549811fa71b9SJerome Forissier         case MBEDTLS_MODE_STREAM:
549911fa71b9SJerome Forissier             transform_expansion = transform->minlen;
550011fa71b9SJerome Forissier             break;
550111fa71b9SJerome Forissier 
550211fa71b9SJerome Forissier         case MBEDTLS_MODE_CBC:
550311fa71b9SJerome Forissier 
550411fa71b9SJerome Forissier             block_size = mbedtls_cipher_get_block_size(
550511fa71b9SJerome Forissier                 &transform->cipher_ctx_enc);
550611fa71b9SJerome Forissier 
550711fa71b9SJerome Forissier             /* Expansion due to the addition of the MAC. */
550811fa71b9SJerome Forissier             transform_expansion += transform->maclen;
550911fa71b9SJerome Forissier 
551011fa71b9SJerome Forissier             /* Expansion due to the addition of CBC padding;
551111fa71b9SJerome Forissier              * Theoretically up to 256 bytes, but we never use
551211fa71b9SJerome Forissier              * more than the block size of the underlying cipher. */
551311fa71b9SJerome Forissier             transform_expansion += block_size;
551411fa71b9SJerome Forissier 
551532b31808SJens Wiklander             /* For TLS 1.2 or higher, an explicit IV is added
551611fa71b9SJerome Forissier              * after the record header. */
551732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
551811fa71b9SJerome Forissier             transform_expansion += block_size;
551932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
552011fa71b9SJerome Forissier 
552111fa71b9SJerome Forissier             break;
552211fa71b9SJerome Forissier 
552311fa71b9SJerome Forissier         default:
552411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
552532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
552611fa71b9SJerome Forissier     }
552732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
552811fa71b9SJerome Forissier 
552911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
553032b31808SJens Wiklander     if (transform->out_cid_len != 0) {
553111fa71b9SJerome Forissier         transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
553232b31808SJens Wiklander     }
553311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
553411fa71b9SJerome Forissier 
553532b31808SJens Wiklander     return (int) (out_hdr_len + transform_expansion);
553611fa71b9SJerome Forissier }
553711fa71b9SJerome Forissier 
553811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
553911fa71b9SJerome Forissier /*
554011fa71b9SJerome Forissier  * Check record counters and renegotiate if they're above the limit.
554111fa71b9SJerome Forissier  */
5542039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
554311fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
554411fa71b9SJerome Forissier {
554511fa71b9SJerome Forissier     size_t ep_len = mbedtls_ssl_ep_len(ssl);
554611fa71b9SJerome Forissier     int in_ctr_cmp;
554711fa71b9SJerome Forissier     int out_ctr_cmp;
554811fa71b9SJerome Forissier 
554932b31808SJens Wiklander     if (mbedtls_ssl_is_handshake_over(ssl) == 0 ||
555011fa71b9SJerome Forissier         ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
555132b31808SJens Wiklander         ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
555232b31808SJens Wiklander         return 0;
555311fa71b9SJerome Forissier     }
555411fa71b9SJerome Forissier 
555511fa71b9SJerome Forissier     in_ctr_cmp = memcmp(ssl->in_ctr + ep_len,
555632b31808SJens Wiklander                         &ssl->conf->renego_period[ep_len],
555732b31808SJens Wiklander                         MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len);
555832b31808SJens Wiklander     out_ctr_cmp = memcmp(&ssl->cur_out_ctr[ep_len],
555932b31808SJens Wiklander                          &ssl->conf->renego_period[ep_len],
556032b31808SJens Wiklander                          sizeof(ssl->cur_out_ctr) - ep_len);
556111fa71b9SJerome Forissier 
556232b31808SJens Wiklander     if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) {
556332b31808SJens Wiklander         return 0;
556411fa71b9SJerome Forissier     }
556511fa71b9SJerome Forissier 
556611fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate"));
556732b31808SJens Wiklander     return mbedtls_ssl_renegotiate(ssl);
556811fa71b9SJerome Forissier }
556911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
557011fa71b9SJerome Forissier 
557132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
557232b31808SJens Wiklander 
5573*cb034002SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C)
557432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
5575*cb034002SJerome Forissier static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl)
557632b31808SJens Wiklander {
557732b31808SJens Wiklander 
557832b31808SJens Wiklander     if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) ||
557932b31808SJens Wiklander         (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET)) {
558032b31808SJens Wiklander         return 0;
558132b31808SJens Wiklander     }
558232b31808SJens Wiklander 
5583*cb034002SJerome Forissier     return 1;
558432b31808SJens Wiklander }
5585*cb034002SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */
558632b31808SJens Wiklander 
558732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
558832b31808SJens Wiklander static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
558932b31808SJens Wiklander {
559032b31808SJens Wiklander 
559132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message"));
559232b31808SJens Wiklander 
5593*cb034002SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C)
559432b31808SJens Wiklander     if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5595*cb034002SJerome Forissier         if (ssl_tls13_is_new_session_ticket(ssl)) {
5596*cb034002SJerome Forissier #if defined(MBEDTLS_SSL_SESSION_TICKETS)
5597*cb034002SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
5598*cb034002SJerome Forissier             if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) ==
5599*cb034002SJerome Forissier                 MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) {
5600*cb034002SJerome Forissier                 ssl->keep_current_message = 1;
5601*cb034002SJerome Forissier 
5602*cb034002SJerome Forissier                 mbedtls_ssl_handshake_set_state(ssl,
5603*cb034002SJerome Forissier                                                 MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
5604*cb034002SJerome Forissier                 return MBEDTLS_ERR_SSL_WANT_READ;
5605*cb034002SJerome Forissier             } else {
5606*cb034002SJerome Forissier                 MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled."));
5607*cb034002SJerome Forissier                 return 0;
5608*cb034002SJerome Forissier             }
5609*cb034002SJerome Forissier #else
5610*cb034002SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported."));
5611*cb034002SJerome Forissier             return 0;
5612*cb034002SJerome Forissier #endif
561332b31808SJens Wiklander         }
561432b31808SJens Wiklander     }
5615*cb034002SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */
561632b31808SJens Wiklander 
561732b31808SJens Wiklander     /* Fail in all other cases. */
561832b31808SJens Wiklander     return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
561932b31808SJens Wiklander }
562032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
562132b31808SJens Wiklander 
562232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
562332b31808SJens Wiklander /* This function is called from mbedtls_ssl_read() when a handshake message is
562432b31808SJens Wiklander  * received after the initial handshake. In this context, handshake messages
562532b31808SJens Wiklander  * may only be sent for the purpose of initiating renegotiations.
562632b31808SJens Wiklander  *
562732b31808SJens Wiklander  * This function is introduced as a separate helper since the handling
562832b31808SJens Wiklander  * of post-handshake handshake messages changes significantly in TLS 1.3,
562932b31808SJens Wiklander  * and having a helper function allows to distinguish between TLS <= 1.2 and
563032b31808SJens Wiklander  * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read().
563132b31808SJens Wiklander  */
563232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
563332b31808SJens Wiklander static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
563432b31808SJens Wiklander {
563532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
563632b31808SJens Wiklander 
563732b31808SJens Wiklander     /*
563832b31808SJens Wiklander      * - For client-side, expect SERVER_HELLO_REQUEST.
563932b31808SJens Wiklander      * - For server-side, expect CLIENT_HELLO.
564032b31808SJens Wiklander      * - Fail (TLS) or silently drop record (DTLS) in other cases.
564132b31808SJens Wiklander      */
564232b31808SJens Wiklander 
564332b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C)
564432b31808SJens Wiklander     if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
564532b31808SJens Wiklander         (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
564632b31808SJens Wiklander          ssl->in_hslen  != mbedtls_ssl_hs_hdr_len(ssl))) {
564732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)"));
564832b31808SJens Wiklander 
564932b31808SJens Wiklander         /* With DTLS, drop the packet (probably from last handshake) */
565032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
565132b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
565232b31808SJens Wiklander             return 0;
565332b31808SJens Wiklander         }
565432b31808SJens Wiklander #endif
565532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
565632b31808SJens Wiklander     }
565732b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C */
565832b31808SJens Wiklander 
565932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SRV_C)
566032b31808SJens Wiklander     if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
566132b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
566232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)"));
566332b31808SJens Wiklander 
566432b31808SJens Wiklander         /* With DTLS, drop the packet (probably from last handshake) */
566532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
566632b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
566732b31808SJens Wiklander             return 0;
566832b31808SJens Wiklander         }
566932b31808SJens Wiklander #endif
567032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
567132b31808SJens Wiklander     }
567232b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C */
567332b31808SJens Wiklander 
567432b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
567532b31808SJens Wiklander     /* Determine whether renegotiation attempt should be accepted */
567632b31808SJens Wiklander     if (!(ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
567732b31808SJens Wiklander           (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
567832b31808SJens Wiklander            ssl->conf->allow_legacy_renegotiation ==
567932b31808SJens Wiklander            MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) {
568032b31808SJens Wiklander         /*
568132b31808SJens Wiklander          * Accept renegotiation request
568232b31808SJens Wiklander          */
568332b31808SJens Wiklander 
568432b31808SJens Wiklander         /* DTLS clients need to know renego is server-initiated */
568532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
568632b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
568732b31808SJens Wiklander             ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
568832b31808SJens Wiklander             ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
568932b31808SJens Wiklander         }
569032b31808SJens Wiklander #endif
569132b31808SJens Wiklander         ret = mbedtls_ssl_start_renegotiation(ssl);
569232b31808SJens Wiklander         if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
569332b31808SJens Wiklander             ret != 0) {
569432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation",
569532b31808SJens Wiklander                                   ret);
569632b31808SJens Wiklander             return ret;
569732b31808SJens Wiklander         }
569832b31808SJens Wiklander     } else
569932b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
570032b31808SJens Wiklander     {
570132b31808SJens Wiklander         /*
570232b31808SJens Wiklander          * Refuse renegotiation
570332b31808SJens Wiklander          */
570432b31808SJens Wiklander 
570532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert"));
570632b31808SJens Wiklander 
570732b31808SJens Wiklander         if ((ret = mbedtls_ssl_send_alert_message(ssl,
570832b31808SJens Wiklander                                                   MBEDTLS_SSL_ALERT_LEVEL_WARNING,
570932b31808SJens Wiklander                                                   MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) {
571032b31808SJens Wiklander             return ret;
571132b31808SJens Wiklander         }
571232b31808SJens Wiklander     }
571332b31808SJens Wiklander 
571432b31808SJens Wiklander     return 0;
571532b31808SJens Wiklander }
571632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
571732b31808SJens Wiklander 
571832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
571932b31808SJens Wiklander static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
572032b31808SJens Wiklander {
572132b31808SJens Wiklander     /* Check protocol version and dispatch accordingly. */
572232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
572332b31808SJens Wiklander     if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
572432b31808SJens Wiklander         return ssl_tls13_handle_hs_message_post_handshake(ssl);
572532b31808SJens Wiklander     }
572632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
572732b31808SJens Wiklander 
572832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
572932b31808SJens Wiklander     if (ssl->tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) {
573032b31808SJens Wiklander         return ssl_tls12_handle_hs_message_post_handshake(ssl);
573132b31808SJens Wiklander     }
573232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
573332b31808SJens Wiklander 
573432b31808SJens Wiklander     /* Should never happen */
573532b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
573632b31808SJens Wiklander }
573732b31808SJens Wiklander 
573811fa71b9SJerome Forissier /*
5739b0563631STom Van Eyck  * brief          Read at most 'len' application data bytes from the input
5740b0563631STom Van Eyck  *                buffer.
5741b0563631STom Van Eyck  *
5742b0563631STom Van Eyck  * param ssl      SSL context:
5743b0563631STom Van Eyck  *                - First byte of application data not read yet in the input
5744b0563631STom Van Eyck  *                  buffer located at address `in_offt`.
5745b0563631STom Van Eyck  *                - The number of bytes of data not read yet is `in_msglen`.
5746b0563631STom Van Eyck  * param buf      buffer that will hold the data
5747b0563631STom Van Eyck  * param len      maximum number of bytes to read
5748b0563631STom Van Eyck  *
5749b0563631STom Van Eyck  * note           The function updates the fields `in_offt` and `in_msglen`
5750b0563631STom Van Eyck  *                according to the number of bytes read.
5751b0563631STom Van Eyck  *
5752b0563631STom Van Eyck  * return         The number of bytes read.
5753b0563631STom Van Eyck  */
5754b0563631STom Van Eyck static int ssl_read_application_data(
5755b0563631STom Van Eyck     mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
5756b0563631STom Van Eyck {
5757b0563631STom Van Eyck     size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
5758b0563631STom Van Eyck 
5759b0563631STom Van Eyck     if (len != 0) {
5760b0563631STom Van Eyck         memcpy(buf, ssl->in_offt, n);
5761b0563631STom Van Eyck         ssl->in_msglen -= n;
5762b0563631STom Van Eyck     }
5763b0563631STom Van Eyck 
5764b0563631STom Van Eyck     /* Zeroising the plaintext buffer to erase unused application data
5765b0563631STom Van Eyck        from the memory. */
5766b0563631STom Van Eyck     mbedtls_platform_zeroize(ssl->in_offt, n);
5767b0563631STom Van Eyck 
5768b0563631STom Van Eyck     if (ssl->in_msglen == 0) {
5769b0563631STom Van Eyck         /* all bytes consumed */
5770b0563631STom Van Eyck         ssl->in_offt = NULL;
5771b0563631STom Van Eyck         ssl->keep_current_message = 0;
5772b0563631STom Van Eyck     } else {
5773b0563631STom Van Eyck         /* more data available */
5774b0563631STom Van Eyck         ssl->in_offt += n;
5775b0563631STom Van Eyck     }
5776b0563631STom Van Eyck 
5777b0563631STom Van Eyck     return (int) n;
5778b0563631STom Van Eyck }
5779b0563631STom Van Eyck 
5780b0563631STom Van Eyck /*
578111fa71b9SJerome Forissier  * Receive application data decrypted from the SSL layer
578211fa71b9SJerome Forissier  */
578311fa71b9SJerome Forissier int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
578411fa71b9SJerome Forissier {
578511fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
578611fa71b9SJerome Forissier 
578732b31808SJens Wiklander     if (ssl == NULL || ssl->conf == NULL) {
578832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
578932b31808SJens Wiklander     }
579011fa71b9SJerome Forissier 
579111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> read"));
579211fa71b9SJerome Forissier 
579311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
579432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
579532b31808SJens Wiklander         if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
579632b31808SJens Wiklander             return ret;
579732b31808SJens Wiklander         }
579811fa71b9SJerome Forissier 
579911fa71b9SJerome Forissier         if (ssl->handshake != NULL &&
580032b31808SJens Wiklander             ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
580132b31808SJens Wiklander             if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
580232b31808SJens Wiklander                 return ret;
580332b31808SJens Wiklander             }
580411fa71b9SJerome Forissier         }
580511fa71b9SJerome Forissier     }
580611fa71b9SJerome Forissier #endif
580711fa71b9SJerome Forissier 
580811fa71b9SJerome Forissier     /*
580911fa71b9SJerome Forissier      * Check if renegotiation is necessary and/or handshake is
581011fa71b9SJerome Forissier      * in process. If yes, perform/continue, and fall through
581111fa71b9SJerome Forissier      * if an unexpected packet is received while the client
581211fa71b9SJerome Forissier      * is waiting for the ServerHello.
581311fa71b9SJerome Forissier      *
581411fa71b9SJerome Forissier      * (There is no equivalent to the last condition on
581511fa71b9SJerome Forissier      *  the server-side as it is not treated as within
581611fa71b9SJerome Forissier      *  a handshake while waiting for the ClientHello
581711fa71b9SJerome Forissier      *  after a renegotiation request.)
581811fa71b9SJerome Forissier      */
581911fa71b9SJerome Forissier 
582011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
582111fa71b9SJerome Forissier     ret = ssl_check_ctr_renegotiate(ssl);
582211fa71b9SJerome Forissier     if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
582332b31808SJens Wiklander         ret != 0) {
582411fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
582532b31808SJens Wiklander         return ret;
582611fa71b9SJerome Forissier     }
582711fa71b9SJerome Forissier #endif
582811fa71b9SJerome Forissier 
582932b31808SJens Wiklander     if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
583011fa71b9SJerome Forissier         ret = mbedtls_ssl_handshake(ssl);
583111fa71b9SJerome Forissier         if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
583232b31808SJens Wiklander             ret != 0) {
583311fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
583432b31808SJens Wiklander             return ret;
583511fa71b9SJerome Forissier         }
583611fa71b9SJerome Forissier     }
583711fa71b9SJerome Forissier 
583811fa71b9SJerome Forissier     /* Loop as long as no application data record is available */
583932b31808SJens Wiklander     while (ssl->in_offt == NULL) {
584011fa71b9SJerome Forissier         /* Start timer if not already running */
584111fa71b9SJerome Forissier         if (ssl->f_get_timer != NULL &&
584232b31808SJens Wiklander             ssl->f_get_timer(ssl->p_timer) == -1) {
584311fa71b9SJerome Forissier             mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout);
584411fa71b9SJerome Forissier         }
584511fa71b9SJerome Forissier 
584632b31808SJens Wiklander         if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
584732b31808SJens Wiklander             if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
584832b31808SJens Wiklander                 return 0;
584932b31808SJens Wiklander             }
585011fa71b9SJerome Forissier 
585111fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
585232b31808SJens Wiklander             return ret;
585311fa71b9SJerome Forissier         }
585411fa71b9SJerome Forissier 
585511fa71b9SJerome Forissier         if (ssl->in_msglen  == 0 &&
585632b31808SJens Wiklander             ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
585711fa71b9SJerome Forissier             /*
585811fa71b9SJerome Forissier              * OpenSSL sends empty messages to randomize the IV
585911fa71b9SJerome Forissier              */
586032b31808SJens Wiklander             if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
586132b31808SJens Wiklander                 if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
586232b31808SJens Wiklander                     return 0;
586332b31808SJens Wiklander                 }
586411fa71b9SJerome Forissier 
586511fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
586632b31808SJens Wiklander                 return ret;
586711fa71b9SJerome Forissier             }
586811fa71b9SJerome Forissier         }
586911fa71b9SJerome Forissier 
587032b31808SJens Wiklander         if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
587132b31808SJens Wiklander             ret = ssl_handle_hs_message_post_handshake(ssl);
587232b31808SJens Wiklander             if (ret != 0) {
587332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake",
587411fa71b9SJerome Forissier                                       ret);
587532b31808SJens Wiklander                 return ret;
587611fa71b9SJerome Forissier             }
587711fa71b9SJerome Forissier 
587832b31808SJens Wiklander             /* At this point, we don't know whether the renegotiation triggered
587932b31808SJens Wiklander              * by the post-handshake message has been completed or not. The cases
588032b31808SJens Wiklander              * to consider are the following:
588111fa71b9SJerome Forissier              * 1) The renegotiation is complete. In this case, no new record
588211fa71b9SJerome Forissier              *    has been read yet.
588311fa71b9SJerome Forissier              * 2) The renegotiation is incomplete because the client received
588411fa71b9SJerome Forissier              *    an application data record while awaiting the ServerHello.
588511fa71b9SJerome Forissier              * 3) The renegotiation is incomplete because the client received
588611fa71b9SJerome Forissier              *    a non-handshake, non-application data message while awaiting
588711fa71b9SJerome Forissier              *    the ServerHello.
588832b31808SJens Wiklander              *
588932b31808SJens Wiklander              * In each of these cases, looping will be the proper action:
589011fa71b9SJerome Forissier              * - For 1), the next iteration will read a new record and check
589111fa71b9SJerome Forissier              *   if it's application data.
589211fa71b9SJerome Forissier              * - For 2), the loop condition isn't satisfied as application data
589311fa71b9SJerome Forissier              *   is present, hence continue is the same as break
589411fa71b9SJerome Forissier              * - For 3), the loop condition is satisfied and read_record
589511fa71b9SJerome Forissier              *   will re-deliver the message that was held back by the client
589611fa71b9SJerome Forissier              *   when expecting the ServerHello.
589711fa71b9SJerome Forissier              */
589832b31808SJens Wiklander 
589911fa71b9SJerome Forissier             continue;
590011fa71b9SJerome Forissier         }
590111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
590232b31808SJens Wiklander         else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
590332b31808SJens Wiklander             if (ssl->conf->renego_max_records >= 0) {
590432b31808SJens Wiklander                 if (++ssl->renego_records_seen > ssl->conf->renego_max_records) {
590511fa71b9SJerome Forissier                     MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, "
590611fa71b9SJerome Forissier                                               "but not honored by client"));
590732b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
590811fa71b9SJerome Forissier                 }
590911fa71b9SJerome Forissier             }
591011fa71b9SJerome Forissier         }
591111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
591211fa71b9SJerome Forissier 
591311fa71b9SJerome Forissier         /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
591432b31808SJens Wiklander         if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
591511fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert"));
591632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_WANT_READ;
591711fa71b9SJerome Forissier         }
591811fa71b9SJerome Forissier 
591932b31808SJens Wiklander         if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
592011fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message"));
592132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
592211fa71b9SJerome Forissier         }
592311fa71b9SJerome Forissier 
592411fa71b9SJerome Forissier         ssl->in_offt = ssl->in_msg;
592511fa71b9SJerome Forissier 
592611fa71b9SJerome Forissier         /* We're going to return something now, cancel timer,
592711fa71b9SJerome Forissier          * except if handshake (renegotiation) is in progress */
592832b31808SJens Wiklander         if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
592911fa71b9SJerome Forissier             mbedtls_ssl_set_timer(ssl, 0);
593032b31808SJens Wiklander         }
593111fa71b9SJerome Forissier 
593211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
593311fa71b9SJerome Forissier         /* If we requested renego but received AppData, resend HelloRequest.
593411fa71b9SJerome Forissier          * Do it now, after setting in_offt, to avoid taking this branch
593511fa71b9SJerome Forissier          * again if ssl_write_hello_request() returns WANT_WRITE */
593611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
593711fa71b9SJerome Forissier         if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
593832b31808SJens Wiklander             ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
593932b31808SJens Wiklander             if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
594011fa71b9SJerome Forissier                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
594111fa71b9SJerome Forissier                                       ret);
594232b31808SJens Wiklander                 return ret;
594311fa71b9SJerome Forissier             }
594411fa71b9SJerome Forissier         }
594511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
594611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
594711fa71b9SJerome Forissier     }
594811fa71b9SJerome Forissier 
5949b0563631STom Van Eyck     ret = ssl_read_application_data(ssl, buf, len);
595011fa71b9SJerome Forissier 
595111fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
595211fa71b9SJerome Forissier 
5953b0563631STom Van Eyck     return ret;
595411fa71b9SJerome Forissier }
595511fa71b9SJerome Forissier 
5956b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
5957b0563631STom Van Eyck int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
5958b0563631STom Van Eyck                                 unsigned char *buf, size_t len)
5959b0563631STom Van Eyck {
5960b0563631STom Van Eyck     if (ssl == NULL || (ssl->conf == NULL)) {
5961b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5962b0563631STom Van Eyck     }
5963b0563631STom Van Eyck 
5964b0563631STom Van Eyck     /*
5965b0563631STom Van Eyck      * The server may receive early data only while waiting for the End of
5966b0563631STom Van Eyck      * Early Data handshake message.
5967b0563631STom Van Eyck      */
5968b0563631STom Van Eyck     if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
5969b0563631STom Van Eyck         (ssl->in_offt == NULL)) {
5970b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
5971b0563631STom Van Eyck     }
5972b0563631STom Van Eyck 
5973b0563631STom Van Eyck     return ssl_read_application_data(ssl, buf, len);
5974b0563631STom Van Eyck }
5975b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
5976b0563631STom Van Eyck 
597711fa71b9SJerome Forissier /*
597811fa71b9SJerome Forissier  * Send application data to be encrypted by the SSL layer, taking care of max
597911fa71b9SJerome Forissier  * fragment length and buffer size.
598011fa71b9SJerome Forissier  *
598111fa71b9SJerome Forissier  * According to RFC 5246 Section 6.2.1:
598211fa71b9SJerome Forissier  *
598311fa71b9SJerome Forissier  *      Zero-length fragments of Application data MAY be sent as they are
598411fa71b9SJerome Forissier  *      potentially useful as a traffic analysis countermeasure.
598511fa71b9SJerome Forissier  *
598611fa71b9SJerome Forissier  * Therefore, it is possible that the input message length is 0 and the
598711fa71b9SJerome Forissier  * corresponding return code is 0 on success.
598811fa71b9SJerome Forissier  */
5989039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
599011fa71b9SJerome Forissier static int ssl_write_real(mbedtls_ssl_context *ssl,
599111fa71b9SJerome Forissier                           const unsigned char *buf, size_t len)
599211fa71b9SJerome Forissier {
599311fa71b9SJerome Forissier     int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
599411fa71b9SJerome Forissier     const size_t max_len = (size_t) ret;
599511fa71b9SJerome Forissier 
599632b31808SJens Wiklander     if (ret < 0) {
599711fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret);
599832b31808SJens Wiklander         return ret;
599911fa71b9SJerome Forissier     }
600011fa71b9SJerome Forissier 
600132b31808SJens Wiklander     if (len > max_len) {
600211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
600332b31808SJens Wiklander         if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
600411fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_MSG(1, ("fragment larger than the (negotiated) "
60057901324dSJerome Forissier                                       "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
60067901324dSJerome Forissier                                       " > %" MBEDTLS_PRINTF_SIZET,
600711fa71b9SJerome Forissier                                       len, max_len));
600832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
600932b31808SJens Wiklander         } else
601011fa71b9SJerome Forissier #endif
601111fa71b9SJerome Forissier         len = max_len;
601211fa71b9SJerome Forissier     }
601311fa71b9SJerome Forissier 
601432b31808SJens Wiklander     if (ssl->out_left != 0) {
601511fa71b9SJerome Forissier         /*
601611fa71b9SJerome Forissier          * The user has previously tried to send the data and
601711fa71b9SJerome Forissier          * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
601811fa71b9SJerome Forissier          * written. In this case, we expect the high-level write function
601911fa71b9SJerome Forissier          * (e.g. mbedtls_ssl_write()) to be called with the same parameters
602011fa71b9SJerome Forissier          */
602132b31808SJens Wiklander         if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
602211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
602332b31808SJens Wiklander             return ret;
602411fa71b9SJerome Forissier         }
602532b31808SJens Wiklander     } else {
602611fa71b9SJerome Forissier         /*
602711fa71b9SJerome Forissier          * The user is trying to send a message the first time, so we need to
602811fa71b9SJerome Forissier          * copy the data into the internal buffers and setup the data structure
602911fa71b9SJerome Forissier          * to keep track of partial writes
603011fa71b9SJerome Forissier          */
603111fa71b9SJerome Forissier         ssl->out_msglen  = len;
603211fa71b9SJerome Forissier         ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
603332b31808SJens Wiklander         if (len > 0) {
603411fa71b9SJerome Forissier             memcpy(ssl->out_msg, buf, len);
603532b31808SJens Wiklander         }
603611fa71b9SJerome Forissier 
603732b31808SJens Wiklander         if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
603811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
603932b31808SJens Wiklander             return ret;
604011fa71b9SJerome Forissier         }
604111fa71b9SJerome Forissier     }
604211fa71b9SJerome Forissier 
604332b31808SJens Wiklander     return (int) len;
604411fa71b9SJerome Forissier }
604511fa71b9SJerome Forissier 
604611fa71b9SJerome Forissier /*
604711fa71b9SJerome Forissier  * Write application data (public-facing wrapper)
604811fa71b9SJerome Forissier  */
604911fa71b9SJerome Forissier int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
605011fa71b9SJerome Forissier {
605111fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
605211fa71b9SJerome Forissier 
605311fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write"));
605411fa71b9SJerome Forissier 
605532b31808SJens Wiklander     if (ssl == NULL || ssl->conf == NULL) {
605632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
605732b31808SJens Wiklander     }
605811fa71b9SJerome Forissier 
605911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
606032b31808SJens Wiklander     if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) {
606111fa71b9SJerome Forissier         MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
606232b31808SJens Wiklander         return ret;
606311fa71b9SJerome Forissier     }
606411fa71b9SJerome Forissier #endif
606511fa71b9SJerome Forissier 
606632b31808SJens Wiklander     if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
606732b31808SJens Wiklander         if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
606811fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
606932b31808SJens Wiklander             return ret;
607011fa71b9SJerome Forissier         }
607111fa71b9SJerome Forissier     }
607211fa71b9SJerome Forissier 
607311fa71b9SJerome Forissier     ret = ssl_write_real(ssl, buf, len);
607411fa71b9SJerome Forissier 
607511fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write"));
607611fa71b9SJerome Forissier 
607732b31808SJens Wiklander     return ret;
607811fa71b9SJerome Forissier }
607911fa71b9SJerome Forissier 
6080b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
6081b0563631STom Van Eyck int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
6082b0563631STom Van Eyck                                  const unsigned char *buf, size_t len)
6083b0563631STom Van Eyck {
6084b0563631STom Van Eyck     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6085b0563631STom Van Eyck     const struct mbedtls_ssl_config *conf;
6086b0563631STom Van Eyck     uint32_t remaining;
6087b0563631STom Van Eyck 
6088b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
6089b0563631STom Van Eyck 
6090b0563631STom Van Eyck     if (ssl == NULL || (conf = ssl->conf) == NULL) {
6091b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6092b0563631STom Van Eyck     }
6093b0563631STom Van Eyck 
6094b0563631STom Van Eyck     if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
6095b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6096b0563631STom Van Eyck     }
6097b0563631STom Van Eyck 
6098b0563631STom Van Eyck     if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
6099b0563631STom Van Eyck         (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
6100b0563631STom Van Eyck         (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
6101b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6102b0563631STom Van Eyck     }
6103b0563631STom Van Eyck 
6104b0563631STom Van Eyck     if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
6105b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6106b0563631STom Van Eyck     }
6107b0563631STom Van Eyck 
6108b0563631STom Van Eyck     /*
6109b0563631STom Van Eyck      * If we are at the beginning of the handshake, the early data state being
6110b0563631STom Van Eyck      * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or
6111b0563631STom Van Eyck      * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just
6112b0563631STom Van Eyck      * enough to be able to send early data if possible. That way, we can
6113b0563631STom Van Eyck      * guarantee that when starting the handshake with this function we will
6114b0563631STom Van Eyck      * send at least one record of early data. Note that when the state is
6115b0563631STom Van Eyck      * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet
6116b0563631STom Van Eyck      * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data
6117b0563631STom Van Eyck      * as the early data outbound transform has not been set as we may have to
6118b0563631STom Van Eyck      * first send a dummy CCS in clear.
6119b0563631STom Van Eyck      */
6120b0563631STom Van Eyck     if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6121b0563631STom Van Eyck         (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6122b0563631STom Van Eyck         while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6123b0563631STom Van Eyck                (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6124b0563631STom Van Eyck             ret = mbedtls_ssl_handshake_step(ssl);
6125b0563631STom Van Eyck             if (ret != 0) {
6126b0563631STom Van Eyck                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
6127b0563631STom Van Eyck                 return ret;
6128b0563631STom Van Eyck             }
6129b0563631STom Van Eyck 
6130b0563631STom Van Eyck             ret = mbedtls_ssl_flush_output(ssl);
6131b0563631STom Van Eyck             if (ret != 0) {
6132b0563631STom Van Eyck                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
6133b0563631STom Van Eyck                 return ret;
6134b0563631STom Van Eyck             }
6135b0563631STom Van Eyck         }
6136b0563631STom Van Eyck         remaining = ssl->session_negotiate->max_early_data_size;
6137b0563631STom Van Eyck     } else {
6138b0563631STom Van Eyck         /*
6139b0563631STom Van Eyck          * If we are past the point where we can send early data or we have
6140b0563631STom Van Eyck          * already reached the maximum early data size, return immediatly.
6141b0563631STom Van Eyck          * Otherwise, progress the handshake as much as possible to not delay
6142b0563631STom Van Eyck          * it too much. If we reach a point where we can still send early data,
6143b0563631STom Van Eyck          * then we will send some.
6144b0563631STom Van Eyck          */
6145b0563631STom Van Eyck         if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6146b0563631STom Van Eyck             (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
6147b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6148b0563631STom Van Eyck         }
6149b0563631STom Van Eyck 
6150b0563631STom Van Eyck         remaining = ssl->session_negotiate->max_early_data_size -
6151b0563631STom Van Eyck                     ssl->total_early_data_size;
6152b0563631STom Van Eyck 
6153b0563631STom Van Eyck         if (remaining == 0) {
6154b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6155b0563631STom Van Eyck         }
6156b0563631STom Van Eyck 
6157b0563631STom Van Eyck         ret = mbedtls_ssl_handshake(ssl);
6158b0563631STom Van Eyck         if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
6159b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6160b0563631STom Van Eyck             return ret;
6161b0563631STom Van Eyck         }
6162b0563631STom Van Eyck     }
6163b0563631STom Van Eyck 
6164b0563631STom Van Eyck     if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6165b0563631STom Van Eyck          (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
6166b0563631STom Van Eyck         || (remaining == 0)) {
6167b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6168b0563631STom Van Eyck     }
6169b0563631STom Van Eyck 
6170b0563631STom Van Eyck     if (len > remaining) {
6171b0563631STom Van Eyck         len = remaining;
6172b0563631STom Van Eyck     }
6173b0563631STom Van Eyck 
6174b0563631STom Van Eyck     ret = ssl_write_real(ssl, buf, len);
6175b0563631STom Van Eyck     if (ret >= 0) {
6176b0563631STom Van Eyck         ssl->total_early_data_size += ret;
6177b0563631STom Van Eyck     }
6178b0563631STom Van Eyck 
6179b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
6180b0563631STom Van Eyck 
6181b0563631STom Van Eyck     return ret;
6182b0563631STom Van Eyck }
6183b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
6184b0563631STom Van Eyck 
618511fa71b9SJerome Forissier /*
618611fa71b9SJerome Forissier  * Notify the peer that the connection is being closed
618711fa71b9SJerome Forissier  */
618811fa71b9SJerome Forissier int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
618911fa71b9SJerome Forissier {
619011fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
619111fa71b9SJerome Forissier 
619232b31808SJens Wiklander     if (ssl == NULL || ssl->conf == NULL) {
619332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
619432b31808SJens Wiklander     }
619511fa71b9SJerome Forissier 
619611fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify"));
619711fa71b9SJerome Forissier 
619832b31808SJens Wiklander     if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
619911fa71b9SJerome Forissier         if ((ret = mbedtls_ssl_send_alert_message(ssl,
620011fa71b9SJerome Forissier                                                   MBEDTLS_SSL_ALERT_LEVEL_WARNING,
620132b31808SJens Wiklander                                                   MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) {
620211fa71b9SJerome Forissier             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret);
620332b31808SJens Wiklander             return ret;
620411fa71b9SJerome Forissier         }
620511fa71b9SJerome Forissier     }
620611fa71b9SJerome Forissier 
620711fa71b9SJerome Forissier     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify"));
620811fa71b9SJerome Forissier 
620932b31808SJens Wiklander     return 0;
621011fa71b9SJerome Forissier }
621111fa71b9SJerome Forissier 
621211fa71b9SJerome Forissier void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform)
621311fa71b9SJerome Forissier {
621432b31808SJens Wiklander     if (transform == NULL) {
621511fa71b9SJerome Forissier         return;
621632b31808SJens Wiklander     }
621711fa71b9SJerome Forissier 
621832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
621932b31808SJens Wiklander     psa_destroy_key(transform->psa_key_enc);
622032b31808SJens Wiklander     psa_destroy_key(transform->psa_key_dec);
622132b31808SJens Wiklander #else
622211fa71b9SJerome Forissier     mbedtls_cipher_free(&transform->cipher_ctx_enc);
622311fa71b9SJerome Forissier     mbedtls_cipher_free(&transform->cipher_ctx_dec);
622432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
622511fa71b9SJerome Forissier 
622632b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
622732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
622832b31808SJens Wiklander     psa_destroy_key(transform->psa_mac_enc);
622932b31808SJens Wiklander     psa_destroy_key(transform->psa_mac_dec);
623032b31808SJens Wiklander #else
623111fa71b9SJerome Forissier     mbedtls_md_free(&transform->md_ctx_enc);
623211fa71b9SJerome Forissier     mbedtls_md_free(&transform->md_ctx_dec);
623332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
623411fa71b9SJerome Forissier #endif
623511fa71b9SJerome Forissier 
623611fa71b9SJerome Forissier     mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform));
623711fa71b9SJerome Forissier }
623811fa71b9SJerome Forissier 
623932b31808SJens Wiklander void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl,
624032b31808SJens Wiklander                                        mbedtls_ssl_transform *transform)
624132b31808SJens Wiklander {
624232b31808SJens Wiklander     ssl->transform_in = transform;
624332b31808SJens Wiklander     memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
624432b31808SJens Wiklander }
624532b31808SJens Wiklander 
624632b31808SJens Wiklander void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl,
624732b31808SJens Wiklander                                         mbedtls_ssl_transform *transform)
624832b31808SJens Wiklander {
624932b31808SJens Wiklander     ssl->transform_out = transform;
625032b31808SJens Wiklander     memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr));
625132b31808SJens Wiklander }
625232b31808SJens Wiklander 
625311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
625411fa71b9SJerome Forissier 
625511fa71b9SJerome Forissier void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl)
625611fa71b9SJerome Forissier {
625711fa71b9SJerome Forissier     unsigned offset;
625811fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
625911fa71b9SJerome Forissier 
626032b31808SJens Wiklander     if (hs == NULL) {
626111fa71b9SJerome Forissier         return;
626232b31808SJens Wiklander     }
626311fa71b9SJerome Forissier 
626411fa71b9SJerome Forissier     ssl_free_buffered_record(ssl);
626511fa71b9SJerome Forissier 
626632b31808SJens Wiklander     for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
626711fa71b9SJerome Forissier         ssl_buffering_free_slot(ssl, offset);
626811fa71b9SJerome Forissier     }
626932b31808SJens Wiklander }
627011fa71b9SJerome Forissier 
627111fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
627211fa71b9SJerome Forissier                                     uint8_t slot)
627311fa71b9SJerome Forissier {
627411fa71b9SJerome Forissier     mbedtls_ssl_handshake_params * const hs = ssl->handshake;
627511fa71b9SJerome Forissier     mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
627611fa71b9SJerome Forissier 
627732b31808SJens Wiklander     if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
627811fa71b9SJerome Forissier         return;
627932b31808SJens Wiklander     }
628011fa71b9SJerome Forissier 
628132b31808SJens Wiklander     if (hs_buf->is_valid == 1) {
628211fa71b9SJerome Forissier         hs->buffering.total_bytes_buffered -= hs_buf->data_len;
6283b0563631STom Van Eyck         mbedtls_zeroize_and_free(hs_buf->data, hs_buf->data_len);
628411fa71b9SJerome Forissier         memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
628511fa71b9SJerome Forissier     }
628611fa71b9SJerome Forissier }
628711fa71b9SJerome Forissier 
628811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
628911fa71b9SJerome Forissier 
629011fa71b9SJerome Forissier /*
629111fa71b9SJerome Forissier  * Convert version numbers to/from wire format
629211fa71b9SJerome Forissier  * and, for DTLS, to/from TLS equivalent.
629311fa71b9SJerome Forissier  *
629411fa71b9SJerome Forissier  * For TLS this is the identity.
629532b31808SJens Wiklander  * For DTLS, map as follows, then use 1's complement (v -> ~v):
629611fa71b9SJerome Forissier  * 1.x <-> 3.x+1    for x != 0 (DTLS 1.2 based on TLS 1.2)
629732b31808SJens Wiklander  *                  DTLS 1.0 is stored as TLS 1.1 internally
629811fa71b9SJerome Forissier  */
629932b31808SJens Wiklander void mbedtls_ssl_write_version(unsigned char version[2], int transport,
630032b31808SJens Wiklander                                mbedtls_ssl_protocol_version tls_version)
630111fa71b9SJerome Forissier {
6302b0563631STom Van Eyck     uint16_t tls_version_formatted;
630311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
630432b31808SJens Wiklander     if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6305b0563631STom Van Eyck         tls_version_formatted =
630632b31808SJens Wiklander             ~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201));
6307b0563631STom Van Eyck     } else
630811fa71b9SJerome Forissier #else
630911fa71b9SJerome Forissier     ((void) transport);
631011fa71b9SJerome Forissier #endif
6311b0563631STom Van Eyck     {
6312b0563631STom Van Eyck         tls_version_formatted = (uint16_t) tls_version;
6313b0563631STom Van Eyck     }
6314b0563631STom Van Eyck     MBEDTLS_PUT_UINT16_BE(tls_version_formatted, version, 0);
631511fa71b9SJerome Forissier }
631611fa71b9SJerome Forissier 
631732b31808SJens Wiklander uint16_t mbedtls_ssl_read_version(const unsigned char version[2],
631832b31808SJens Wiklander                                   int transport)
631911fa71b9SJerome Forissier {
632032b31808SJens Wiklander     uint16_t tls_version = MBEDTLS_GET_UINT16_BE(version, 0);
632111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
632232b31808SJens Wiklander     if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
632332b31808SJens Wiklander         tls_version =
632432b31808SJens Wiklander             ~(tls_version - (tls_version == 0xfeff ? 0x0202 : 0x0201));
632511fa71b9SJerome Forissier     }
632611fa71b9SJerome Forissier #else
632711fa71b9SJerome Forissier     ((void) transport);
632811fa71b9SJerome Forissier #endif
632932b31808SJens Wiklander     return tls_version;
633011fa71b9SJerome Forissier }
633132b31808SJens Wiklander 
633232b31808SJens Wiklander /*
633332b31808SJens Wiklander  * Send pending fatal alert.
633432b31808SJens Wiklander  * 0,   No alert message.
633532b31808SJens Wiklander  * !0,  if mbedtls_ssl_send_alert_message() returned in error, the error code it
633632b31808SJens Wiklander  *      returned, ssl->alert_reason otherwise.
633732b31808SJens Wiklander  */
633832b31808SJens Wiklander int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl)
633932b31808SJens Wiklander {
634032b31808SJens Wiklander     int ret;
634132b31808SJens Wiklander 
634232b31808SJens Wiklander     /* No pending alert, return success*/
634332b31808SJens Wiklander     if (ssl->send_alert == 0) {
634432b31808SJens Wiklander         return 0;
634532b31808SJens Wiklander     }
634632b31808SJens Wiklander 
634732b31808SJens Wiklander     ret = mbedtls_ssl_send_alert_message(ssl,
634832b31808SJens Wiklander                                          MBEDTLS_SSL_ALERT_LEVEL_FATAL,
634932b31808SJens Wiklander                                          ssl->alert_type);
635032b31808SJens Wiklander 
635132b31808SJens Wiklander     /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE,
635232b31808SJens Wiklander      * do not clear the alert to be able to send it later.
635332b31808SJens Wiklander      */
635432b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
635532b31808SJens Wiklander         ssl->send_alert = 0;
635632b31808SJens Wiklander     }
635732b31808SJens Wiklander 
635832b31808SJens Wiklander     if (ret != 0) {
635932b31808SJens Wiklander         return ret;
636032b31808SJens Wiklander     }
636132b31808SJens Wiklander 
636232b31808SJens Wiklander     return ssl->alert_reason;
636332b31808SJens Wiklander }
636432b31808SJens Wiklander 
636532b31808SJens Wiklander /*
636632b31808SJens Wiklander  * Set pending fatal alert flag.
636732b31808SJens Wiklander  */
636832b31808SJens Wiklander void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl,
636932b31808SJens Wiklander                                   unsigned char alert_type,
637032b31808SJens Wiklander                                   int alert_reason)
637132b31808SJens Wiklander {
637232b31808SJens Wiklander     ssl->send_alert = 1;
637332b31808SJens Wiklander     ssl->alert_type = alert_type;
637432b31808SJens Wiklander     ssl->alert_reason = alert_reason;
637511fa71b9SJerome Forissier }
637611fa71b9SJerome Forissier 
637711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */
6378