1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  Generic SSL/TLS messaging layer functions
3a8e1175bSopenharmony_ci *  (record layer + retransmission state machine)
4a8e1175bSopenharmony_ci *
5a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
6a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7a8e1175bSopenharmony_ci */
8a8e1175bSopenharmony_ci/*
9a8e1175bSopenharmony_ci *  http://www.ietf.org/rfc/rfc2246.txt
10a8e1175bSopenharmony_ci *  http://www.ietf.org/rfc/rfc4346.txt
11a8e1175bSopenharmony_ci */
12a8e1175bSopenharmony_ci
13a8e1175bSopenharmony_ci#include "common.h"
14a8e1175bSopenharmony_ci
15a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS_C)
16a8e1175bSopenharmony_ci
17a8e1175bSopenharmony_ci#include "mbedtls/platform.h"
18a8e1175bSopenharmony_ci
19a8e1175bSopenharmony_ci#include "mbedtls/ssl.h"
20a8e1175bSopenharmony_ci#include "ssl_misc.h"
21a8e1175bSopenharmony_ci#include "debug_internal.h"
22a8e1175bSopenharmony_ci#include "mbedtls/error.h"
23a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h"
24a8e1175bSopenharmony_ci#include "mbedtls/version.h"
25a8e1175bSopenharmony_ci#include "constant_time_internal.h"
26a8e1175bSopenharmony_ci#include "mbedtls/constant_time.h"
27a8e1175bSopenharmony_ci
28a8e1175bSopenharmony_ci#include <string.h>
29a8e1175bSopenharmony_ci
30a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
31a8e1175bSopenharmony_ci#include "psa_util_internal.h"
32a8e1175bSopenharmony_ci#include "psa/crypto.h"
33a8e1175bSopenharmony_ci#endif
34a8e1175bSopenharmony_ci
35a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRT_PARSE_C)
36a8e1175bSopenharmony_ci#include "mbedtls/oid.h"
37a8e1175bSopenharmony_ci#endif
38a8e1175bSopenharmony_ci
39a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
40a8e1175bSopenharmony_ci/* Define a local translating function to save code size by not using too many
41a8e1175bSopenharmony_ci * arguments in each translating place. */
42a8e1175bSopenharmony_cistatic int local_err_translation(psa_status_t status)
43a8e1175bSopenharmony_ci{
44a8e1175bSopenharmony_ci    return psa_status_to_mbedtls(status, psa_to_ssl_errors,
45a8e1175bSopenharmony_ci                                 ARRAY_LENGTH(psa_to_ssl_errors),
46a8e1175bSopenharmony_ci                                 psa_generic_status_to_mbedtls);
47a8e1175bSopenharmony_ci}
48a8e1175bSopenharmony_ci#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
49a8e1175bSopenharmony_ci#endif
50a8e1175bSopenharmony_ci
51a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
52a8e1175bSopenharmony_ci
53a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
54a8e1175bSopenharmony_ci
55a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_SHA_384)
56a8e1175bSopenharmony_ci#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384)
57a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_SHA_256)
58a8e1175bSopenharmony_ci#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)
59a8e1175bSopenharmony_ci#else /* See check_config.h */
60a8e1175bSopenharmony_ci#define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1)
61a8e1175bSopenharmony_ci#endif
62a8e1175bSopenharmony_ci
63a8e1175bSopenharmony_ciMBEDTLS_STATIC_TESTABLE
64a8e1175bSopenharmony_ciint mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
65a8e1175bSopenharmony_ci                    psa_algorithm_t mac_alg,
66a8e1175bSopenharmony_ci                    const unsigned char *add_data,
67a8e1175bSopenharmony_ci                    size_t add_data_len,
68a8e1175bSopenharmony_ci                    const unsigned char *data,
69a8e1175bSopenharmony_ci                    size_t data_len_secret,
70a8e1175bSopenharmony_ci                    size_t min_data_len,
71a8e1175bSopenharmony_ci                    size_t max_data_len,
72a8e1175bSopenharmony_ci                    unsigned char *output)
73a8e1175bSopenharmony_ci{
74a8e1175bSopenharmony_ci    /*
75a8e1175bSopenharmony_ci     * This function breaks the HMAC abstraction and uses psa_hash_clone()
76a8e1175bSopenharmony_ci     * extension in order to get constant-flow behaviour.
77a8e1175bSopenharmony_ci     *
78a8e1175bSopenharmony_ci     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
79a8e1175bSopenharmony_ci     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
80a8e1175bSopenharmony_ci     * patterns (see RFC 2104, sec. 2).
81a8e1175bSopenharmony_ci     *
82a8e1175bSopenharmony_ci     * We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
83a8e1175bSopenharmony_ci     * hashing up to minlen, then cloning the context, and for each byte up
84a8e1175bSopenharmony_ci     * to maxlen finishing up the hash computation, keeping only the
85a8e1175bSopenharmony_ci     * correct result.
86a8e1175bSopenharmony_ci     *
87a8e1175bSopenharmony_ci     * Then we only need to compute HASH(okey + inner_hash) and we're done.
88a8e1175bSopenharmony_ci     */
89a8e1175bSopenharmony_ci    psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
90a8e1175bSopenharmony_ci    const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
91a8e1175bSopenharmony_ci    unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
92a8e1175bSopenharmony_ci    const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
93a8e1175bSopenharmony_ci    psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
94a8e1175bSopenharmony_ci    size_t hash_length;
95a8e1175bSopenharmony_ci
96a8e1175bSopenharmony_ci    unsigned char aux_out[PSA_HASH_MAX_SIZE];
97a8e1175bSopenharmony_ci    psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
98a8e1175bSopenharmony_ci    size_t offset;
99a8e1175bSopenharmony_ci    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
100a8e1175bSopenharmony_ci
101a8e1175bSopenharmony_ci    size_t mac_key_length;
102a8e1175bSopenharmony_ci    size_t i;
103a8e1175bSopenharmony_ci
104a8e1175bSopenharmony_ci#define PSA_CHK(func_call)        \
105a8e1175bSopenharmony_ci    do {                            \
106a8e1175bSopenharmony_ci        status = (func_call);       \
107a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) \
108a8e1175bSopenharmony_ci        goto cleanup;           \
109a8e1175bSopenharmony_ci    } while (0)
110a8e1175bSopenharmony_ci
111a8e1175bSopenharmony_ci    /* Export MAC key
112a8e1175bSopenharmony_ci     * We assume key length is always exactly the output size
113a8e1175bSopenharmony_ci     * which is never more than the block size, thus we use block_size
114a8e1175bSopenharmony_ci     * as the key buffer size.
115a8e1175bSopenharmony_ci     */
116a8e1175bSopenharmony_ci    PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
117a8e1175bSopenharmony_ci
118a8e1175bSopenharmony_ci    /* Calculate ikey */
119a8e1175bSopenharmony_ci    for (i = 0; i < mac_key_length; i++) {
120a8e1175bSopenharmony_ci        key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
121a8e1175bSopenharmony_ci    }
122a8e1175bSopenharmony_ci    for (; i < block_size; ++i) {
123a8e1175bSopenharmony_ci        key_buf[i] = 0x36;
124a8e1175bSopenharmony_ci    }
125a8e1175bSopenharmony_ci
126a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_setup(&operation, hash_alg));
127a8e1175bSopenharmony_ci
128a8e1175bSopenharmony_ci    /* Now compute inner_hash = HASH(ikey + msg) */
129a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
130a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
131a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_update(&operation, data, min_data_len));
132a8e1175bSopenharmony_ci
133a8e1175bSopenharmony_ci    /* Fill the hash buffer in advance with something that is
134a8e1175bSopenharmony_ci     * not a valid hash (barring an attack on the hash and
135a8e1175bSopenharmony_ci     * deliberately-crafted input), in case the caller doesn't
136a8e1175bSopenharmony_ci     * check the return status properly. */
137a8e1175bSopenharmony_ci    memset(output, '!', hash_size);
138a8e1175bSopenharmony_ci
139a8e1175bSopenharmony_ci    /* For each possible length, compute the hash up to that point */
140a8e1175bSopenharmony_ci    for (offset = min_data_len; offset <= max_data_len; offset++) {
141a8e1175bSopenharmony_ci        PSA_CHK(psa_hash_clone(&operation, &aux_operation));
142a8e1175bSopenharmony_ci        PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
143a8e1175bSopenharmony_ci                                PSA_HASH_MAX_SIZE, &hash_length));
144a8e1175bSopenharmony_ci        /* Keep only the correct inner_hash in the output buffer */
145a8e1175bSopenharmony_ci        mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
146a8e1175bSopenharmony_ci                             output, aux_out, NULL, hash_size);
147a8e1175bSopenharmony_ci
148a8e1175bSopenharmony_ci        if (offset < max_data_len) {
149a8e1175bSopenharmony_ci            PSA_CHK(psa_hash_update(&operation, data + offset, 1));
150a8e1175bSopenharmony_ci        }
151a8e1175bSopenharmony_ci    }
152a8e1175bSopenharmony_ci
153a8e1175bSopenharmony_ci    /* Abort current operation to prepare for final operation */
154a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_abort(&operation));
155a8e1175bSopenharmony_ci
156a8e1175bSopenharmony_ci    /* Calculate okey */
157a8e1175bSopenharmony_ci    for (i = 0; i < mac_key_length; i++) {
158a8e1175bSopenharmony_ci        key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
159a8e1175bSopenharmony_ci    }
160a8e1175bSopenharmony_ci    for (; i < block_size; ++i) {
161a8e1175bSopenharmony_ci        key_buf[i] = 0x5C;
162a8e1175bSopenharmony_ci    }
163a8e1175bSopenharmony_ci
164a8e1175bSopenharmony_ci    /* Now compute HASH(okey + inner_hash) */
165a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_setup(&operation, hash_alg));
166a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
167a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_update(&operation, output, hash_size));
168a8e1175bSopenharmony_ci    PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
169a8e1175bSopenharmony_ci
170a8e1175bSopenharmony_ci#undef PSA_CHK
171a8e1175bSopenharmony_ci
172a8e1175bSopenharmony_cicleanup:
173a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
174a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
175a8e1175bSopenharmony_ci
176a8e1175bSopenharmony_ci    psa_hash_abort(&operation);
177a8e1175bSopenharmony_ci    psa_hash_abort(&aux_operation);
178a8e1175bSopenharmony_ci    return PSA_TO_MBEDTLS_ERR(status);
179a8e1175bSopenharmony_ci}
180a8e1175bSopenharmony_ci
181a8e1175bSopenharmony_ci#undef MAX_HASH_BLOCK_LENGTH
182a8e1175bSopenharmony_ci
183a8e1175bSopenharmony_ci#else
184a8e1175bSopenharmony_ciMBEDTLS_STATIC_TESTABLE
185a8e1175bSopenharmony_ciint mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
186a8e1175bSopenharmony_ci                    const unsigned char *add_data,
187a8e1175bSopenharmony_ci                    size_t add_data_len,
188a8e1175bSopenharmony_ci                    const unsigned char *data,
189a8e1175bSopenharmony_ci                    size_t data_len_secret,
190a8e1175bSopenharmony_ci                    size_t min_data_len,
191a8e1175bSopenharmony_ci                    size_t max_data_len,
192a8e1175bSopenharmony_ci                    unsigned char *output)
193a8e1175bSopenharmony_ci{
194a8e1175bSopenharmony_ci    /*
195a8e1175bSopenharmony_ci     * This function breaks the HMAC abstraction and uses the md_clone()
196a8e1175bSopenharmony_ci     * extension to the MD API in order to get constant-flow behaviour.
197a8e1175bSopenharmony_ci     *
198a8e1175bSopenharmony_ci     * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
199a8e1175bSopenharmony_ci     * concatenation, and okey/ikey are the XOR of the key with some fixed bit
200a8e1175bSopenharmony_ci     * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
201a8e1175bSopenharmony_ci     *
202a8e1175bSopenharmony_ci     * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
203a8e1175bSopenharmony_ci     * minlen, then cloning the context, and for each byte up to maxlen
204a8e1175bSopenharmony_ci     * finishing up the hash computation, keeping only the correct result.
205a8e1175bSopenharmony_ci     *
206a8e1175bSopenharmony_ci     * Then we only need to compute HASH(okey + inner_hash) and we're done.
207a8e1175bSopenharmony_ci     */
208a8e1175bSopenharmony_ci    const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
209a8e1175bSopenharmony_ci    /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
210a8e1175bSopenharmony_ci     * all of which have the same block size except SHA-384. */
211a8e1175bSopenharmony_ci    const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
212a8e1175bSopenharmony_ci    const unsigned char * const ikey = ctx->hmac_ctx;
213a8e1175bSopenharmony_ci    const unsigned char * const okey = ikey + block_size;
214a8e1175bSopenharmony_ci    const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
215a8e1175bSopenharmony_ci
216a8e1175bSopenharmony_ci    unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
217a8e1175bSopenharmony_ci    mbedtls_md_context_t aux;
218a8e1175bSopenharmony_ci    size_t offset;
219a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
220a8e1175bSopenharmony_ci
221a8e1175bSopenharmony_ci    mbedtls_md_init(&aux);
222a8e1175bSopenharmony_ci
223a8e1175bSopenharmony_ci#define MD_CHK(func_call) \
224a8e1175bSopenharmony_ci    do {                    \
225a8e1175bSopenharmony_ci        ret = (func_call);  \
226a8e1175bSopenharmony_ci        if (ret != 0)      \
227a8e1175bSopenharmony_ci        goto cleanup;   \
228a8e1175bSopenharmony_ci    } while (0)
229a8e1175bSopenharmony_ci
230a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
231a8e1175bSopenharmony_ci
232a8e1175bSopenharmony_ci    /* After hmac_start() of hmac_reset(), ikey has already been hashed,
233a8e1175bSopenharmony_ci     * so we can start directly with the message */
234a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
235a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
236a8e1175bSopenharmony_ci
237a8e1175bSopenharmony_ci    /* Fill the hash buffer in advance with something that is
238a8e1175bSopenharmony_ci     * not a valid hash (barring an attack on the hash and
239a8e1175bSopenharmony_ci     * deliberately-crafted input), in case the caller doesn't
240a8e1175bSopenharmony_ci     * check the return status properly. */
241a8e1175bSopenharmony_ci    memset(output, '!', hash_size);
242a8e1175bSopenharmony_ci
243a8e1175bSopenharmony_ci    /* For each possible length, compute the hash up to that point */
244a8e1175bSopenharmony_ci    for (offset = min_data_len; offset <= max_data_len; offset++) {
245a8e1175bSopenharmony_ci        MD_CHK(mbedtls_md_clone(&aux, ctx));
246a8e1175bSopenharmony_ci        MD_CHK(mbedtls_md_finish(&aux, aux_out));
247a8e1175bSopenharmony_ci        /* Keep only the correct inner_hash in the output buffer */
248a8e1175bSopenharmony_ci        mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
249a8e1175bSopenharmony_ci                             output, aux_out, NULL, hash_size);
250a8e1175bSopenharmony_ci
251a8e1175bSopenharmony_ci        if (offset < max_data_len) {
252a8e1175bSopenharmony_ci            MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
253a8e1175bSopenharmony_ci        }
254a8e1175bSopenharmony_ci    }
255a8e1175bSopenharmony_ci
256a8e1175bSopenharmony_ci    /* The context needs to finish() before it starts() again */
257a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_finish(ctx, aux_out));
258a8e1175bSopenharmony_ci
259a8e1175bSopenharmony_ci    /* Now compute HASH(okey + inner_hash) */
260a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_starts(ctx));
261a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_update(ctx, okey, block_size));
262a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_update(ctx, output, hash_size));
263a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_finish(ctx, output));
264a8e1175bSopenharmony_ci
265a8e1175bSopenharmony_ci    /* Done, get ready for next time */
266a8e1175bSopenharmony_ci    MD_CHK(mbedtls_md_hmac_reset(ctx));
267a8e1175bSopenharmony_ci
268a8e1175bSopenharmony_ci#undef MD_CHK
269a8e1175bSopenharmony_ci
270a8e1175bSopenharmony_cicleanup:
271a8e1175bSopenharmony_ci    mbedtls_md_free(&aux);
272a8e1175bSopenharmony_ci    return ret;
273a8e1175bSopenharmony_ci}
274a8e1175bSopenharmony_ci
275a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
276a8e1175bSopenharmony_ci
277a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
278a8e1175bSopenharmony_ci
279a8e1175bSopenharmony_cistatic uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
280a8e1175bSopenharmony_ci
281a8e1175bSopenharmony_ci/*
282a8e1175bSopenharmony_ci * Start a timer.
283a8e1175bSopenharmony_ci * Passing millisecs = 0 cancels a running timer.
284a8e1175bSopenharmony_ci */
285a8e1175bSopenharmony_civoid mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs)
286a8e1175bSopenharmony_ci{
287a8e1175bSopenharmony_ci    if (ssl->f_set_timer == NULL) {
288a8e1175bSopenharmony_ci        return;
289a8e1175bSopenharmony_ci    }
290a8e1175bSopenharmony_ci
291a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int) millisecs));
292a8e1175bSopenharmony_ci    ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs);
293a8e1175bSopenharmony_ci}
294a8e1175bSopenharmony_ci
295a8e1175bSopenharmony_ci/*
296a8e1175bSopenharmony_ci * Return -1 is timer is expired, 0 if it isn't.
297a8e1175bSopenharmony_ci */
298a8e1175bSopenharmony_ciint mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl)
299a8e1175bSopenharmony_ci{
300a8e1175bSopenharmony_ci    if (ssl->f_get_timer == NULL) {
301a8e1175bSopenharmony_ci        return 0;
302a8e1175bSopenharmony_ci    }
303a8e1175bSopenharmony_ci
304a8e1175bSopenharmony_ci    if (ssl->f_get_timer(ssl->p_timer) == 2) {
305a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired"));
306a8e1175bSopenharmony_ci        return -1;
307a8e1175bSopenharmony_ci    }
308a8e1175bSopenharmony_ci
309a8e1175bSopenharmony_ci    return 0;
310a8e1175bSopenharmony_ci}
311a8e1175bSopenharmony_ci
312a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
313a8e1175bSopenharmony_cistatic int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
314a8e1175bSopenharmony_ci                                   unsigned char *buf,
315a8e1175bSopenharmony_ci                                   size_t len,
316a8e1175bSopenharmony_ci                                   mbedtls_record *rec);
317a8e1175bSopenharmony_ci
318a8e1175bSopenharmony_ciint mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl,
319a8e1175bSopenharmony_ci                             unsigned char *buf,
320a8e1175bSopenharmony_ci                             size_t buflen)
321a8e1175bSopenharmony_ci{
322a8e1175bSopenharmony_ci    int ret = 0;
323a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record"));
324a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen);
325a8e1175bSopenharmony_ci
326a8e1175bSopenharmony_ci    /* We don't support record checking in TLS because
327a8e1175bSopenharmony_ci     * there doesn't seem to be a usecase for it.
328a8e1175bSopenharmony_ci     */
329a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
330a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
331a8e1175bSopenharmony_ci        goto exit;
332a8e1175bSopenharmony_ci    }
333a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
334a8e1175bSopenharmony_ci    else {
335a8e1175bSopenharmony_ci        mbedtls_record rec;
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci        ret = ssl_parse_record_header(ssl, buf, buflen, &rec);
338a8e1175bSopenharmony_ci        if (ret != 0) {
339a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret);
340a8e1175bSopenharmony_ci            goto exit;
341a8e1175bSopenharmony_ci        }
342a8e1175bSopenharmony_ci
343a8e1175bSopenharmony_ci        if (ssl->transform_in != NULL) {
344a8e1175bSopenharmony_ci            ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec);
345a8e1175bSopenharmony_ci            if (ret != 0) {
346a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret);
347a8e1175bSopenharmony_ci                goto exit;
348a8e1175bSopenharmony_ci            }
349a8e1175bSopenharmony_ci        }
350a8e1175bSopenharmony_ci    }
351a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
352a8e1175bSopenharmony_ci
353a8e1175bSopenharmony_ciexit:
354a8e1175bSopenharmony_ci    /* On success, we have decrypted the buffer in-place, so make
355a8e1175bSopenharmony_ci     * sure we don't leak any plaintext data. */
356a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(buf, buflen);
357a8e1175bSopenharmony_ci
358a8e1175bSopenharmony_ci    /* For the purpose of this API, treat messages with unexpected CID
359a8e1175bSopenharmony_ci     * as well as such from future epochs as unexpected. */
360a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
361a8e1175bSopenharmony_ci        ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
362a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
363a8e1175bSopenharmony_ci    }
364a8e1175bSopenharmony_ci
365a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record"));
366a8e1175bSopenharmony_ci    return ret;
367a8e1175bSopenharmony_ci}
368a8e1175bSopenharmony_ci
369a8e1175bSopenharmony_ci#define SSL_DONT_FORCE_FLUSH 0
370a8e1175bSopenharmony_ci#define SSL_FORCE_FLUSH      1
371a8e1175bSopenharmony_ci
372a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
373a8e1175bSopenharmony_ci
374a8e1175bSopenharmony_ci/* Forward declarations for functions related to message buffering. */
375a8e1175bSopenharmony_cistatic void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
376a8e1175bSopenharmony_ci                                    uint8_t slot);
377a8e1175bSopenharmony_cistatic void ssl_free_buffered_record(mbedtls_ssl_context *ssl);
378a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
379a8e1175bSopenharmony_cistatic int ssl_load_buffered_message(mbedtls_ssl_context *ssl);
380a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
381a8e1175bSopenharmony_cistatic int ssl_load_buffered_record(mbedtls_ssl_context *ssl);
382a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
383a8e1175bSopenharmony_cistatic int ssl_buffer_message(mbedtls_ssl_context *ssl);
384a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
385a8e1175bSopenharmony_cistatic int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
386a8e1175bSopenharmony_ci                                    mbedtls_record const *rec);
387a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
388a8e1175bSopenharmony_cistatic int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl);
389a8e1175bSopenharmony_ci
390a8e1175bSopenharmony_cistatic size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl)
391a8e1175bSopenharmony_ci{
392a8e1175bSopenharmony_ci    size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
393a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
394a8e1175bSopenharmony_ci    size_t out_buf_len = ssl->out_buf_len;
395a8e1175bSopenharmony_ci#else
396a8e1175bSopenharmony_ci    size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
397a8e1175bSopenharmony_ci#endif
398a8e1175bSopenharmony_ci
399a8e1175bSopenharmony_ci    if (mtu != 0 && mtu < out_buf_len) {
400a8e1175bSopenharmony_ci        return mtu;
401a8e1175bSopenharmony_ci    }
402a8e1175bSopenharmony_ci
403a8e1175bSopenharmony_ci    return out_buf_len;
404a8e1175bSopenharmony_ci}
405a8e1175bSopenharmony_ci
406a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
407a8e1175bSopenharmony_cistatic int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl)
408a8e1175bSopenharmony_ci{
409a8e1175bSopenharmony_ci    size_t const bytes_written = ssl->out_left;
410a8e1175bSopenharmony_ci    size_t const mtu           = ssl_get_maximum_datagram_size(ssl);
411a8e1175bSopenharmony_ci
412a8e1175bSopenharmony_ci    /* Double-check that the write-index hasn't gone
413a8e1175bSopenharmony_ci     * past what we can transmit in a single datagram. */
414a8e1175bSopenharmony_ci    if (bytes_written > mtu) {
415a8e1175bSopenharmony_ci        /* Should never happen... */
416a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
417a8e1175bSopenharmony_ci    }
418a8e1175bSopenharmony_ci
419a8e1175bSopenharmony_ci    return (int) (mtu - bytes_written);
420a8e1175bSopenharmony_ci}
421a8e1175bSopenharmony_ci
422a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
423a8e1175bSopenharmony_cistatic int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl)
424a8e1175bSopenharmony_ci{
425a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426a8e1175bSopenharmony_ci    size_t remaining, expansion;
427a8e1175bSopenharmony_ci    size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
428a8e1175bSopenharmony_ci
429a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
430a8e1175bSopenharmony_ci    const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
431a8e1175bSopenharmony_ci
432a8e1175bSopenharmony_ci    if (max_len > mfl) {
433a8e1175bSopenharmony_ci        max_len = mfl;
434a8e1175bSopenharmony_ci    }
435a8e1175bSopenharmony_ci
436a8e1175bSopenharmony_ci    /* By the standard (RFC 6066 Sect. 4), the MFL extension
437a8e1175bSopenharmony_ci     * only limits the maximum record payload size, so in theory
438a8e1175bSopenharmony_ci     * we would be allowed to pack multiple records of payload size
439a8e1175bSopenharmony_ci     * MFL into a single datagram. However, this would mean that there's
440a8e1175bSopenharmony_ci     * no way to explicitly communicate MTU restrictions to the peer.
441a8e1175bSopenharmony_ci     *
442a8e1175bSopenharmony_ci     * The following reduction of max_len makes sure that we never
443a8e1175bSopenharmony_ci     * write datagrams larger than MFL + Record Expansion Overhead.
444a8e1175bSopenharmony_ci     */
445a8e1175bSopenharmony_ci    if (max_len <= ssl->out_left) {
446a8e1175bSopenharmony_ci        return 0;
447a8e1175bSopenharmony_ci    }
448a8e1175bSopenharmony_ci
449a8e1175bSopenharmony_ci    max_len -= ssl->out_left;
450a8e1175bSopenharmony_ci#endif
451a8e1175bSopenharmony_ci
452a8e1175bSopenharmony_ci    ret = ssl_get_remaining_space_in_datagram(ssl);
453a8e1175bSopenharmony_ci    if (ret < 0) {
454a8e1175bSopenharmony_ci        return ret;
455a8e1175bSopenharmony_ci    }
456a8e1175bSopenharmony_ci    remaining = (size_t) ret;
457a8e1175bSopenharmony_ci
458a8e1175bSopenharmony_ci    ret = mbedtls_ssl_get_record_expansion(ssl);
459a8e1175bSopenharmony_ci    if (ret < 0) {
460a8e1175bSopenharmony_ci        return ret;
461a8e1175bSopenharmony_ci    }
462a8e1175bSopenharmony_ci    expansion = (size_t) ret;
463a8e1175bSopenharmony_ci
464a8e1175bSopenharmony_ci    if (remaining <= expansion) {
465a8e1175bSopenharmony_ci        return 0;
466a8e1175bSopenharmony_ci    }
467a8e1175bSopenharmony_ci
468a8e1175bSopenharmony_ci    remaining -= expansion;
469a8e1175bSopenharmony_ci    if (remaining >= max_len) {
470a8e1175bSopenharmony_ci        remaining = max_len;
471a8e1175bSopenharmony_ci    }
472a8e1175bSopenharmony_ci
473a8e1175bSopenharmony_ci    return (int) remaining;
474a8e1175bSopenharmony_ci}
475a8e1175bSopenharmony_ci
476a8e1175bSopenharmony_ci/*
477a8e1175bSopenharmony_ci * Double the retransmit timeout value, within the allowed range,
478a8e1175bSopenharmony_ci * returning -1 if the maximum value has already been reached.
479a8e1175bSopenharmony_ci */
480a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
481a8e1175bSopenharmony_cistatic int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl)
482a8e1175bSopenharmony_ci{
483a8e1175bSopenharmony_ci    uint32_t new_timeout;
484a8e1175bSopenharmony_ci
485a8e1175bSopenharmony_ci    if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max) {
486a8e1175bSopenharmony_ci        return -1;
487a8e1175bSopenharmony_ci    }
488a8e1175bSopenharmony_ci
489a8e1175bSopenharmony_ci    /* Implement the final paragraph of RFC 6347 section 4.1.1.1
490a8e1175bSopenharmony_ci     * in the following way: after the initial transmission and a first
491a8e1175bSopenharmony_ci     * retransmission, back off to a temporary estimated MTU of 508 bytes.
492a8e1175bSopenharmony_ci     * This value is guaranteed to be deliverable (if not guaranteed to be
493a8e1175bSopenharmony_ci     * delivered) of any compliant IPv4 (and IPv6) network, and should work
494a8e1175bSopenharmony_ci     * on most non-IP stacks too. */
495a8e1175bSopenharmony_ci    if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) {
496a8e1175bSopenharmony_ci        ssl->handshake->mtu = 508;
497a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes", ssl->handshake->mtu));
498a8e1175bSopenharmony_ci    }
499a8e1175bSopenharmony_ci
500a8e1175bSopenharmony_ci    new_timeout = 2 * ssl->handshake->retransmit_timeout;
501a8e1175bSopenharmony_ci
502a8e1175bSopenharmony_ci    /* Avoid arithmetic overflow and range overflow */
503a8e1175bSopenharmony_ci    if (new_timeout < ssl->handshake->retransmit_timeout ||
504a8e1175bSopenharmony_ci        new_timeout > ssl->conf->hs_timeout_max) {
505a8e1175bSopenharmony_ci        new_timeout = ssl->conf->hs_timeout_max;
506a8e1175bSopenharmony_ci    }
507a8e1175bSopenharmony_ci
508a8e1175bSopenharmony_ci    ssl->handshake->retransmit_timeout = new_timeout;
509a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
510a8e1175bSopenharmony_ci                              (unsigned long) ssl->handshake->retransmit_timeout));
511a8e1175bSopenharmony_ci
512a8e1175bSopenharmony_ci    return 0;
513a8e1175bSopenharmony_ci}
514a8e1175bSopenharmony_ci
515a8e1175bSopenharmony_cistatic void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl)
516a8e1175bSopenharmony_ci{
517a8e1175bSopenharmony_ci    ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
518a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
519a8e1175bSopenharmony_ci                              (unsigned long) ssl->handshake->retransmit_timeout));
520a8e1175bSopenharmony_ci}
521a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
522a8e1175bSopenharmony_ci
523a8e1175bSopenharmony_ci/*
524a8e1175bSopenharmony_ci * Encryption/decryption functions
525a8e1175bSopenharmony_ci */
526a8e1175bSopenharmony_ci
527a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
528a8e1175bSopenharmony_ci
529a8e1175bSopenharmony_cistatic size_t ssl_compute_padding_length(size_t len,
530a8e1175bSopenharmony_ci                                         size_t granularity)
531a8e1175bSopenharmony_ci{
532a8e1175bSopenharmony_ci    return (granularity - (len + 1) % granularity) % granularity;
533a8e1175bSopenharmony_ci}
534a8e1175bSopenharmony_ci
535a8e1175bSopenharmony_ci/* This functions transforms a (D)TLS plaintext fragment and a record content
536a8e1175bSopenharmony_ci * type into an instance of the (D)TLSInnerPlaintext structure. This is used
537a8e1175bSopenharmony_ci * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
538a8e1175bSopenharmony_ci * a record's content type.
539a8e1175bSopenharmony_ci *
540a8e1175bSopenharmony_ci *        struct {
541a8e1175bSopenharmony_ci *            opaque content[DTLSPlaintext.length];
542a8e1175bSopenharmony_ci *            ContentType real_type;
543a8e1175bSopenharmony_ci *            uint8 zeros[length_of_padding];
544a8e1175bSopenharmony_ci *        } (D)TLSInnerPlaintext;
545a8e1175bSopenharmony_ci *
546a8e1175bSopenharmony_ci *  Input:
547a8e1175bSopenharmony_ci *  - `content`: The beginning of the buffer holding the
548a8e1175bSopenharmony_ci *               plaintext to be wrapped.
549a8e1175bSopenharmony_ci *  - `*content_size`: The length of the plaintext in Bytes.
550a8e1175bSopenharmony_ci *  - `max_len`: The number of Bytes available starting from
551a8e1175bSopenharmony_ci *               `content`. This must be `>= *content_size`.
552a8e1175bSopenharmony_ci *  - `rec_type`: The desired record content type.
553a8e1175bSopenharmony_ci *
554a8e1175bSopenharmony_ci *  Output:
555a8e1175bSopenharmony_ci *  - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
556a8e1175bSopenharmony_ci *  - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
557a8e1175bSopenharmony_ci *
558a8e1175bSopenharmony_ci *  Returns:
559a8e1175bSopenharmony_ci *  - `0` on success.
560a8e1175bSopenharmony_ci *  - A negative error code if `max_len` didn't offer enough space
561a8e1175bSopenharmony_ci *    for the expansion.
562a8e1175bSopenharmony_ci */
563a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
564a8e1175bSopenharmony_cistatic int ssl_build_inner_plaintext(unsigned char *content,
565a8e1175bSopenharmony_ci                                     size_t *content_size,
566a8e1175bSopenharmony_ci                                     size_t remaining,
567a8e1175bSopenharmony_ci                                     uint8_t rec_type,
568a8e1175bSopenharmony_ci                                     size_t pad)
569a8e1175bSopenharmony_ci{
570a8e1175bSopenharmony_ci    size_t len = *content_size;
571a8e1175bSopenharmony_ci
572a8e1175bSopenharmony_ci    /* Write real content type */
573a8e1175bSopenharmony_ci    if (remaining == 0) {
574a8e1175bSopenharmony_ci        return -1;
575a8e1175bSopenharmony_ci    }
576a8e1175bSopenharmony_ci    content[len] = rec_type;
577a8e1175bSopenharmony_ci    len++;
578a8e1175bSopenharmony_ci    remaining--;
579a8e1175bSopenharmony_ci
580a8e1175bSopenharmony_ci    if (remaining < pad) {
581a8e1175bSopenharmony_ci        return -1;
582a8e1175bSopenharmony_ci    }
583a8e1175bSopenharmony_ci    memset(content + len, 0, pad);
584a8e1175bSopenharmony_ci    len += pad;
585a8e1175bSopenharmony_ci    remaining -= pad;
586a8e1175bSopenharmony_ci
587a8e1175bSopenharmony_ci    *content_size = len;
588a8e1175bSopenharmony_ci    return 0;
589a8e1175bSopenharmony_ci}
590a8e1175bSopenharmony_ci
591a8e1175bSopenharmony_ci/* This function parses a (D)TLSInnerPlaintext structure.
592a8e1175bSopenharmony_ci * See ssl_build_inner_plaintext() for details. */
593a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
594a8e1175bSopenharmony_cistatic int ssl_parse_inner_plaintext(unsigned char const *content,
595a8e1175bSopenharmony_ci                                     size_t *content_size,
596a8e1175bSopenharmony_ci                                     uint8_t *rec_type)
597a8e1175bSopenharmony_ci{
598a8e1175bSopenharmony_ci    size_t remaining = *content_size;
599a8e1175bSopenharmony_ci
600a8e1175bSopenharmony_ci    /* Determine length of padding by skipping zeroes from the back. */
601a8e1175bSopenharmony_ci    do {
602a8e1175bSopenharmony_ci        if (remaining == 0) {
603a8e1175bSopenharmony_ci            return -1;
604a8e1175bSopenharmony_ci        }
605a8e1175bSopenharmony_ci        remaining--;
606a8e1175bSopenharmony_ci    } while (content[remaining] == 0);
607a8e1175bSopenharmony_ci
608a8e1175bSopenharmony_ci    *content_size = remaining;
609a8e1175bSopenharmony_ci    *rec_type = content[remaining];
610a8e1175bSopenharmony_ci
611a8e1175bSopenharmony_ci    return 0;
612a8e1175bSopenharmony_ci}
613a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */
614a8e1175bSopenharmony_ci
615a8e1175bSopenharmony_ci/* The size of the `add_data` structure depends on various
616a8e1175bSopenharmony_ci * factors, namely
617a8e1175bSopenharmony_ci *
618a8e1175bSopenharmony_ci * 1) CID functionality disabled
619a8e1175bSopenharmony_ci *
620a8e1175bSopenharmony_ci * additional_data =
621a8e1175bSopenharmony_ci *    8:                    seq_num +
622a8e1175bSopenharmony_ci *    1:                       type +
623a8e1175bSopenharmony_ci *    2:                    version +
624a8e1175bSopenharmony_ci *    2:  length of inner plaintext +
625a8e1175bSopenharmony_ci *
626a8e1175bSopenharmony_ci * size = 13 bytes
627a8e1175bSopenharmony_ci *
628a8e1175bSopenharmony_ci * 2) CID functionality based on RFC 9146 enabled
629a8e1175bSopenharmony_ci *
630a8e1175bSopenharmony_ci * size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length
631a8e1175bSopenharmony_ci *      = 23 + CID-length
632a8e1175bSopenharmony_ci *
633a8e1175bSopenharmony_ci * 3) CID functionality based on legacy CID version
634a8e1175bSopenharmony_ci    according to draft-ietf-tls-dtls-connection-id-05
635a8e1175bSopenharmony_ci *  https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
636a8e1175bSopenharmony_ci *
637a8e1175bSopenharmony_ci * size = 13 + 1 + CID-length
638a8e1175bSopenharmony_ci *
639a8e1175bSopenharmony_ci * More information about the CID usage:
640a8e1175bSopenharmony_ci *
641a8e1175bSopenharmony_ci * Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the
642a8e1175bSopenharmony_ci * size of the additional data structure is calculated as:
643a8e1175bSopenharmony_ci *
644a8e1175bSopenharmony_ci * additional_data =
645a8e1175bSopenharmony_ci *    8:                    seq_num +
646a8e1175bSopenharmony_ci *    1:                  tls12_cid +
647a8e1175bSopenharmony_ci *    2:     DTLSCipherText.version +
648a8e1175bSopenharmony_ci *    n:                        cid +
649a8e1175bSopenharmony_ci *    1:                 cid_length +
650a8e1175bSopenharmony_ci *    2: length_of_DTLSInnerPlaintext
651a8e1175bSopenharmony_ci *
652a8e1175bSopenharmony_ci * Per RFC 9146 the size of the add_data structure is calculated as:
653a8e1175bSopenharmony_ci *
654a8e1175bSopenharmony_ci * additional_data =
655a8e1175bSopenharmony_ci *    8:        seq_num_placeholder +
656a8e1175bSopenharmony_ci *    1:                  tls12_cid +
657a8e1175bSopenharmony_ci *    1:                 cid_length +
658a8e1175bSopenharmony_ci *    1:                  tls12_cid +
659a8e1175bSopenharmony_ci *    2:     DTLSCiphertext.version +
660a8e1175bSopenharmony_ci *    2:                      epoch +
661a8e1175bSopenharmony_ci *    6:            sequence_number +
662a8e1175bSopenharmony_ci *    n:                        cid +
663a8e1175bSopenharmony_ci *    2: length_of_DTLSInnerPlaintext
664a8e1175bSopenharmony_ci *
665a8e1175bSopenharmony_ci */
666a8e1175bSopenharmony_cistatic void ssl_extract_add_data_from_record(unsigned char *add_data,
667a8e1175bSopenharmony_ci                                             size_t *add_data_len,
668a8e1175bSopenharmony_ci                                             mbedtls_record *rec,
669a8e1175bSopenharmony_ci                                             mbedtls_ssl_protocol_version
670a8e1175bSopenharmony_ci                                             tls_version,
671a8e1175bSopenharmony_ci                                             size_t taglen)
672a8e1175bSopenharmony_ci{
673a8e1175bSopenharmony_ci    /* Several types of ciphers have been defined for use with TLS and DTLS,
674a8e1175bSopenharmony_ci     * and the MAC calculations for those ciphers differ slightly. Further
675a8e1175bSopenharmony_ci     * variants were added when the CID functionality was added with RFC 9146.
676a8e1175bSopenharmony_ci     * This implementations also considers the use of a legacy version of the
677a8e1175bSopenharmony_ci     * CID specification published in draft-ietf-tls-dtls-connection-id-05,
678a8e1175bSopenharmony_ci     * which is used in deployments.
679a8e1175bSopenharmony_ci     *
680a8e1175bSopenharmony_ci     * We will distinguish between the non-CID and the CID cases below.
681a8e1175bSopenharmony_ci     *
682a8e1175bSopenharmony_ci     * --- Non-CID cases ---
683a8e1175bSopenharmony_ci     *
684a8e1175bSopenharmony_ci     * Quoting RFC 5246 (TLS 1.2):
685a8e1175bSopenharmony_ci     *
686a8e1175bSopenharmony_ci     *    additional_data = seq_num + TLSCompressed.type +
687a8e1175bSopenharmony_ci     *                      TLSCompressed.version + TLSCompressed.length;
688a8e1175bSopenharmony_ci     *
689a8e1175bSopenharmony_ci     * For TLS 1.3, the record sequence number is dropped from the AAD
690a8e1175bSopenharmony_ci     * and encoded within the nonce of the AEAD operation instead.
691a8e1175bSopenharmony_ci     * Moreover, the additional data involves the length of the TLS
692a8e1175bSopenharmony_ci     * ciphertext, not the TLS plaintext as in earlier versions.
693a8e1175bSopenharmony_ci     * Quoting RFC 8446 (TLS 1.3):
694a8e1175bSopenharmony_ci     *
695a8e1175bSopenharmony_ci     *      additional_data = TLSCiphertext.opaque_type ||
696a8e1175bSopenharmony_ci     *                        TLSCiphertext.legacy_record_version ||
697a8e1175bSopenharmony_ci     *                        TLSCiphertext.length
698a8e1175bSopenharmony_ci     *
699a8e1175bSopenharmony_ci     * We pass the tag length to this function in order to compute the
700a8e1175bSopenharmony_ci     * ciphertext length from the inner plaintext length rec->data_len via
701a8e1175bSopenharmony_ci     *
702a8e1175bSopenharmony_ci     *     TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
703a8e1175bSopenharmony_ci     *
704a8e1175bSopenharmony_ci     * --- CID cases ---
705a8e1175bSopenharmony_ci     *
706a8e1175bSopenharmony_ci     * RFC 9146 uses a common pattern when constructing the data
707a8e1175bSopenharmony_ci     * passed into a MAC / AEAD cipher.
708a8e1175bSopenharmony_ci     *
709a8e1175bSopenharmony_ci     * Data concatenation for MACs used with block ciphers with
710a8e1175bSopenharmony_ci     * Encrypt-then-MAC Processing (with CID):
711a8e1175bSopenharmony_ci     *
712a8e1175bSopenharmony_ci     *  data = seq_num_placeholder +
713a8e1175bSopenharmony_ci     *         tls12_cid +
714a8e1175bSopenharmony_ci     *         cid_length +
715a8e1175bSopenharmony_ci     *         tls12_cid +
716a8e1175bSopenharmony_ci     *         DTLSCiphertext.version +
717a8e1175bSopenharmony_ci     *         epoch +
718a8e1175bSopenharmony_ci     *         sequence_number +
719a8e1175bSopenharmony_ci     *         cid +
720a8e1175bSopenharmony_ci     *         DTLSCiphertext.length +
721a8e1175bSopenharmony_ci     *         IV +
722a8e1175bSopenharmony_ci     *         ENC(content + padding + padding_length)
723a8e1175bSopenharmony_ci     *
724a8e1175bSopenharmony_ci     * Data concatenation for MACs used with block ciphers (with CID):
725a8e1175bSopenharmony_ci     *
726a8e1175bSopenharmony_ci     *  data =  seq_num_placeholder +
727a8e1175bSopenharmony_ci     *          tls12_cid +
728a8e1175bSopenharmony_ci     *          cid_length +
729a8e1175bSopenharmony_ci     *          tls12_cid +
730a8e1175bSopenharmony_ci     *          DTLSCiphertext.version +
731a8e1175bSopenharmony_ci     *          epoch +
732a8e1175bSopenharmony_ci     *          sequence_number +
733a8e1175bSopenharmony_ci     *          cid +
734a8e1175bSopenharmony_ci     *          length_of_DTLSInnerPlaintext +
735a8e1175bSopenharmony_ci     *          DTLSInnerPlaintext.content +
736a8e1175bSopenharmony_ci     *          DTLSInnerPlaintext.real_type +
737a8e1175bSopenharmony_ci     *          DTLSInnerPlaintext.zeros
738a8e1175bSopenharmony_ci     *
739a8e1175bSopenharmony_ci     * AEAD ciphers use the following additional data calculation (with CIDs):
740a8e1175bSopenharmony_ci     *
741a8e1175bSopenharmony_ci     *     additional_data = seq_num_placeholder +
742a8e1175bSopenharmony_ci     *                tls12_cid +
743a8e1175bSopenharmony_ci     *                cid_length +
744a8e1175bSopenharmony_ci     *                tls12_cid +
745a8e1175bSopenharmony_ci     *                DTLSCiphertext.version +
746a8e1175bSopenharmony_ci     *                epoch +
747a8e1175bSopenharmony_ci     *                sequence_number +
748a8e1175bSopenharmony_ci     *                cid +
749a8e1175bSopenharmony_ci     *                length_of_DTLSInnerPlaintext
750a8e1175bSopenharmony_ci     *
751a8e1175bSopenharmony_ci     * Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use)
752a8e1175bSopenharmony_ci     * defines the additional data calculation as follows:
753a8e1175bSopenharmony_ci     *
754a8e1175bSopenharmony_ci     *     additional_data = seq_num +
755a8e1175bSopenharmony_ci     *                tls12_cid +
756a8e1175bSopenharmony_ci     *                DTLSCipherText.version +
757a8e1175bSopenharmony_ci     *                cid +
758a8e1175bSopenharmony_ci     *                cid_length +
759a8e1175bSopenharmony_ci     *                length_of_DTLSInnerPlaintext
760a8e1175bSopenharmony_ci     */
761a8e1175bSopenharmony_ci
762a8e1175bSopenharmony_ci    unsigned char *cur = add_data;
763a8e1175bSopenharmony_ci    size_t ad_len_field = rec->data_len;
764a8e1175bSopenharmony_ci
765a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
766a8e1175bSopenharmony_ci    MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
767a8e1175bSopenharmony_ci    const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
768a8e1175bSopenharmony_ci#endif
769a8e1175bSopenharmony_ci
770a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
771a8e1175bSopenharmony_ci    if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
772a8e1175bSopenharmony_ci        /* In TLS 1.3, the AAD contains the length of the TLSCiphertext,
773a8e1175bSopenharmony_ci         * which differs from the length of the TLSInnerPlaintext
774a8e1175bSopenharmony_ci         * by the length of the authentication tag. */
775a8e1175bSopenharmony_ci        ad_len_field += taglen;
776a8e1175bSopenharmony_ci    } else
777a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
778a8e1175bSopenharmony_ci    {
779a8e1175bSopenharmony_ci        ((void) tls_version);
780a8e1175bSopenharmony_ci        ((void) taglen);
781a8e1175bSopenharmony_ci
782a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
783a8e1175bSopenharmony_ci        MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
784a8e1175bSopenharmony_ci        if (rec->cid_len != 0) {
785a8e1175bSopenharmony_ci            // seq_num_placeholder
786a8e1175bSopenharmony_ci            memcpy(cur, seq_num_placeholder, sizeof(seq_num_placeholder));
787a8e1175bSopenharmony_ci            cur += sizeof(seq_num_placeholder);
788a8e1175bSopenharmony_ci
789a8e1175bSopenharmony_ci            // tls12_cid type
790a8e1175bSopenharmony_ci            *cur = rec->type;
791a8e1175bSopenharmony_ci            cur++;
792a8e1175bSopenharmony_ci
793a8e1175bSopenharmony_ci            // cid_length
794a8e1175bSopenharmony_ci            *cur = rec->cid_len;
795a8e1175bSopenharmony_ci            cur++;
796a8e1175bSopenharmony_ci        } else
797a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
798a8e1175bSopenharmony_ci        {
799a8e1175bSopenharmony_ci            // epoch + sequence number
800a8e1175bSopenharmony_ci            memcpy(cur, rec->ctr, sizeof(rec->ctr));
801a8e1175bSopenharmony_ci            cur += sizeof(rec->ctr);
802a8e1175bSopenharmony_ci        }
803a8e1175bSopenharmony_ci    }
804a8e1175bSopenharmony_ci
805a8e1175bSopenharmony_ci    // type
806a8e1175bSopenharmony_ci    *cur = rec->type;
807a8e1175bSopenharmony_ci    cur++;
808a8e1175bSopenharmony_ci
809a8e1175bSopenharmony_ci    // version
810a8e1175bSopenharmony_ci    memcpy(cur, rec->ver, sizeof(rec->ver));
811a8e1175bSopenharmony_ci    cur += sizeof(rec->ver);
812a8e1175bSopenharmony_ci
813a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
814a8e1175bSopenharmony_ci    MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1
815a8e1175bSopenharmony_ci
816a8e1175bSopenharmony_ci    if (rec->cid_len != 0) {
817a8e1175bSopenharmony_ci        // CID
818a8e1175bSopenharmony_ci        memcpy(cur, rec->cid, rec->cid_len);
819a8e1175bSopenharmony_ci        cur += rec->cid_len;
820a8e1175bSopenharmony_ci
821a8e1175bSopenharmony_ci        // cid_length
822a8e1175bSopenharmony_ci        *cur = rec->cid_len;
823a8e1175bSopenharmony_ci        cur++;
824a8e1175bSopenharmony_ci
825a8e1175bSopenharmony_ci        // length of inner plaintext
826a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
827a8e1175bSopenharmony_ci        cur += 2;
828a8e1175bSopenharmony_ci    } else
829a8e1175bSopenharmony_ci#elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
830a8e1175bSopenharmony_ci    MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
831a8e1175bSopenharmony_ci
832a8e1175bSopenharmony_ci    if (rec->cid_len != 0) {
833a8e1175bSopenharmony_ci        // epoch + sequence number
834a8e1175bSopenharmony_ci        memcpy(cur, rec->ctr, sizeof(rec->ctr));
835a8e1175bSopenharmony_ci        cur += sizeof(rec->ctr);
836a8e1175bSopenharmony_ci
837a8e1175bSopenharmony_ci        // CID
838a8e1175bSopenharmony_ci        memcpy(cur, rec->cid, rec->cid_len);
839a8e1175bSopenharmony_ci        cur += rec->cid_len;
840a8e1175bSopenharmony_ci
841a8e1175bSopenharmony_ci        // length of inner plaintext
842a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
843a8e1175bSopenharmony_ci        cur += 2;
844a8e1175bSopenharmony_ci    } else
845a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
846a8e1175bSopenharmony_ci    {
847a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
848a8e1175bSopenharmony_ci        cur += 2;
849a8e1175bSopenharmony_ci    }
850a8e1175bSopenharmony_ci
851a8e1175bSopenharmony_ci    *add_data_len = (size_t) (cur - add_data);
852a8e1175bSopenharmony_ci}
853a8e1175bSopenharmony_ci
854a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HAVE_AEAD)
855a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
856a8e1175bSopenharmony_cistatic int ssl_transform_aead_dynamic_iv_is_explicit(
857a8e1175bSopenharmony_ci    mbedtls_ssl_transform const *transform)
858a8e1175bSopenharmony_ci{
859a8e1175bSopenharmony_ci    return transform->ivlen != transform->fixed_ivlen;
860a8e1175bSopenharmony_ci}
861a8e1175bSopenharmony_ci
862a8e1175bSopenharmony_ci/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
863a8e1175bSopenharmony_ci *
864a8e1175bSopenharmony_ci * Concretely, this occurs in two variants:
865a8e1175bSopenharmony_ci *
866a8e1175bSopenharmony_ci * a) Fixed and dynamic IV lengths add up to total IV length, giving
867a8e1175bSopenharmony_ci *       IV = fixed_iv || dynamic_iv
868a8e1175bSopenharmony_ci *
869a8e1175bSopenharmony_ci *    This variant is used in TLS 1.2 when used with GCM or CCM.
870a8e1175bSopenharmony_ci *
871a8e1175bSopenharmony_ci * b) Fixed IV lengths matches total IV length, giving
872a8e1175bSopenharmony_ci *       IV = fixed_iv XOR ( 0 || dynamic_iv )
873a8e1175bSopenharmony_ci *
874a8e1175bSopenharmony_ci *    This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
875a8e1175bSopenharmony_ci *
876a8e1175bSopenharmony_ci * See also the documentation of mbedtls_ssl_transform.
877a8e1175bSopenharmony_ci *
878a8e1175bSopenharmony_ci * This function has the precondition that
879a8e1175bSopenharmony_ci *
880a8e1175bSopenharmony_ci *     dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
881a8e1175bSopenharmony_ci *
882a8e1175bSopenharmony_ci * which has to be ensured by the caller. If this precondition
883a8e1175bSopenharmony_ci * violated, the behavior of this function is undefined.
884a8e1175bSopenharmony_ci */
885a8e1175bSopenharmony_cistatic void ssl_build_record_nonce(unsigned char *dst_iv,
886a8e1175bSopenharmony_ci                                   size_t dst_iv_len,
887a8e1175bSopenharmony_ci                                   unsigned char const *fixed_iv,
888a8e1175bSopenharmony_ci                                   size_t fixed_iv_len,
889a8e1175bSopenharmony_ci                                   unsigned char const *dynamic_iv,
890a8e1175bSopenharmony_ci                                   size_t dynamic_iv_len)
891a8e1175bSopenharmony_ci{
892a8e1175bSopenharmony_ci    /* Start with Fixed IV || 0 */
893a8e1175bSopenharmony_ci    memset(dst_iv, 0, dst_iv_len);
894a8e1175bSopenharmony_ci    memcpy(dst_iv, fixed_iv, fixed_iv_len);
895a8e1175bSopenharmony_ci
896a8e1175bSopenharmony_ci    dst_iv += dst_iv_len - dynamic_iv_len;
897a8e1175bSopenharmony_ci    mbedtls_xor(dst_iv, dst_iv, dynamic_iv, dynamic_iv_len);
898a8e1175bSopenharmony_ci}
899a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HAVE_AEAD */
900a8e1175bSopenharmony_ci
901a8e1175bSopenharmony_ciint mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
902a8e1175bSopenharmony_ci                            mbedtls_ssl_transform *transform,
903a8e1175bSopenharmony_ci                            mbedtls_record *rec,
904a8e1175bSopenharmony_ci                            int (*f_rng)(void *, unsigned char *, size_t),
905a8e1175bSopenharmony_ci                            void *p_rng)
906a8e1175bSopenharmony_ci{
907a8e1175bSopenharmony_ci    mbedtls_ssl_mode_t ssl_mode;
908a8e1175bSopenharmony_ci    int auth_done = 0;
909a8e1175bSopenharmony_ci    unsigned char *data;
910a8e1175bSopenharmony_ci    /* For an explanation of the additional data length see
911a8e1175bSopenharmony_ci     * the description of ssl_extract_add_data_from_record().
912a8e1175bSopenharmony_ci     */
913a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
914a8e1175bSopenharmony_ci    unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
915a8e1175bSopenharmony_ci#else
916a8e1175bSopenharmony_ci    unsigned char add_data[13];
917a8e1175bSopenharmony_ci#endif
918a8e1175bSopenharmony_ci    size_t add_data_len;
919a8e1175bSopenharmony_ci    size_t post_avail;
920a8e1175bSopenharmony_ci
921a8e1175bSopenharmony_ci    /* The SSL context is only used for debugging purposes! */
922a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEBUG_C)
923a8e1175bSopenharmony_ci    ssl = NULL; /* make sure we don't use it except for debug */
924a8e1175bSopenharmony_ci    ((void) ssl);
925a8e1175bSopenharmony_ci#endif
926a8e1175bSopenharmony_ci
927a8e1175bSopenharmony_ci    /* The PRNG is used for dynamic IV generation that's used
928a8e1175bSopenharmony_ci     * for CBC transformations in TLS 1.2. */
929a8e1175bSopenharmony_ci#if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
930a8e1175bSopenharmony_ci    defined(MBEDTLS_SSL_PROTO_TLS1_2))
931a8e1175bSopenharmony_ci    ((void) f_rng);
932a8e1175bSopenharmony_ci    ((void) p_rng);
933a8e1175bSopenharmony_ci#endif
934a8e1175bSopenharmony_ci
935a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf"));
936a8e1175bSopenharmony_ci
937a8e1175bSopenharmony_ci    if (transform == NULL) {
938a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf"));
939a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
940a8e1175bSopenharmony_ci    }
941a8e1175bSopenharmony_ci    if (rec == NULL
942a8e1175bSopenharmony_ci        || rec->buf == NULL
943a8e1175bSopenharmony_ci        || rec->buf_len < rec->data_offset
944a8e1175bSopenharmony_ci        || rec->buf_len - rec->data_offset < rec->data_len
945a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
946a8e1175bSopenharmony_ci        || rec->cid_len != 0
947a8e1175bSopenharmony_ci#endif
948a8e1175bSopenharmony_ci        ) {
949a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to encrypt_buf"));
950a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
951a8e1175bSopenharmony_ci    }
952a8e1175bSopenharmony_ci
953a8e1175bSopenharmony_ci    ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
954a8e1175bSopenharmony_ci
955a8e1175bSopenharmony_ci    data = rec->buf + rec->data_offset;
956a8e1175bSopenharmony_ci    post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
957a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload",
958a8e1175bSopenharmony_ci                          data, rec->data_len);
959a8e1175bSopenharmony_ci
960a8e1175bSopenharmony_ci    if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
961a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET
962a8e1175bSopenharmony_ci                                  " too large, maximum %" MBEDTLS_PRINTF_SIZET,
963a8e1175bSopenharmony_ci                                  rec->data_len,
964a8e1175bSopenharmony_ci                                  (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
965a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
966a8e1175bSopenharmony_ci    }
967a8e1175bSopenharmony_ci
968a8e1175bSopenharmony_ci    /* The following two code paths implement the (D)TLSInnerPlaintext
969a8e1175bSopenharmony_ci     * structure present in TLS 1.3 and DTLS 1.2 + CID.
970a8e1175bSopenharmony_ci     *
971a8e1175bSopenharmony_ci     * See ssl_build_inner_plaintext() for more information.
972a8e1175bSopenharmony_ci     *
973a8e1175bSopenharmony_ci     * Note that this changes `rec->data_len`, and hence
974a8e1175bSopenharmony_ci     * `post_avail` needs to be recalculated afterwards.
975a8e1175bSopenharmony_ci     *
976a8e1175bSopenharmony_ci     * Note also that the two code paths cannot occur simultaneously
977a8e1175bSopenharmony_ci     * since they apply to different versions of the protocol. There
978a8e1175bSopenharmony_ci     * is hence no risk of double-addition of the inner plaintext.
979a8e1175bSopenharmony_ci     */
980a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
981a8e1175bSopenharmony_ci    if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
982a8e1175bSopenharmony_ci        size_t padding =
983a8e1175bSopenharmony_ci            ssl_compute_padding_length(rec->data_len,
984a8e1175bSopenharmony_ci                                       MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
985a8e1175bSopenharmony_ci        if (ssl_build_inner_plaintext(data,
986a8e1175bSopenharmony_ci                                      &rec->data_len,
987a8e1175bSopenharmony_ci                                      post_avail,
988a8e1175bSopenharmony_ci                                      rec->type,
989a8e1175bSopenharmony_ci                                      padding) != 0) {
990a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
991a8e1175bSopenharmony_ci        }
992a8e1175bSopenharmony_ci
993a8e1175bSopenharmony_ci        rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
994a8e1175bSopenharmony_ci    }
995a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
996a8e1175bSopenharmony_ci
997a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
998a8e1175bSopenharmony_ci    /*
999a8e1175bSopenharmony_ci     * Add CID information
1000a8e1175bSopenharmony_ci     */
1001a8e1175bSopenharmony_ci    rec->cid_len = transform->out_cid_len;
1002a8e1175bSopenharmony_ci    memcpy(rec->cid, transform->out_cid, transform->out_cid_len);
1003a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len);
1004a8e1175bSopenharmony_ci
1005a8e1175bSopenharmony_ci    if (rec->cid_len != 0) {
1006a8e1175bSopenharmony_ci        size_t padding =
1007a8e1175bSopenharmony_ci            ssl_compute_padding_length(rec->data_len,
1008a8e1175bSopenharmony_ci                                       MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
1009a8e1175bSopenharmony_ci        /*
1010a8e1175bSopenharmony_ci         * Wrap plaintext into DTLSInnerPlaintext structure.
1011a8e1175bSopenharmony_ci         * See ssl_build_inner_plaintext() for more information.
1012a8e1175bSopenharmony_ci         *
1013a8e1175bSopenharmony_ci         * Note that this changes `rec->data_len`, and hence
1014a8e1175bSopenharmony_ci         * `post_avail` needs to be recalculated afterwards.
1015a8e1175bSopenharmony_ci         */
1016a8e1175bSopenharmony_ci        if (ssl_build_inner_plaintext(data,
1017a8e1175bSopenharmony_ci                                      &rec->data_len,
1018a8e1175bSopenharmony_ci                                      post_avail,
1019a8e1175bSopenharmony_ci                                      rec->type,
1020a8e1175bSopenharmony_ci                                      padding) != 0) {
1021a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1022a8e1175bSopenharmony_ci        }
1023a8e1175bSopenharmony_ci
1024a8e1175bSopenharmony_ci        rec->type = MBEDTLS_SSL_MSG_CID;
1025a8e1175bSopenharmony_ci    }
1026a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1027a8e1175bSopenharmony_ci
1028a8e1175bSopenharmony_ci    post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
1029a8e1175bSopenharmony_ci
1030a8e1175bSopenharmony_ci    /*
1031a8e1175bSopenharmony_ci     * Add MAC before if needed
1032a8e1175bSopenharmony_ci     */
1033a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
1034a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_STREAM ||
1035a8e1175bSopenharmony_ci        ssl_mode == MBEDTLS_SSL_MODE_CBC) {
1036a8e1175bSopenharmony_ci        if (post_avail < transform->maclen) {
1037a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1038a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1039a8e1175bSopenharmony_ci        }
1040a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1041a8e1175bSopenharmony_ci        unsigned char mac[MBEDTLS_SSL_MAC_ADD];
1042a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1043a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1044a8e1175bSopenharmony_ci        psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
1045a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1046a8e1175bSopenharmony_ci        size_t sign_mac_length = 0;
1047a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1048a8e1175bSopenharmony_ci
1049a8e1175bSopenharmony_ci        ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1050a8e1175bSopenharmony_ci                                         transform->tls_version,
1051a8e1175bSopenharmony_ci                                         transform->taglen);
1052a8e1175bSopenharmony_ci
1053a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1054a8e1175bSopenharmony_ci        status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
1055a8e1175bSopenharmony_ci                                    transform->psa_mac_alg);
1056a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1057a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1058a8e1175bSopenharmony_ci        }
1059a8e1175bSopenharmony_ci
1060a8e1175bSopenharmony_ci        status = psa_mac_update(&operation, add_data, add_data_len);
1061a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1062a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1063a8e1175bSopenharmony_ci        }
1064a8e1175bSopenharmony_ci
1065a8e1175bSopenharmony_ci        status = psa_mac_update(&operation, data, rec->data_len);
1066a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1067a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1068a8e1175bSopenharmony_ci        }
1069a8e1175bSopenharmony_ci
1070a8e1175bSopenharmony_ci        status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
1071a8e1175bSopenharmony_ci                                     &sign_mac_length);
1072a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1073a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1074a8e1175bSopenharmony_ci        }
1075a8e1175bSopenharmony_ci#else
1076a8e1175bSopenharmony_ci        ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
1077a8e1175bSopenharmony_ci                                     add_data_len);
1078a8e1175bSopenharmony_ci        if (ret != 0) {
1079a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1080a8e1175bSopenharmony_ci        }
1081a8e1175bSopenharmony_ci        ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len);
1082a8e1175bSopenharmony_ci        if (ret != 0) {
1083a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1084a8e1175bSopenharmony_ci        }
1085a8e1175bSopenharmony_ci        ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
1086a8e1175bSopenharmony_ci        if (ret != 0) {
1087a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1088a8e1175bSopenharmony_ci        }
1089a8e1175bSopenharmony_ci        ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
1090a8e1175bSopenharmony_ci        if (ret != 0) {
1091a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
1092a8e1175bSopenharmony_ci        }
1093a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1094a8e1175bSopenharmony_ci
1095a8e1175bSopenharmony_ci        memcpy(data + rec->data_len, mac, transform->maclen);
1096a8e1175bSopenharmony_ci#endif
1097a8e1175bSopenharmony_ci
1098a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len,
1099a8e1175bSopenharmony_ci                              transform->maclen);
1100a8e1175bSopenharmony_ci
1101a8e1175bSopenharmony_ci        rec->data_len += transform->maclen;
1102a8e1175bSopenharmony_ci        post_avail -= transform->maclen;
1103a8e1175bSopenharmony_ci        auth_done++;
1104a8e1175bSopenharmony_ci
1105a8e1175bSopenharmony_cihmac_failed_etm_disabled:
1106a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(mac, transform->maclen);
1107a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1108a8e1175bSopenharmony_ci        ret = PSA_TO_MBEDTLS_ERR(status);
1109a8e1175bSopenharmony_ci        status = psa_mac_abort(&operation);
1110a8e1175bSopenharmony_ci        if (ret == 0 && status != PSA_SUCCESS) {
1111a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1112a8e1175bSopenharmony_ci        }
1113a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1114a8e1175bSopenharmony_ci        if (ret != 0) {
1115a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_hmac_xxx", ret);
1116a8e1175bSopenharmony_ci            return ret;
1117a8e1175bSopenharmony_ci        }
1118a8e1175bSopenharmony_ci    }
1119a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
1120a8e1175bSopenharmony_ci
1121a8e1175bSopenharmony_ci    /*
1122a8e1175bSopenharmony_ci     * Encrypt
1123a8e1175bSopenharmony_ci     */
1124a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
1125a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
1126a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
1127a8e1175bSopenharmony_ci                                                                                    "including %d bytes of padding",
1128a8e1175bSopenharmony_ci                                  rec->data_len, 0));
1129a8e1175bSopenharmony_ci
1130a8e1175bSopenharmony_ci        /* The only supported stream cipher is "NULL",
1131a8e1175bSopenharmony_ci         * so there's nothing to do here.*/
1132a8e1175bSopenharmony_ci    } else
1133a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
1134a8e1175bSopenharmony_ci
1135a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HAVE_AEAD)
1136a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
1137a8e1175bSopenharmony_ci        unsigned char iv[12];
1138a8e1175bSopenharmony_ci        unsigned char *dynamic_iv;
1139a8e1175bSopenharmony_ci        size_t dynamic_iv_len;
1140a8e1175bSopenharmony_ci        int dynamic_iv_is_explicit =
1141a8e1175bSopenharmony_ci            ssl_transform_aead_dynamic_iv_is_explicit(transform);
1142a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1143a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1144a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1145a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1146a8e1175bSopenharmony_ci
1147a8e1175bSopenharmony_ci        /* Check that there's space for the authentication tag. */
1148a8e1175bSopenharmony_ci        if (post_avail < transform->taglen) {
1149a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1150a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1151a8e1175bSopenharmony_ci        }
1152a8e1175bSopenharmony_ci
1153a8e1175bSopenharmony_ci        /*
1154a8e1175bSopenharmony_ci         * Build nonce for AEAD encryption.
1155a8e1175bSopenharmony_ci         *
1156a8e1175bSopenharmony_ci         * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
1157a8e1175bSopenharmony_ci         *       part of the IV is prepended to the ciphertext and
1158a8e1175bSopenharmony_ci         *       can be chosen freely - in particular, it need not
1159a8e1175bSopenharmony_ci         *       agree with the record sequence number.
1160a8e1175bSopenharmony_ci         *       However, since ChaChaPoly as well as all AEAD modes
1161a8e1175bSopenharmony_ci         *       in TLS 1.3 use the record sequence number as the
1162a8e1175bSopenharmony_ci         *       dynamic part of the nonce, we uniformly use the
1163a8e1175bSopenharmony_ci         *       record sequence number here in all cases.
1164a8e1175bSopenharmony_ci         */
1165a8e1175bSopenharmony_ci        dynamic_iv     = rec->ctr;
1166a8e1175bSopenharmony_ci        dynamic_iv_len = sizeof(rec->ctr);
1167a8e1175bSopenharmony_ci
1168a8e1175bSopenharmony_ci        ssl_build_record_nonce(iv, sizeof(iv),
1169a8e1175bSopenharmony_ci                               transform->iv_enc,
1170a8e1175bSopenharmony_ci                               transform->fixed_ivlen,
1171a8e1175bSopenharmony_ci                               dynamic_iv,
1172a8e1175bSopenharmony_ci                               dynamic_iv_len);
1173a8e1175bSopenharmony_ci
1174a8e1175bSopenharmony_ci        /*
1175a8e1175bSopenharmony_ci         * Build additional data for AEAD encryption.
1176a8e1175bSopenharmony_ci         * This depends on the TLS version.
1177a8e1175bSopenharmony_ci         */
1178a8e1175bSopenharmony_ci        ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1179a8e1175bSopenharmony_ci                                         transform->tls_version,
1180a8e1175bSopenharmony_ci                                         transform->taglen);
1181a8e1175bSopenharmony_ci
1182a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)",
1183a8e1175bSopenharmony_ci                              iv, transform->ivlen);
1184a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)",
1185a8e1175bSopenharmony_ci                              dynamic_iv,
1186a8e1175bSopenharmony_ci                              dynamic_iv_is_explicit ? dynamic_iv_len : 0);
1187a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
1188a8e1175bSopenharmony_ci                              add_data, add_data_len);
1189a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
1190a8e1175bSopenharmony_ci                                                                                    "including 0 bytes of padding",
1191a8e1175bSopenharmony_ci                                  rec->data_len));
1192a8e1175bSopenharmony_ci
1193a8e1175bSopenharmony_ci        /*
1194a8e1175bSopenharmony_ci         * Encrypt and authenticate
1195a8e1175bSopenharmony_ci         */
1196a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1197a8e1175bSopenharmony_ci        status = psa_aead_encrypt(transform->psa_key_enc,
1198a8e1175bSopenharmony_ci                                  transform->psa_alg,
1199a8e1175bSopenharmony_ci                                  iv, transform->ivlen,
1200a8e1175bSopenharmony_ci                                  add_data, add_data_len,
1201a8e1175bSopenharmony_ci                                  data, rec->data_len,
1202a8e1175bSopenharmony_ci                                  data, rec->buf_len - (data - rec->buf),
1203a8e1175bSopenharmony_ci                                  &rec->data_len);
1204a8e1175bSopenharmony_ci
1205a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1206a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1207a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_encrypt_buf", ret);
1208a8e1175bSopenharmony_ci            return ret;
1209a8e1175bSopenharmony_ci        }
1210a8e1175bSopenharmony_ci#else
1211a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_auth_encrypt_ext(&transform->cipher_ctx_enc,
1212a8e1175bSopenharmony_ci                                                   iv, transform->ivlen,
1213a8e1175bSopenharmony_ci                                                   add_data, add_data_len,
1214a8e1175bSopenharmony_ci                                                   data, rec->data_len, /* src */
1215a8e1175bSopenharmony_ci                                                   data, rec->buf_len - (size_t) (data - rec->buf), /* dst */
1216a8e1175bSopenharmony_ci                                                   &rec->data_len,
1217a8e1175bSopenharmony_ci                                                   transform->taglen)) != 0) {
1218a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret);
1219a8e1175bSopenharmony_ci            return ret;
1220a8e1175bSopenharmony_ci        }
1221a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1222a8e1175bSopenharmony_ci
1223a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag",
1224a8e1175bSopenharmony_ci                              data + rec->data_len - transform->taglen,
1225a8e1175bSopenharmony_ci                              transform->taglen);
1226a8e1175bSopenharmony_ci        /* Account for authentication tag. */
1227a8e1175bSopenharmony_ci        post_avail -= transform->taglen;
1228a8e1175bSopenharmony_ci
1229a8e1175bSopenharmony_ci        /*
1230a8e1175bSopenharmony_ci         * Prefix record content with dynamic IV in case it is explicit.
1231a8e1175bSopenharmony_ci         */
1232a8e1175bSopenharmony_ci        if (dynamic_iv_is_explicit != 0) {
1233a8e1175bSopenharmony_ci            if (rec->data_offset < dynamic_iv_len) {
1234a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1235a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1236a8e1175bSopenharmony_ci            }
1237a8e1175bSopenharmony_ci
1238a8e1175bSopenharmony_ci            memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len);
1239a8e1175bSopenharmony_ci            rec->data_offset -= dynamic_iv_len;
1240a8e1175bSopenharmony_ci            rec->data_len    += dynamic_iv_len;
1241a8e1175bSopenharmony_ci        }
1242a8e1175bSopenharmony_ci
1243a8e1175bSopenharmony_ci        auth_done++;
1244a8e1175bSopenharmony_ci    } else
1245a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HAVE_AEAD */
1246a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
1247a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
1248a8e1175bSopenharmony_ci        ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
1249a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1250a8e1175bSopenharmony_ci        size_t padlen, i;
1251a8e1175bSopenharmony_ci        size_t olen;
1252a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1253a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1254a8e1175bSopenharmony_ci        size_t part_len;
1255a8e1175bSopenharmony_ci        psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
1256a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1257a8e1175bSopenharmony_ci
1258a8e1175bSopenharmony_ci        /* Currently we're always using minimal padding
1259a8e1175bSopenharmony_ci         * (up to 255 bytes would be allowed). */
1260a8e1175bSopenharmony_ci        padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen;
1261a8e1175bSopenharmony_ci        if (padlen == transform->ivlen) {
1262a8e1175bSopenharmony_ci            padlen = 0;
1263a8e1175bSopenharmony_ci        }
1264a8e1175bSopenharmony_ci
1265a8e1175bSopenharmony_ci        /* Check there's enough space in the buffer for the padding. */
1266a8e1175bSopenharmony_ci        if (post_avail < padlen + 1) {
1267a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1268a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1269a8e1175bSopenharmony_ci        }
1270a8e1175bSopenharmony_ci
1271a8e1175bSopenharmony_ci        for (i = 0; i <= padlen; i++) {
1272a8e1175bSopenharmony_ci            data[rec->data_len + i] = (unsigned char) padlen;
1273a8e1175bSopenharmony_ci        }
1274a8e1175bSopenharmony_ci
1275a8e1175bSopenharmony_ci        rec->data_len += padlen + 1;
1276a8e1175bSopenharmony_ci        post_avail -= padlen + 1;
1277a8e1175bSopenharmony_ci
1278a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1279a8e1175bSopenharmony_ci        /*
1280a8e1175bSopenharmony_ci         * Prepend per-record IV for block cipher in TLS v1.2 as per
1281a8e1175bSopenharmony_ci         * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
1282a8e1175bSopenharmony_ci         */
1283a8e1175bSopenharmony_ci        if (f_rng == NULL) {
1284a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("No PRNG provided to encrypt_record routine"));
1285a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1286a8e1175bSopenharmony_ci        }
1287a8e1175bSopenharmony_ci
1288a8e1175bSopenharmony_ci        if (rec->data_offset < transform->ivlen) {
1289a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1290a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1291a8e1175bSopenharmony_ci        }
1292a8e1175bSopenharmony_ci
1293a8e1175bSopenharmony_ci        /*
1294a8e1175bSopenharmony_ci         * Generate IV
1295a8e1175bSopenharmony_ci         */
1296a8e1175bSopenharmony_ci        ret = f_rng(p_rng, transform->iv_enc, transform->ivlen);
1297a8e1175bSopenharmony_ci        if (ret != 0) {
1298a8e1175bSopenharmony_ci            return ret;
1299a8e1175bSopenharmony_ci        }
1300a8e1175bSopenharmony_ci
1301a8e1175bSopenharmony_ci        memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen);
1302a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
1303a8e1175bSopenharmony_ci
1304a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
1305a8e1175bSopenharmony_ci                                                                                    "including %"
1306a8e1175bSopenharmony_ci                                  MBEDTLS_PRINTF_SIZET
1307a8e1175bSopenharmony_ci                                  " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
1308a8e1175bSopenharmony_ci                                  rec->data_len, transform->ivlen,
1309a8e1175bSopenharmony_ci                                  padlen + 1));
1310a8e1175bSopenharmony_ci
1311a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1312a8e1175bSopenharmony_ci        status = psa_cipher_encrypt_setup(&cipher_op,
1313a8e1175bSopenharmony_ci                                          transform->psa_key_enc, transform->psa_alg);
1314a8e1175bSopenharmony_ci
1315a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1316a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1317a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_encrypt_setup", ret);
1318a8e1175bSopenharmony_ci            return ret;
1319a8e1175bSopenharmony_ci        }
1320a8e1175bSopenharmony_ci
1321a8e1175bSopenharmony_ci        status = psa_cipher_set_iv(&cipher_op, transform->iv_enc, transform->ivlen);
1322a8e1175bSopenharmony_ci
1323a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1324a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1325a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
1326a8e1175bSopenharmony_ci            return ret;
1327a8e1175bSopenharmony_ci
1328a8e1175bSopenharmony_ci        }
1329a8e1175bSopenharmony_ci
1330a8e1175bSopenharmony_ci        status = psa_cipher_update(&cipher_op,
1331a8e1175bSopenharmony_ci                                   data, rec->data_len,
1332a8e1175bSopenharmony_ci                                   data, rec->data_len, &olen);
1333a8e1175bSopenharmony_ci
1334a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1335a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1336a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
1337a8e1175bSopenharmony_ci            return ret;
1338a8e1175bSopenharmony_ci
1339a8e1175bSopenharmony_ci        }
1340a8e1175bSopenharmony_ci
1341a8e1175bSopenharmony_ci        status = psa_cipher_finish(&cipher_op,
1342a8e1175bSopenharmony_ci                                   data + olen, rec->data_len - olen,
1343a8e1175bSopenharmony_ci                                   &part_len);
1344a8e1175bSopenharmony_ci
1345a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1346a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1347a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
1348a8e1175bSopenharmony_ci            return ret;
1349a8e1175bSopenharmony_ci
1350a8e1175bSopenharmony_ci        }
1351a8e1175bSopenharmony_ci
1352a8e1175bSopenharmony_ci        olen += part_len;
1353a8e1175bSopenharmony_ci#else
1354a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_enc,
1355a8e1175bSopenharmony_ci                                        transform->iv_enc,
1356a8e1175bSopenharmony_ci                                        transform->ivlen,
1357a8e1175bSopenharmony_ci                                        data, rec->data_len,
1358a8e1175bSopenharmony_ci                                        data, &olen)) != 0) {
1359a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
1360a8e1175bSopenharmony_ci            return ret;
1361a8e1175bSopenharmony_ci        }
1362a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1363a8e1175bSopenharmony_ci
1364a8e1175bSopenharmony_ci        if (rec->data_len != olen) {
1365a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1366a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1367a8e1175bSopenharmony_ci        }
1368a8e1175bSopenharmony_ci
1369a8e1175bSopenharmony_ci        data             -= transform->ivlen;
1370a8e1175bSopenharmony_ci        rec->data_offset -= transform->ivlen;
1371a8e1175bSopenharmony_ci        rec->data_len    += transform->ivlen;
1372a8e1175bSopenharmony_ci
1373a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1374a8e1175bSopenharmony_ci        if (auth_done == 0) {
1375a8e1175bSopenharmony_ci            unsigned char mac[MBEDTLS_SSL_MAC_ADD];
1376a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1377a8e1175bSopenharmony_ci            psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
1378a8e1175bSopenharmony_ci            size_t sign_mac_length = 0;
1379a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1380a8e1175bSopenharmony_ci
1381a8e1175bSopenharmony_ci            /* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length))
1382a8e1175bSopenharmony_ci             */
1383a8e1175bSopenharmony_ci
1384a8e1175bSopenharmony_ci            if (post_avail < transform->maclen) {
1385a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
1386a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1387a8e1175bSopenharmony_ci            }
1388a8e1175bSopenharmony_ci
1389a8e1175bSopenharmony_ci            ssl_extract_add_data_from_record(add_data, &add_data_len,
1390a8e1175bSopenharmony_ci                                             rec, transform->tls_version,
1391a8e1175bSopenharmony_ci                                             transform->taglen);
1392a8e1175bSopenharmony_ci
1393a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
1394a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
1395a8e1175bSopenharmony_ci                                  add_data_len);
1396a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1397a8e1175bSopenharmony_ci            status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
1398a8e1175bSopenharmony_ci                                        transform->psa_mac_alg);
1399a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1400a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1401a8e1175bSopenharmony_ci            }
1402a8e1175bSopenharmony_ci
1403a8e1175bSopenharmony_ci            status = psa_mac_update(&operation, add_data, add_data_len);
1404a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1405a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1406a8e1175bSopenharmony_ci            }
1407a8e1175bSopenharmony_ci
1408a8e1175bSopenharmony_ci            status = psa_mac_update(&operation, data, rec->data_len);
1409a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1410a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1411a8e1175bSopenharmony_ci            }
1412a8e1175bSopenharmony_ci
1413a8e1175bSopenharmony_ci            status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
1414a8e1175bSopenharmony_ci                                         &sign_mac_length);
1415a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1416a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1417a8e1175bSopenharmony_ci            }
1418a8e1175bSopenharmony_ci#else
1419a8e1175bSopenharmony_ci
1420a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
1421a8e1175bSopenharmony_ci                                         add_data_len);
1422a8e1175bSopenharmony_ci            if (ret != 0) {
1423a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1424a8e1175bSopenharmony_ci            }
1425a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_update(&transform->md_ctx_enc,
1426a8e1175bSopenharmony_ci                                         data, rec->data_len);
1427a8e1175bSopenharmony_ci            if (ret != 0) {
1428a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1429a8e1175bSopenharmony_ci            }
1430a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
1431a8e1175bSopenharmony_ci            if (ret != 0) {
1432a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1433a8e1175bSopenharmony_ci            }
1434a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
1435a8e1175bSopenharmony_ci            if (ret != 0) {
1436a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1437a8e1175bSopenharmony_ci            }
1438a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1439a8e1175bSopenharmony_ci
1440a8e1175bSopenharmony_ci            memcpy(data + rec->data_len, mac, transform->maclen);
1441a8e1175bSopenharmony_ci
1442a8e1175bSopenharmony_ci            rec->data_len += transform->maclen;
1443a8e1175bSopenharmony_ci            post_avail -= transform->maclen;
1444a8e1175bSopenharmony_ci            auth_done++;
1445a8e1175bSopenharmony_ci
1446a8e1175bSopenharmony_cihmac_failed_etm_enabled:
1447a8e1175bSopenharmony_ci            mbedtls_platform_zeroize(mac, transform->maclen);
1448a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1449a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1450a8e1175bSopenharmony_ci            status = psa_mac_abort(&operation);
1451a8e1175bSopenharmony_ci            if (ret == 0 && status != PSA_SUCCESS) {
1452a8e1175bSopenharmony_ci                ret = PSA_TO_MBEDTLS_ERR(status);
1453a8e1175bSopenharmony_ci            }
1454a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1455a8e1175bSopenharmony_ci            if (ret != 0) {
1456a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "HMAC calculation failed", ret);
1457a8e1175bSopenharmony_ci                return ret;
1458a8e1175bSopenharmony_ci            }
1459a8e1175bSopenharmony_ci        }
1460a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
1461a8e1175bSopenharmony_ci    } else
1462a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
1463a8e1175bSopenharmony_ci    {
1464a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1465a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1466a8e1175bSopenharmony_ci    }
1467a8e1175bSopenharmony_ci
1468a8e1175bSopenharmony_ci    /* Make extra sure authentication was performed, exactly once */
1469a8e1175bSopenharmony_ci    if (auth_done != 1) {
1470a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1471a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1472a8e1175bSopenharmony_ci    }
1473a8e1175bSopenharmony_ci
1474a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf"));
1475a8e1175bSopenharmony_ci
1476a8e1175bSopenharmony_ci    return 0;
1477a8e1175bSopenharmony_ci}
1478a8e1175bSopenharmony_ci
1479a8e1175bSopenharmony_ciint mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
1480a8e1175bSopenharmony_ci                            mbedtls_ssl_transform *transform,
1481a8e1175bSopenharmony_ci                            mbedtls_record *rec)
1482a8e1175bSopenharmony_ci{
1483a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_SSL_HAVE_AEAD)
1484a8e1175bSopenharmony_ci    size_t olen;
1485a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_SSL_HAVE_AEAD */
1486a8e1175bSopenharmony_ci    mbedtls_ssl_mode_t ssl_mode;
1487a8e1175bSopenharmony_ci    int ret;
1488a8e1175bSopenharmony_ci
1489a8e1175bSopenharmony_ci    int auth_done = 0;
1490a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
1491a8e1175bSopenharmony_ci    size_t padlen = 0;
1492a8e1175bSopenharmony_ci    mbedtls_ct_condition_t correct = MBEDTLS_CT_TRUE;
1493a8e1175bSopenharmony_ci#endif
1494a8e1175bSopenharmony_ci    unsigned char *data;
1495a8e1175bSopenharmony_ci    /* For an explanation of the additional data length see
1496a8e1175bSopenharmony_ci     * the description of ssl_extract_add_data_from_record().
1497a8e1175bSopenharmony_ci     */
1498a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1499a8e1175bSopenharmony_ci    unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX];
1500a8e1175bSopenharmony_ci#else
1501a8e1175bSopenharmony_ci    unsigned char add_data[13];
1502a8e1175bSopenharmony_ci#endif
1503a8e1175bSopenharmony_ci    size_t add_data_len;
1504a8e1175bSopenharmony_ci
1505a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEBUG_C)
1506a8e1175bSopenharmony_ci    ssl = NULL; /* make sure we don't use it except for debug */
1507a8e1175bSopenharmony_ci    ((void) ssl);
1508a8e1175bSopenharmony_ci#endif
1509a8e1175bSopenharmony_ci
1510a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf"));
1511a8e1175bSopenharmony_ci    if (rec == NULL                     ||
1512a8e1175bSopenharmony_ci        rec->buf == NULL                ||
1513a8e1175bSopenharmony_ci        rec->buf_len < rec->data_offset ||
1514a8e1175bSopenharmony_ci        rec->buf_len - rec->data_offset < rec->data_len) {
1515a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to decrypt_buf"));
1516a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1517a8e1175bSopenharmony_ci    }
1518a8e1175bSopenharmony_ci
1519a8e1175bSopenharmony_ci    data = rec->buf + rec->data_offset;
1520a8e1175bSopenharmony_ci    ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
1521a8e1175bSopenharmony_ci
1522a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1523a8e1175bSopenharmony_ci    /*
1524a8e1175bSopenharmony_ci     * Match record's CID with incoming CID.
1525a8e1175bSopenharmony_ci     */
1526a8e1175bSopenharmony_ci    if (rec->cid_len != transform->in_cid_len ||
1527a8e1175bSopenharmony_ci        memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) {
1528a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_UNEXPECTED_CID;
1529a8e1175bSopenharmony_ci    }
1530a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1531a8e1175bSopenharmony_ci
1532a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
1533a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
1534a8e1175bSopenharmony_ci        if (rec->data_len < transform->maclen) {
1535a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
1536a8e1175bSopenharmony_ci                                  ("Record too short for MAC:"
1537a8e1175bSopenharmony_ci                                   " %" MBEDTLS_PRINTF_SIZET " < %" MBEDTLS_PRINTF_SIZET,
1538a8e1175bSopenharmony_ci                                   rec->data_len, transform->maclen));
1539a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_MAC;
1540a8e1175bSopenharmony_ci        }
1541a8e1175bSopenharmony_ci
1542a8e1175bSopenharmony_ci        /* The only supported stream cipher is "NULL",
1543a8e1175bSopenharmony_ci         * so there's no encryption to do here.*/
1544a8e1175bSopenharmony_ci    } else
1545a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
1546a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HAVE_AEAD)
1547a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
1548a8e1175bSopenharmony_ci        unsigned char iv[12];
1549a8e1175bSopenharmony_ci        unsigned char *dynamic_iv;
1550a8e1175bSopenharmony_ci        size_t dynamic_iv_len;
1551a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1552a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1553a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1554a8e1175bSopenharmony_ci
1555a8e1175bSopenharmony_ci        /*
1556a8e1175bSopenharmony_ci         * Extract dynamic part of nonce for AEAD decryption.
1557a8e1175bSopenharmony_ci         *
1558a8e1175bSopenharmony_ci         * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
1559a8e1175bSopenharmony_ci         *       part of the IV is prepended to the ciphertext and
1560a8e1175bSopenharmony_ci         *       can be chosen freely - in particular, it need not
1561a8e1175bSopenharmony_ci         *       agree with the record sequence number.
1562a8e1175bSopenharmony_ci         */
1563a8e1175bSopenharmony_ci        dynamic_iv_len = sizeof(rec->ctr);
1564a8e1175bSopenharmony_ci        if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) {
1565a8e1175bSopenharmony_ci            if (rec->data_len < dynamic_iv_len) {
1566a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1567a8e1175bSopenharmony_ci                                          " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
1568a8e1175bSopenharmony_ci                                          rec->data_len,
1569a8e1175bSopenharmony_ci                                          dynamic_iv_len));
1570a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INVALID_MAC;
1571a8e1175bSopenharmony_ci            }
1572a8e1175bSopenharmony_ci            dynamic_iv = data;
1573a8e1175bSopenharmony_ci
1574a8e1175bSopenharmony_ci            data += dynamic_iv_len;
1575a8e1175bSopenharmony_ci            rec->data_offset += dynamic_iv_len;
1576a8e1175bSopenharmony_ci            rec->data_len    -= dynamic_iv_len;
1577a8e1175bSopenharmony_ci        } else {
1578a8e1175bSopenharmony_ci            dynamic_iv = rec->ctr;
1579a8e1175bSopenharmony_ci        }
1580a8e1175bSopenharmony_ci
1581a8e1175bSopenharmony_ci        /* Check that there's space for the authentication tag. */
1582a8e1175bSopenharmony_ci        if (rec->data_len < transform->taglen) {
1583a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1584a8e1175bSopenharmony_ci                                      ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
1585a8e1175bSopenharmony_ci                                      rec->data_len,
1586a8e1175bSopenharmony_ci                                      transform->taglen));
1587a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_MAC;
1588a8e1175bSopenharmony_ci        }
1589a8e1175bSopenharmony_ci        rec->data_len -= transform->taglen;
1590a8e1175bSopenharmony_ci
1591a8e1175bSopenharmony_ci        /*
1592a8e1175bSopenharmony_ci         * Prepare nonce from dynamic and static parts.
1593a8e1175bSopenharmony_ci         */
1594a8e1175bSopenharmony_ci        ssl_build_record_nonce(iv, sizeof(iv),
1595a8e1175bSopenharmony_ci                               transform->iv_dec,
1596a8e1175bSopenharmony_ci                               transform->fixed_ivlen,
1597a8e1175bSopenharmony_ci                               dynamic_iv,
1598a8e1175bSopenharmony_ci                               dynamic_iv_len);
1599a8e1175bSopenharmony_ci
1600a8e1175bSopenharmony_ci        /*
1601a8e1175bSopenharmony_ci         * Build additional data for AEAD encryption.
1602a8e1175bSopenharmony_ci         * This depends on the TLS version.
1603a8e1175bSopenharmony_ci         */
1604a8e1175bSopenharmony_ci        ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1605a8e1175bSopenharmony_ci                                         transform->tls_version,
1606a8e1175bSopenharmony_ci                                         transform->taglen);
1607a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
1608a8e1175bSopenharmony_ci                              add_data, add_data_len);
1609a8e1175bSopenharmony_ci
1610a8e1175bSopenharmony_ci        /* Because of the check above, we know that there are
1611a8e1175bSopenharmony_ci         * explicit_iv_len Bytes preceding data, and taglen
1612a8e1175bSopenharmony_ci         * bytes following data + data_len. This justifies
1613a8e1175bSopenharmony_ci         * the debug message and the invocation of
1614a8e1175bSopenharmony_ci         * mbedtls_cipher_auth_decrypt_ext() below. */
1615a8e1175bSopenharmony_ci
1616a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen);
1617a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len,
1618a8e1175bSopenharmony_ci                              transform->taglen);
1619a8e1175bSopenharmony_ci
1620a8e1175bSopenharmony_ci        /*
1621a8e1175bSopenharmony_ci         * Decrypt and authenticate
1622a8e1175bSopenharmony_ci         */
1623a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1624a8e1175bSopenharmony_ci        status = psa_aead_decrypt(transform->psa_key_dec,
1625a8e1175bSopenharmony_ci                                  transform->psa_alg,
1626a8e1175bSopenharmony_ci                                  iv, transform->ivlen,
1627a8e1175bSopenharmony_ci                                  add_data, add_data_len,
1628a8e1175bSopenharmony_ci                                  data, rec->data_len + transform->taglen,
1629a8e1175bSopenharmony_ci                                  data, rec->buf_len - (data - rec->buf),
1630a8e1175bSopenharmony_ci                                  &olen);
1631a8e1175bSopenharmony_ci
1632a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1633a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1634a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_aead_decrypt", ret);
1635a8e1175bSopenharmony_ci            return ret;
1636a8e1175bSopenharmony_ci        }
1637a8e1175bSopenharmony_ci#else
1638a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_auth_decrypt_ext
1639a8e1175bSopenharmony_ci                       (&transform->cipher_ctx_dec,
1640a8e1175bSopenharmony_ci                       iv, transform->ivlen,
1641a8e1175bSopenharmony_ci                       add_data, add_data_len,
1642a8e1175bSopenharmony_ci                       data, rec->data_len + transform->taglen, /* src */
1643a8e1175bSopenharmony_ci                       data, rec->buf_len - (size_t) (data - rec->buf), &olen, /* dst */
1644a8e1175bSopenharmony_ci                       transform->taglen)) != 0) {
1645a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret);
1646a8e1175bSopenharmony_ci
1647a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
1648a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INVALID_MAC;
1649a8e1175bSopenharmony_ci            }
1650a8e1175bSopenharmony_ci
1651a8e1175bSopenharmony_ci            return ret;
1652a8e1175bSopenharmony_ci        }
1653a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1654a8e1175bSopenharmony_ci
1655a8e1175bSopenharmony_ci        auth_done++;
1656a8e1175bSopenharmony_ci
1657a8e1175bSopenharmony_ci        /* Double-check that AEAD decryption doesn't change content length. */
1658a8e1175bSopenharmony_ci        if (olen != rec->data_len) {
1659a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1660a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1661a8e1175bSopenharmony_ci        }
1662a8e1175bSopenharmony_ci    } else
1663a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HAVE_AEAD */
1664a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
1665a8e1175bSopenharmony_ci    if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
1666a8e1175bSopenharmony_ci        ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
1667a8e1175bSopenharmony_ci        size_t minlen = 0;
1668a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1669a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
1670a8e1175bSopenharmony_ci        size_t part_len;
1671a8e1175bSopenharmony_ci        psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
1672a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1673a8e1175bSopenharmony_ci
1674a8e1175bSopenharmony_ci        /*
1675a8e1175bSopenharmony_ci         * Check immediate ciphertext sanity
1676a8e1175bSopenharmony_ci         */
1677a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1678a8e1175bSopenharmony_ci        /* The ciphertext is prefixed with the CBC IV. */
1679a8e1175bSopenharmony_ci        minlen += transform->ivlen;
1680a8e1175bSopenharmony_ci#endif
1681a8e1175bSopenharmony_ci
1682a8e1175bSopenharmony_ci        /* Size considerations:
1683a8e1175bSopenharmony_ci         *
1684a8e1175bSopenharmony_ci         * - The CBC cipher text must not be empty and hence
1685a8e1175bSopenharmony_ci         *   at least of size transform->ivlen.
1686a8e1175bSopenharmony_ci         *
1687a8e1175bSopenharmony_ci         * Together with the potential IV-prefix, this explains
1688a8e1175bSopenharmony_ci         * the first of the two checks below.
1689a8e1175bSopenharmony_ci         *
1690a8e1175bSopenharmony_ci         * - The record must contain a MAC, either in plain or
1691a8e1175bSopenharmony_ci         *   encrypted, depending on whether Encrypt-then-MAC
1692a8e1175bSopenharmony_ci         *   is used or not.
1693a8e1175bSopenharmony_ci         *   - If it is, the message contains the IV-prefix,
1694a8e1175bSopenharmony_ci         *     the CBC ciphertext, and the MAC.
1695a8e1175bSopenharmony_ci         *   - If it is not, the padded plaintext, and hence
1696a8e1175bSopenharmony_ci         *     the CBC ciphertext, has at least length maclen + 1
1697a8e1175bSopenharmony_ci         *     because there is at least the padding length byte.
1698a8e1175bSopenharmony_ci         *
1699a8e1175bSopenharmony_ci         * As the CBC ciphertext is not empty, both cases give the
1700a8e1175bSopenharmony_ci         * lower bound minlen + maclen + 1 on the record size, which
1701a8e1175bSopenharmony_ci         * we test for in the second check below.
1702a8e1175bSopenharmony_ci         */
1703a8e1175bSopenharmony_ci        if (rec->data_len < minlen + transform->ivlen ||
1704a8e1175bSopenharmony_ci            rec->data_len < minlen + transform->maclen + 1) {
1705a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1706a8e1175bSopenharmony_ci                                      ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
1707a8e1175bSopenharmony_ci                                      "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
1708a8e1175bSopenharmony_ci                                                                          "+ 1 ) ( + expl IV )",
1709a8e1175bSopenharmony_ci                                      rec->data_len,
1710a8e1175bSopenharmony_ci                                      transform->ivlen,
1711a8e1175bSopenharmony_ci                                      transform->maclen));
1712a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_MAC;
1713a8e1175bSopenharmony_ci        }
1714a8e1175bSopenharmony_ci
1715a8e1175bSopenharmony_ci        /*
1716a8e1175bSopenharmony_ci         * Authenticate before decrypt if enabled
1717a8e1175bSopenharmony_ci         */
1718a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1719a8e1175bSopenharmony_ci        if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
1720a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1721a8e1175bSopenharmony_ci            psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
1722a8e1175bSopenharmony_ci#else
1723a8e1175bSopenharmony_ci            unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
1724a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1725a8e1175bSopenharmony_ci
1726a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
1727a8e1175bSopenharmony_ci
1728a8e1175bSopenharmony_ci            /* Update data_len in tandem with add_data.
1729a8e1175bSopenharmony_ci             *
1730a8e1175bSopenharmony_ci             * The subtraction is safe because of the previous check
1731a8e1175bSopenharmony_ci             * data_len >= minlen + maclen + 1.
1732a8e1175bSopenharmony_ci             *
1733a8e1175bSopenharmony_ci             * Afterwards, we know that data + data_len is followed by at
1734a8e1175bSopenharmony_ci             * least maclen Bytes, which justifies the call to
1735a8e1175bSopenharmony_ci             * mbedtls_ct_memcmp() below.
1736a8e1175bSopenharmony_ci             *
1737a8e1175bSopenharmony_ci             * Further, we still know that data_len > minlen */
1738a8e1175bSopenharmony_ci            rec->data_len -= transform->maclen;
1739a8e1175bSopenharmony_ci            ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
1740a8e1175bSopenharmony_ci                                             transform->tls_version,
1741a8e1175bSopenharmony_ci                                             transform->taglen);
1742a8e1175bSopenharmony_ci
1743a8e1175bSopenharmony_ci            /* Calculate expected MAC. */
1744a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
1745a8e1175bSopenharmony_ci                                  add_data_len);
1746a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1747a8e1175bSopenharmony_ci            status = psa_mac_verify_setup(&operation, transform->psa_mac_dec,
1748a8e1175bSopenharmony_ci                                          transform->psa_mac_alg);
1749a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1750a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1751a8e1175bSopenharmony_ci            }
1752a8e1175bSopenharmony_ci
1753a8e1175bSopenharmony_ci            status = psa_mac_update(&operation, add_data, add_data_len);
1754a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1755a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1756a8e1175bSopenharmony_ci            }
1757a8e1175bSopenharmony_ci
1758a8e1175bSopenharmony_ci            status = psa_mac_update(&operation, data, rec->data_len);
1759a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1760a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1761a8e1175bSopenharmony_ci            }
1762a8e1175bSopenharmony_ci
1763a8e1175bSopenharmony_ci            /* Compare expected MAC with MAC at the end of the record. */
1764a8e1175bSopenharmony_ci            status = psa_mac_verify_finish(&operation, data + rec->data_len,
1765a8e1175bSopenharmony_ci                                           transform->maclen);
1766a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
1767a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1768a8e1175bSopenharmony_ci            }
1769a8e1175bSopenharmony_ci#else
1770a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data,
1771a8e1175bSopenharmony_ci                                         add_data_len);
1772a8e1175bSopenharmony_ci            if (ret != 0) {
1773a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1774a8e1175bSopenharmony_ci            }
1775a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_update(&transform->md_ctx_dec,
1776a8e1175bSopenharmony_ci                                         data, rec->data_len);
1777a8e1175bSopenharmony_ci            if (ret != 0) {
1778a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1779a8e1175bSopenharmony_ci            }
1780a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect);
1781a8e1175bSopenharmony_ci            if (ret != 0) {
1782a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1783a8e1175bSopenharmony_ci            }
1784a8e1175bSopenharmony_ci            ret = mbedtls_md_hmac_reset(&transform->md_ctx_dec);
1785a8e1175bSopenharmony_ci            if (ret != 0) {
1786a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1787a8e1175bSopenharmony_ci            }
1788a8e1175bSopenharmony_ci
1789a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(4, "message  mac", data + rec->data_len,
1790a8e1175bSopenharmony_ci                                  transform->maclen);
1791a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect,
1792a8e1175bSopenharmony_ci                                  transform->maclen);
1793a8e1175bSopenharmony_ci
1794a8e1175bSopenharmony_ci            /* Compare expected MAC with MAC at the end of the record. */
1795a8e1175bSopenharmony_ci            if (mbedtls_ct_memcmp(data + rec->data_len, mac_expect,
1796a8e1175bSopenharmony_ci                                  transform->maclen) != 0) {
1797a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
1798a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_INVALID_MAC;
1799a8e1175bSopenharmony_ci                goto hmac_failed_etm_enabled;
1800a8e1175bSopenharmony_ci            }
1801a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1802a8e1175bSopenharmony_ci            auth_done++;
1803a8e1175bSopenharmony_ci
1804a8e1175bSopenharmony_cihmac_failed_etm_enabled:
1805a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1806a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1807a8e1175bSopenharmony_ci            status = psa_mac_abort(&operation);
1808a8e1175bSopenharmony_ci            if (ret == 0 && status != PSA_SUCCESS) {
1809a8e1175bSopenharmony_ci                ret = PSA_TO_MBEDTLS_ERR(status);
1810a8e1175bSopenharmony_ci            }
1811a8e1175bSopenharmony_ci#else
1812a8e1175bSopenharmony_ci            mbedtls_platform_zeroize(mac_expect, transform->maclen);
1813a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1814a8e1175bSopenharmony_ci            if (ret != 0) {
1815a8e1175bSopenharmony_ci                if (ret != MBEDTLS_ERR_SSL_INVALID_MAC) {
1816a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_hmac_xxx", ret);
1817a8e1175bSopenharmony_ci                }
1818a8e1175bSopenharmony_ci                return ret;
1819a8e1175bSopenharmony_ci            }
1820a8e1175bSopenharmony_ci        }
1821a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
1822a8e1175bSopenharmony_ci
1823a8e1175bSopenharmony_ci        /*
1824a8e1175bSopenharmony_ci         * Check length sanity
1825a8e1175bSopenharmony_ci         */
1826a8e1175bSopenharmony_ci
1827a8e1175bSopenharmony_ci        /* We know from above that data_len > minlen >= 0,
1828a8e1175bSopenharmony_ci         * so the following check in particular implies that
1829a8e1175bSopenharmony_ci         * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
1830a8e1175bSopenharmony_ci        if (rec->data_len % transform->ivlen != 0) {
1831a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1832a8e1175bSopenharmony_ci                                      ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
1833a8e1175bSopenharmony_ci                                      rec->data_len, transform->ivlen));
1834a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_MAC;
1835a8e1175bSopenharmony_ci        }
1836a8e1175bSopenharmony_ci
1837a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1838a8e1175bSopenharmony_ci        /*
1839a8e1175bSopenharmony_ci         * Initialize for prepended IV for block cipher in TLS v1.2
1840a8e1175bSopenharmony_ci         */
1841a8e1175bSopenharmony_ci        /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
1842a8e1175bSopenharmony_ci        memcpy(transform->iv_dec, data, transform->ivlen);
1843a8e1175bSopenharmony_ci
1844a8e1175bSopenharmony_ci        data += transform->ivlen;
1845a8e1175bSopenharmony_ci        rec->data_offset += transform->ivlen;
1846a8e1175bSopenharmony_ci        rec->data_len -= transform->ivlen;
1847a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
1848a8e1175bSopenharmony_ci
1849a8e1175bSopenharmony_ci        /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
1850a8e1175bSopenharmony_ci
1851a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1852a8e1175bSopenharmony_ci        status = psa_cipher_decrypt_setup(&cipher_op,
1853a8e1175bSopenharmony_ci                                          transform->psa_key_dec, transform->psa_alg);
1854a8e1175bSopenharmony_ci
1855a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1856a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1857a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_decrypt_setup", ret);
1858a8e1175bSopenharmony_ci            return ret;
1859a8e1175bSopenharmony_ci        }
1860a8e1175bSopenharmony_ci
1861a8e1175bSopenharmony_ci        status = psa_cipher_set_iv(&cipher_op, transform->iv_dec, transform->ivlen);
1862a8e1175bSopenharmony_ci
1863a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1864a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1865a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
1866a8e1175bSopenharmony_ci            return ret;
1867a8e1175bSopenharmony_ci        }
1868a8e1175bSopenharmony_ci
1869a8e1175bSopenharmony_ci        status = psa_cipher_update(&cipher_op,
1870a8e1175bSopenharmony_ci                                   data, rec->data_len,
1871a8e1175bSopenharmony_ci                                   data, rec->data_len, &olen);
1872a8e1175bSopenharmony_ci
1873a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1874a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1875a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
1876a8e1175bSopenharmony_ci            return ret;
1877a8e1175bSopenharmony_ci        }
1878a8e1175bSopenharmony_ci
1879a8e1175bSopenharmony_ci        status = psa_cipher_finish(&cipher_op,
1880a8e1175bSopenharmony_ci                                   data + olen, rec->data_len - olen,
1881a8e1175bSopenharmony_ci                                   &part_len);
1882a8e1175bSopenharmony_ci
1883a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
1884a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
1885a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
1886a8e1175bSopenharmony_ci            return ret;
1887a8e1175bSopenharmony_ci        }
1888a8e1175bSopenharmony_ci
1889a8e1175bSopenharmony_ci        olen += part_len;
1890a8e1175bSopenharmony_ci#else
1891a8e1175bSopenharmony_ci
1892a8e1175bSopenharmony_ci        if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec,
1893a8e1175bSopenharmony_ci                                        transform->iv_dec, transform->ivlen,
1894a8e1175bSopenharmony_ci                                        data, rec->data_len, data, &olen)) != 0) {
1895a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
1896a8e1175bSopenharmony_ci            return ret;
1897a8e1175bSopenharmony_ci        }
1898a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1899a8e1175bSopenharmony_ci
1900a8e1175bSopenharmony_ci        /* Double-check that length hasn't changed during decryption. */
1901a8e1175bSopenharmony_ci        if (rec->data_len != olen) {
1902a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1903a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1904a8e1175bSopenharmony_ci        }
1905a8e1175bSopenharmony_ci
1906a8e1175bSopenharmony_ci        /* Safe since data_len >= minlen + maclen + 1, so after having
1907a8e1175bSopenharmony_ci         * subtracted at most minlen and maclen up to this point,
1908a8e1175bSopenharmony_ci         * data_len > 0 (because of data_len % ivlen == 0, it's actually
1909a8e1175bSopenharmony_ci         * >= ivlen ). */
1910a8e1175bSopenharmony_ci        padlen = data[rec->data_len - 1];
1911a8e1175bSopenharmony_ci
1912a8e1175bSopenharmony_ci        if (auth_done == 1) {
1913a8e1175bSopenharmony_ci            const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
1914a8e1175bSopenharmony_ci                rec->data_len,
1915a8e1175bSopenharmony_ci                padlen + 1);
1916a8e1175bSopenharmony_ci            correct = mbedtls_ct_bool_and(ge, correct);
1917a8e1175bSopenharmony_ci            padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
1918a8e1175bSopenharmony_ci        } else {
1919a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL)
1920a8e1175bSopenharmony_ci            if (rec->data_len < transform->maclen + padlen + 1) {
1921a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
1922a8e1175bSopenharmony_ci                                          ") < maclen (%" MBEDTLS_PRINTF_SIZET
1923a8e1175bSopenharmony_ci                                          ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
1924a8e1175bSopenharmony_ci                                          rec->data_len,
1925a8e1175bSopenharmony_ci                                          transform->maclen,
1926a8e1175bSopenharmony_ci                                          padlen + 1));
1927a8e1175bSopenharmony_ci            }
1928a8e1175bSopenharmony_ci#endif
1929a8e1175bSopenharmony_ci            const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
1930a8e1175bSopenharmony_ci                rec->data_len,
1931a8e1175bSopenharmony_ci                transform->maclen + padlen + 1);
1932a8e1175bSopenharmony_ci            correct = mbedtls_ct_bool_and(ge, correct);
1933a8e1175bSopenharmony_ci            padlen  = mbedtls_ct_size_if_else_0(ge, padlen);
1934a8e1175bSopenharmony_ci        }
1935a8e1175bSopenharmony_ci
1936a8e1175bSopenharmony_ci        padlen++;
1937a8e1175bSopenharmony_ci
1938a8e1175bSopenharmony_ci        /* Regardless of the validity of the padding,
1939a8e1175bSopenharmony_ci         * we have data_len >= padlen here. */
1940a8e1175bSopenharmony_ci
1941a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
1942a8e1175bSopenharmony_ci        /* The padding check involves a series of up to 256
1943a8e1175bSopenharmony_ci         * consecutive memory reads at the end of the record
1944a8e1175bSopenharmony_ci         * plaintext buffer. In order to hide the length and
1945a8e1175bSopenharmony_ci         * validity of the padding, always perform exactly
1946a8e1175bSopenharmony_ci         * `min(256,plaintext_len)` reads (but take into account
1947a8e1175bSopenharmony_ci         * only the last `padlen` bytes for the padding check). */
1948a8e1175bSopenharmony_ci        size_t pad_count = 0;
1949a8e1175bSopenharmony_ci        volatile unsigned char * const check = data;
1950a8e1175bSopenharmony_ci
1951a8e1175bSopenharmony_ci        /* Index of first padding byte; it has been ensured above
1952a8e1175bSopenharmony_ci         * that the subtraction is safe. */
1953a8e1175bSopenharmony_ci        size_t const padding_idx = rec->data_len - padlen;
1954a8e1175bSopenharmony_ci        size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
1955a8e1175bSopenharmony_ci        size_t const start_idx = rec->data_len - num_checks;
1956a8e1175bSopenharmony_ci        size_t idx;
1957a8e1175bSopenharmony_ci
1958a8e1175bSopenharmony_ci        for (idx = start_idx; idx < rec->data_len; idx++) {
1959a8e1175bSopenharmony_ci            /* pad_count += (idx >= padding_idx) &&
1960a8e1175bSopenharmony_ci             *              (check[idx] == padlen - 1);
1961a8e1175bSopenharmony_ci             */
1962a8e1175bSopenharmony_ci            const mbedtls_ct_condition_t a = mbedtls_ct_uint_ge(idx, padding_idx);
1963a8e1175bSopenharmony_ci            size_t increment = mbedtls_ct_size_if_else_0(a, 1);
1964a8e1175bSopenharmony_ci            const mbedtls_ct_condition_t b = mbedtls_ct_uint_eq(check[idx], padlen - 1);
1965a8e1175bSopenharmony_ci            increment = mbedtls_ct_size_if_else_0(b, increment);
1966a8e1175bSopenharmony_ci            pad_count += increment;
1967a8e1175bSopenharmony_ci        }
1968a8e1175bSopenharmony_ci        correct = mbedtls_ct_bool_and(mbedtls_ct_uint_eq(pad_count, padlen), correct);
1969a8e1175bSopenharmony_ci
1970a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL)
1971a8e1175bSopenharmony_ci        if (padlen > 0 && correct == MBEDTLS_CT_FALSE) {
1972a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
1973a8e1175bSopenharmony_ci        }
1974a8e1175bSopenharmony_ci#endif
1975a8e1175bSopenharmony_ci        padlen = mbedtls_ct_size_if_else_0(correct, padlen);
1976a8e1175bSopenharmony_ci
1977a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
1978a8e1175bSopenharmony_ci
1979a8e1175bSopenharmony_ci        /* If the padding was found to be invalid, padlen == 0
1980a8e1175bSopenharmony_ci         * and the subtraction is safe. If the padding was found valid,
1981a8e1175bSopenharmony_ci         * padlen hasn't been changed and the previous assertion
1982a8e1175bSopenharmony_ci         * data_len >= padlen still holds. */
1983a8e1175bSopenharmony_ci        rec->data_len -= padlen;
1984a8e1175bSopenharmony_ci    } else
1985a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
1986a8e1175bSopenharmony_ci    {
1987a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1988a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1989a8e1175bSopenharmony_ci    }
1990a8e1175bSopenharmony_ci
1991a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL)
1992a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption",
1993a8e1175bSopenharmony_ci                          data, rec->data_len);
1994a8e1175bSopenharmony_ci#endif
1995a8e1175bSopenharmony_ci
1996a8e1175bSopenharmony_ci    /*
1997a8e1175bSopenharmony_ci     * Authenticate if not done yet.
1998a8e1175bSopenharmony_ci     * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
1999a8e1175bSopenharmony_ci     */
2000a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
2001a8e1175bSopenharmony_ci    if (auth_done == 0) {
2002a8e1175bSopenharmony_ci        unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
2003a8e1175bSopenharmony_ci        unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
2004a8e1175bSopenharmony_ci
2005a8e1175bSopenharmony_ci        /* For CBC+MAC, If the initial value of padlen was such that
2006a8e1175bSopenharmony_ci         * data_len < maclen + padlen + 1, then padlen
2007a8e1175bSopenharmony_ci         * got reset to 1, and the initial check
2008a8e1175bSopenharmony_ci         * data_len >= minlen + maclen + 1
2009a8e1175bSopenharmony_ci         * guarantees that at this point we still
2010a8e1175bSopenharmony_ci         * have at least data_len >= maclen.
2011a8e1175bSopenharmony_ci         *
2012a8e1175bSopenharmony_ci         * If the initial value of padlen was such that
2013a8e1175bSopenharmony_ci         * data_len >= maclen + padlen + 1, then we have
2014a8e1175bSopenharmony_ci         * subtracted either padlen + 1 (if the padding was correct)
2015a8e1175bSopenharmony_ci         * or 0 (if the padding was incorrect) since then,
2016a8e1175bSopenharmony_ci         * hence data_len >= maclen in any case.
2017a8e1175bSopenharmony_ci         *
2018a8e1175bSopenharmony_ci         * For stream ciphers, we checked above that
2019a8e1175bSopenharmony_ci         * data_len >= maclen.
2020a8e1175bSopenharmony_ci         */
2021a8e1175bSopenharmony_ci        rec->data_len -= transform->maclen;
2022a8e1175bSopenharmony_ci        ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
2023a8e1175bSopenharmony_ci                                         transform->tls_version,
2024a8e1175bSopenharmony_ci                                         transform->taglen);
2025a8e1175bSopenharmony_ci
2026a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
2027a8e1175bSopenharmony_ci        /*
2028a8e1175bSopenharmony_ci         * The next two sizes are the minimum and maximum values of
2029a8e1175bSopenharmony_ci         * data_len over all padlen values.
2030a8e1175bSopenharmony_ci         *
2031a8e1175bSopenharmony_ci         * They're independent of padlen, since we previously did
2032a8e1175bSopenharmony_ci         * data_len -= padlen.
2033a8e1175bSopenharmony_ci         *
2034a8e1175bSopenharmony_ci         * Note that max_len + maclen is never more than the buffer
2035a8e1175bSopenharmony_ci         * length, as we previously did in_msglen -= maclen too.
2036a8e1175bSopenharmony_ci         */
2037a8e1175bSopenharmony_ci        const size_t max_len = rec->data_len + padlen;
2038a8e1175bSopenharmony_ci        const size_t min_len = (max_len > 256) ? max_len - 256 : 0;
2039a8e1175bSopenharmony_ci
2040a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
2041a8e1175bSopenharmony_ci        ret = mbedtls_ct_hmac(transform->psa_mac_dec,
2042a8e1175bSopenharmony_ci                              transform->psa_mac_alg,
2043a8e1175bSopenharmony_ci                              add_data, add_data_len,
2044a8e1175bSopenharmony_ci                              data, rec->data_len, min_len, max_len,
2045a8e1175bSopenharmony_ci                              mac_expect);
2046a8e1175bSopenharmony_ci#else
2047a8e1175bSopenharmony_ci        ret = mbedtls_ct_hmac(&transform->md_ctx_dec,
2048a8e1175bSopenharmony_ci                              add_data, add_data_len,
2049a8e1175bSopenharmony_ci                              data, rec->data_len, min_len, max_len,
2050a8e1175bSopenharmony_ci                              mac_expect);
2051a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
2052a8e1175bSopenharmony_ci        if (ret != 0) {
2053a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ct_hmac", ret);
2054a8e1175bSopenharmony_ci            goto hmac_failed_etm_disabled;
2055a8e1175bSopenharmony_ci        }
2056a8e1175bSopenharmony_ci
2057a8e1175bSopenharmony_ci        mbedtls_ct_memcpy_offset(mac_peer, data,
2058a8e1175bSopenharmony_ci                                 rec->data_len,
2059a8e1175bSopenharmony_ci                                 min_len, max_len,
2060a8e1175bSopenharmony_ci                                 transform->maclen);
2061a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
2062a8e1175bSopenharmony_ci
2063a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL)
2064a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen);
2065a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "message  mac", mac_peer, transform->maclen);
2066a8e1175bSopenharmony_ci#endif
2067a8e1175bSopenharmony_ci
2068a8e1175bSopenharmony_ci        if (mbedtls_ct_memcmp(mac_peer, mac_expect,
2069a8e1175bSopenharmony_ci                              transform->maclen) != 0) {
2070a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL)
2071a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
2072a8e1175bSopenharmony_ci#endif
2073a8e1175bSopenharmony_ci            correct = MBEDTLS_CT_FALSE;
2074a8e1175bSopenharmony_ci        }
2075a8e1175bSopenharmony_ci        auth_done++;
2076a8e1175bSopenharmony_ci
2077a8e1175bSopenharmony_cihmac_failed_etm_disabled:
2078a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(mac_peer, transform->maclen);
2079a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(mac_expect, transform->maclen);
2080a8e1175bSopenharmony_ci        if (ret != 0) {
2081a8e1175bSopenharmony_ci            return ret;
2082a8e1175bSopenharmony_ci        }
2083a8e1175bSopenharmony_ci    }
2084a8e1175bSopenharmony_ci
2085a8e1175bSopenharmony_ci    /*
2086a8e1175bSopenharmony_ci     * Finally check the correct flag
2087a8e1175bSopenharmony_ci     */
2088a8e1175bSopenharmony_ci    if (correct == MBEDTLS_CT_FALSE) {
2089a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_MAC;
2090a8e1175bSopenharmony_ci    }
2091a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
2092a8e1175bSopenharmony_ci
2093a8e1175bSopenharmony_ci    /* Make extra sure authentication was performed, exactly once */
2094a8e1175bSopenharmony_ci    if (auth_done != 1) {
2095a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2096a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2097a8e1175bSopenharmony_ci    }
2098a8e1175bSopenharmony_ci
2099a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2100a8e1175bSopenharmony_ci    if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
2101a8e1175bSopenharmony_ci        /* Remove inner padding and infer true content type. */
2102a8e1175bSopenharmony_ci        ret = ssl_parse_inner_plaintext(data, &rec->data_len,
2103a8e1175bSopenharmony_ci                                        &rec->type);
2104a8e1175bSopenharmony_ci
2105a8e1175bSopenharmony_ci        if (ret != 0) {
2106a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
2107a8e1175bSopenharmony_ci        }
2108a8e1175bSopenharmony_ci    }
2109a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2110a8e1175bSopenharmony_ci
2111a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2112a8e1175bSopenharmony_ci    if (rec->cid_len != 0) {
2113a8e1175bSopenharmony_ci        ret = ssl_parse_inner_plaintext(data, &rec->data_len,
2114a8e1175bSopenharmony_ci                                        &rec->type);
2115a8e1175bSopenharmony_ci        if (ret != 0) {
2116a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
2117a8e1175bSopenharmony_ci        }
2118a8e1175bSopenharmony_ci    }
2119a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2120a8e1175bSopenharmony_ci
2121a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf"));
2122a8e1175bSopenharmony_ci
2123a8e1175bSopenharmony_ci    return 0;
2124a8e1175bSopenharmony_ci}
2125a8e1175bSopenharmony_ci
2126a8e1175bSopenharmony_ci#undef MAC_NONE
2127a8e1175bSopenharmony_ci#undef MAC_PLAINTEXT
2128a8e1175bSopenharmony_ci#undef MAC_CIPHERTEXT
2129a8e1175bSopenharmony_ci
2130a8e1175bSopenharmony_ci/*
2131a8e1175bSopenharmony_ci * Fill the input message buffer by appending data to it.
2132a8e1175bSopenharmony_ci * The amount of data already fetched is in ssl->in_left.
2133a8e1175bSopenharmony_ci *
2134a8e1175bSopenharmony_ci * If we return 0, is it guaranteed that (at least) nb_want bytes are
2135a8e1175bSopenharmony_ci * available (from this read and/or a previous one). Otherwise, an error code
2136a8e1175bSopenharmony_ci * is returned (possibly EOF or WANT_READ).
2137a8e1175bSopenharmony_ci *
2138a8e1175bSopenharmony_ci * With stream transport (TLS) on success ssl->in_left == nb_want, but
2139a8e1175bSopenharmony_ci * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
2140a8e1175bSopenharmony_ci * since we always read a whole datagram at once.
2141a8e1175bSopenharmony_ci *
2142a8e1175bSopenharmony_ci * For DTLS, it is up to the caller to set ssl->next_record_offset when
2143a8e1175bSopenharmony_ci * they're done reading a record.
2144a8e1175bSopenharmony_ci */
2145a8e1175bSopenharmony_ciint mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
2146a8e1175bSopenharmony_ci{
2147a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2148a8e1175bSopenharmony_ci    size_t len;
2149a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2150a8e1175bSopenharmony_ci    size_t in_buf_len = ssl->in_buf_len;
2151a8e1175bSopenharmony_ci#else
2152a8e1175bSopenharmony_ci    size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
2153a8e1175bSopenharmony_ci#endif
2154a8e1175bSopenharmony_ci
2155a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input"));
2156a8e1175bSopenharmony_ci
2157a8e1175bSopenharmony_ci    if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) {
2158a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
2159a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2160a8e1175bSopenharmony_ci    }
2161a8e1175bSopenharmony_ci
2162a8e1175bSopenharmony_ci    if (nb_want > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
2163a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits"));
2164a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2165a8e1175bSopenharmony_ci    }
2166a8e1175bSopenharmony_ci
2167a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2168a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
2169a8e1175bSopenharmony_ci        uint32_t timeout;
2170a8e1175bSopenharmony_ci
2171a8e1175bSopenharmony_ci        /*
2172a8e1175bSopenharmony_ci         * The point is, we need to always read a full datagram at once, so we
2173a8e1175bSopenharmony_ci         * sometimes read more then requested, and handle the additional data.
2174a8e1175bSopenharmony_ci         * It could be the rest of the current record (while fetching the
2175a8e1175bSopenharmony_ci         * header) and/or some other records in the same datagram.
2176a8e1175bSopenharmony_ci         */
2177a8e1175bSopenharmony_ci
2178a8e1175bSopenharmony_ci        /*
2179a8e1175bSopenharmony_ci         * Move to the next record in the already read datagram if applicable
2180a8e1175bSopenharmony_ci         */
2181a8e1175bSopenharmony_ci        if (ssl->next_record_offset != 0) {
2182a8e1175bSopenharmony_ci            if (ssl->in_left < ssl->next_record_offset) {
2183a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2184a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2185a8e1175bSopenharmony_ci            }
2186a8e1175bSopenharmony_ci
2187a8e1175bSopenharmony_ci            ssl->in_left -= ssl->next_record_offset;
2188a8e1175bSopenharmony_ci
2189a8e1175bSopenharmony_ci            if (ssl->in_left != 0) {
2190a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("next record in same datagram, offset: %"
2191a8e1175bSopenharmony_ci                                          MBEDTLS_PRINTF_SIZET,
2192a8e1175bSopenharmony_ci                                          ssl->next_record_offset));
2193a8e1175bSopenharmony_ci                memmove(ssl->in_hdr,
2194a8e1175bSopenharmony_ci                        ssl->in_hdr + ssl->next_record_offset,
2195a8e1175bSopenharmony_ci                        ssl->in_left);
2196a8e1175bSopenharmony_ci            }
2197a8e1175bSopenharmony_ci
2198a8e1175bSopenharmony_ci            ssl->next_record_offset = 0;
2199a8e1175bSopenharmony_ci        }
2200a8e1175bSopenharmony_ci
2201a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
2202a8e1175bSopenharmony_ci                                  ", nb_want: %" MBEDTLS_PRINTF_SIZET,
2203a8e1175bSopenharmony_ci                                  ssl->in_left, nb_want));
2204a8e1175bSopenharmony_ci
2205a8e1175bSopenharmony_ci        /*
2206a8e1175bSopenharmony_ci         * Done if we already have enough data.
2207a8e1175bSopenharmony_ci         */
2208a8e1175bSopenharmony_ci        if (nb_want <= ssl->in_left) {
2209a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
2210a8e1175bSopenharmony_ci            return 0;
2211a8e1175bSopenharmony_ci        }
2212a8e1175bSopenharmony_ci
2213a8e1175bSopenharmony_ci        /*
2214a8e1175bSopenharmony_ci         * A record can't be split across datagrams. If we need to read but
2215a8e1175bSopenharmony_ci         * are not at the beginning of a new record, the caller did something
2216a8e1175bSopenharmony_ci         * wrong.
2217a8e1175bSopenharmony_ci         */
2218a8e1175bSopenharmony_ci        if (ssl->in_left != 0) {
2219a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2220a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2221a8e1175bSopenharmony_ci        }
2222a8e1175bSopenharmony_ci
2223a8e1175bSopenharmony_ci        /*
2224a8e1175bSopenharmony_ci         * Don't even try to read if time's out already.
2225a8e1175bSopenharmony_ci         * This avoids by-passing the timer when repeatedly receiving messages
2226a8e1175bSopenharmony_ci         * that will end up being dropped.
2227a8e1175bSopenharmony_ci         */
2228a8e1175bSopenharmony_ci        if (mbedtls_ssl_check_timer(ssl) != 0) {
2229a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired"));
2230a8e1175bSopenharmony_ci            ret = MBEDTLS_ERR_SSL_TIMEOUT;
2231a8e1175bSopenharmony_ci        } else {
2232a8e1175bSopenharmony_ci            len = in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf);
2233a8e1175bSopenharmony_ci
2234a8e1175bSopenharmony_ci            if (mbedtls_ssl_is_handshake_over(ssl) == 0) {
2235a8e1175bSopenharmony_ci                timeout = ssl->handshake->retransmit_timeout;
2236a8e1175bSopenharmony_ci            } else {
2237a8e1175bSopenharmony_ci                timeout = ssl->conf->read_timeout;
2238a8e1175bSopenharmony_ci            }
2239a8e1175bSopenharmony_ci
2240a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms", (unsigned long) timeout));
2241a8e1175bSopenharmony_ci
2242a8e1175bSopenharmony_ci            if (ssl->f_recv_timeout != NULL) {
2243a8e1175bSopenharmony_ci                ret = ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len,
2244a8e1175bSopenharmony_ci                                          timeout);
2245a8e1175bSopenharmony_ci            } else {
2246a8e1175bSopenharmony_ci                ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len);
2247a8e1175bSopenharmony_ci            }
2248a8e1175bSopenharmony_ci
2249a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
2250a8e1175bSopenharmony_ci
2251a8e1175bSopenharmony_ci            if (ret == 0) {
2252a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_CONN_EOF;
2253a8e1175bSopenharmony_ci            }
2254a8e1175bSopenharmony_ci        }
2255a8e1175bSopenharmony_ci
2256a8e1175bSopenharmony_ci        if (ret == MBEDTLS_ERR_SSL_TIMEOUT) {
2257a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("timeout"));
2258a8e1175bSopenharmony_ci            mbedtls_ssl_set_timer(ssl, 0);
2259a8e1175bSopenharmony_ci
2260a8e1175bSopenharmony_ci            if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
2261a8e1175bSopenharmony_ci                if (ssl_double_retransmit_timeout(ssl) != 0) {
2262a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout"));
2263a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_SSL_TIMEOUT;
2264a8e1175bSopenharmony_ci                }
2265a8e1175bSopenharmony_ci
2266a8e1175bSopenharmony_ci                if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
2267a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
2268a8e1175bSopenharmony_ci                    return ret;
2269a8e1175bSopenharmony_ci                }
2270a8e1175bSopenharmony_ci
2271a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_WANT_READ;
2272a8e1175bSopenharmony_ci            }
2273a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
2274a8e1175bSopenharmony_ci            else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
2275a8e1175bSopenharmony_ci                     ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
2276a8e1175bSopenharmony_ci                if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
2277a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
2278a8e1175bSopenharmony_ci                                          ret);
2279a8e1175bSopenharmony_ci                    return ret;
2280a8e1175bSopenharmony_ci                }
2281a8e1175bSopenharmony_ci
2282a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_WANT_READ;
2283a8e1175bSopenharmony_ci            }
2284a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
2285a8e1175bSopenharmony_ci        }
2286a8e1175bSopenharmony_ci
2287a8e1175bSopenharmony_ci        if (ret < 0) {
2288a8e1175bSopenharmony_ci            return ret;
2289a8e1175bSopenharmony_ci        }
2290a8e1175bSopenharmony_ci
2291a8e1175bSopenharmony_ci        ssl->in_left = ret;
2292a8e1175bSopenharmony_ci    } else
2293a8e1175bSopenharmony_ci#endif
2294a8e1175bSopenharmony_ci    {
2295a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
2296a8e1175bSopenharmony_ci                                  ", nb_want: %" MBEDTLS_PRINTF_SIZET,
2297a8e1175bSopenharmony_ci                                  ssl->in_left, nb_want));
2298a8e1175bSopenharmony_ci
2299a8e1175bSopenharmony_ci        while (ssl->in_left < nb_want) {
2300a8e1175bSopenharmony_ci            len = nb_want - ssl->in_left;
2301a8e1175bSopenharmony_ci
2302a8e1175bSopenharmony_ci            if (mbedtls_ssl_check_timer(ssl) != 0) {
2303a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_TIMEOUT;
2304a8e1175bSopenharmony_ci            } else {
2305a8e1175bSopenharmony_ci                if (ssl->f_recv_timeout != NULL) {
2306a8e1175bSopenharmony_ci                    ret = ssl->f_recv_timeout(ssl->p_bio,
2307a8e1175bSopenharmony_ci                                              ssl->in_hdr + ssl->in_left, len,
2308a8e1175bSopenharmony_ci                                              ssl->conf->read_timeout);
2309a8e1175bSopenharmony_ci                } else {
2310a8e1175bSopenharmony_ci                    ret = ssl->f_recv(ssl->p_bio,
2311a8e1175bSopenharmony_ci                                      ssl->in_hdr + ssl->in_left, len);
2312a8e1175bSopenharmony_ci                }
2313a8e1175bSopenharmony_ci            }
2314a8e1175bSopenharmony_ci
2315a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
2316a8e1175bSopenharmony_ci                                      ", nb_want: %" MBEDTLS_PRINTF_SIZET,
2317a8e1175bSopenharmony_ci                                      ssl->in_left, nb_want));
2318a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
2319a8e1175bSopenharmony_ci
2320a8e1175bSopenharmony_ci            if (ret == 0) {
2321a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_CONN_EOF;
2322a8e1175bSopenharmony_ci            }
2323a8e1175bSopenharmony_ci
2324a8e1175bSopenharmony_ci            if (ret < 0) {
2325a8e1175bSopenharmony_ci                return ret;
2326a8e1175bSopenharmony_ci            }
2327a8e1175bSopenharmony_ci
2328a8e1175bSopenharmony_ci            if ((size_t) ret > len) {
2329a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1,
2330a8e1175bSopenharmony_ci                                      ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
2331a8e1175bSopenharmony_ci                                       " were requested",
2332a8e1175bSopenharmony_ci                                       ret, len));
2333a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2334a8e1175bSopenharmony_ci            }
2335a8e1175bSopenharmony_ci
2336a8e1175bSopenharmony_ci            ssl->in_left += ret;
2337a8e1175bSopenharmony_ci        }
2338a8e1175bSopenharmony_ci    }
2339a8e1175bSopenharmony_ci
2340a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
2341a8e1175bSopenharmony_ci
2342a8e1175bSopenharmony_ci    return 0;
2343a8e1175bSopenharmony_ci}
2344a8e1175bSopenharmony_ci
2345a8e1175bSopenharmony_ci/*
2346a8e1175bSopenharmony_ci * Flush any data not yet written
2347a8e1175bSopenharmony_ci */
2348a8e1175bSopenharmony_ciint mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
2349a8e1175bSopenharmony_ci{
2350a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2351a8e1175bSopenharmony_ci    unsigned char *buf;
2352a8e1175bSopenharmony_ci
2353a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output"));
2354a8e1175bSopenharmony_ci
2355a8e1175bSopenharmony_ci    if (ssl->f_send == NULL) {
2356a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
2357a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2358a8e1175bSopenharmony_ci    }
2359a8e1175bSopenharmony_ci
2360a8e1175bSopenharmony_ci    /* Avoid incrementing counter if data is flushed */
2361a8e1175bSopenharmony_ci    if (ssl->out_left == 0) {
2362a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
2363a8e1175bSopenharmony_ci        return 0;
2364a8e1175bSopenharmony_ci    }
2365a8e1175bSopenharmony_ci
2366a8e1175bSopenharmony_ci    while (ssl->out_left > 0) {
2367a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("message length: %" MBEDTLS_PRINTF_SIZET
2368a8e1175bSopenharmony_ci                                  ", out_left: %" MBEDTLS_PRINTF_SIZET,
2369a8e1175bSopenharmony_ci                                  mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left));
2370a8e1175bSopenharmony_ci
2371a8e1175bSopenharmony_ci        buf = ssl->out_hdr - ssl->out_left;
2372a8e1175bSopenharmony_ci        ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left);
2373a8e1175bSopenharmony_ci
2374a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret);
2375a8e1175bSopenharmony_ci
2376a8e1175bSopenharmony_ci        if (ret <= 0) {
2377a8e1175bSopenharmony_ci            return ret;
2378a8e1175bSopenharmony_ci        }
2379a8e1175bSopenharmony_ci
2380a8e1175bSopenharmony_ci        if ((size_t) ret > ssl->out_left) {
2381a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
2382a8e1175bSopenharmony_ci                                  ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
2383a8e1175bSopenharmony_ci                                   " bytes were sent",
2384a8e1175bSopenharmony_ci                                   ret, ssl->out_left));
2385a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2386a8e1175bSopenharmony_ci        }
2387a8e1175bSopenharmony_ci
2388a8e1175bSopenharmony_ci        ssl->out_left -= ret;
2389a8e1175bSopenharmony_ci    }
2390a8e1175bSopenharmony_ci
2391a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2392a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
2393a8e1175bSopenharmony_ci        ssl->out_hdr = ssl->out_buf;
2394a8e1175bSopenharmony_ci    } else
2395a8e1175bSopenharmony_ci#endif
2396a8e1175bSopenharmony_ci    {
2397a8e1175bSopenharmony_ci        ssl->out_hdr = ssl->out_buf + 8;
2398a8e1175bSopenharmony_ci    }
2399a8e1175bSopenharmony_ci    mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
2400a8e1175bSopenharmony_ci
2401a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
2402a8e1175bSopenharmony_ci
2403a8e1175bSopenharmony_ci    return 0;
2404a8e1175bSopenharmony_ci}
2405a8e1175bSopenharmony_ci
2406a8e1175bSopenharmony_ci/*
2407a8e1175bSopenharmony_ci * Functions to handle the DTLS retransmission state machine
2408a8e1175bSopenharmony_ci */
2409a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2410a8e1175bSopenharmony_ci/*
2411a8e1175bSopenharmony_ci * Append current handshake message to current outgoing flight
2412a8e1175bSopenharmony_ci */
2413a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2414a8e1175bSopenharmony_cistatic int ssl_flight_append(mbedtls_ssl_context *ssl)
2415a8e1175bSopenharmony_ci{
2416a8e1175bSopenharmony_ci    mbedtls_ssl_flight_item *msg;
2417a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append"));
2418a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight",
2419a8e1175bSopenharmony_ci                          ssl->out_msg, ssl->out_msglen);
2420a8e1175bSopenharmony_ci
2421a8e1175bSopenharmony_ci    /* Allocate space for current message */
2422a8e1175bSopenharmony_ci    if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) {
2423a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
2424a8e1175bSopenharmony_ci                                  sizeof(mbedtls_ssl_flight_item)));
2425a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
2426a8e1175bSopenharmony_ci    }
2427a8e1175bSopenharmony_ci
2428a8e1175bSopenharmony_ci    if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) {
2429a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
2430a8e1175bSopenharmony_ci                                  ssl->out_msglen));
2431a8e1175bSopenharmony_ci        mbedtls_free(msg);
2432a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
2433a8e1175bSopenharmony_ci    }
2434a8e1175bSopenharmony_ci
2435a8e1175bSopenharmony_ci    /* Copy current handshake message with headers */
2436a8e1175bSopenharmony_ci    memcpy(msg->p, ssl->out_msg, ssl->out_msglen);
2437a8e1175bSopenharmony_ci    msg->len = ssl->out_msglen;
2438a8e1175bSopenharmony_ci    msg->type = ssl->out_msgtype;
2439a8e1175bSopenharmony_ci    msg->next = NULL;
2440a8e1175bSopenharmony_ci
2441a8e1175bSopenharmony_ci    /* Append to the current flight */
2442a8e1175bSopenharmony_ci    if (ssl->handshake->flight == NULL) {
2443a8e1175bSopenharmony_ci        ssl->handshake->flight = msg;
2444a8e1175bSopenharmony_ci    } else {
2445a8e1175bSopenharmony_ci        mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
2446a8e1175bSopenharmony_ci        while (cur->next != NULL) {
2447a8e1175bSopenharmony_ci            cur = cur->next;
2448a8e1175bSopenharmony_ci        }
2449a8e1175bSopenharmony_ci        cur->next = msg;
2450a8e1175bSopenharmony_ci    }
2451a8e1175bSopenharmony_ci
2452a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append"));
2453a8e1175bSopenharmony_ci    return 0;
2454a8e1175bSopenharmony_ci}
2455a8e1175bSopenharmony_ci
2456a8e1175bSopenharmony_ci/*
2457a8e1175bSopenharmony_ci * Free the current flight of handshake messages
2458a8e1175bSopenharmony_ci */
2459a8e1175bSopenharmony_civoid mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight)
2460a8e1175bSopenharmony_ci{
2461a8e1175bSopenharmony_ci    mbedtls_ssl_flight_item *cur = flight;
2462a8e1175bSopenharmony_ci    mbedtls_ssl_flight_item *next;
2463a8e1175bSopenharmony_ci
2464a8e1175bSopenharmony_ci    while (cur != NULL) {
2465a8e1175bSopenharmony_ci        next = cur->next;
2466a8e1175bSopenharmony_ci
2467a8e1175bSopenharmony_ci        mbedtls_free(cur->p);
2468a8e1175bSopenharmony_ci        mbedtls_free(cur);
2469a8e1175bSopenharmony_ci
2470a8e1175bSopenharmony_ci        cur = next;
2471a8e1175bSopenharmony_ci    }
2472a8e1175bSopenharmony_ci}
2473a8e1175bSopenharmony_ci
2474a8e1175bSopenharmony_ci/*
2475a8e1175bSopenharmony_ci * Swap transform_out and out_ctr with the alternative ones
2476a8e1175bSopenharmony_ci */
2477a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2478a8e1175bSopenharmony_cistatic int ssl_swap_epochs(mbedtls_ssl_context *ssl)
2479a8e1175bSopenharmony_ci{
2480a8e1175bSopenharmony_ci    mbedtls_ssl_transform *tmp_transform;
2481a8e1175bSopenharmony_ci    unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
2482a8e1175bSopenharmony_ci
2483a8e1175bSopenharmony_ci    if (ssl->transform_out == ssl->handshake->alt_transform_out) {
2484a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs"));
2485a8e1175bSopenharmony_ci        return 0;
2486a8e1175bSopenharmony_ci    }
2487a8e1175bSopenharmony_ci
2488a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs"));
2489a8e1175bSopenharmony_ci
2490a8e1175bSopenharmony_ci    /* Swap transforms */
2491a8e1175bSopenharmony_ci    tmp_transform                     = ssl->transform_out;
2492a8e1175bSopenharmony_ci    ssl->transform_out                = ssl->handshake->alt_transform_out;
2493a8e1175bSopenharmony_ci    ssl->handshake->alt_transform_out = tmp_transform;
2494a8e1175bSopenharmony_ci
2495a8e1175bSopenharmony_ci    /* Swap epoch + sequence_number */
2496a8e1175bSopenharmony_ci    memcpy(tmp_out_ctr, ssl->cur_out_ctr, sizeof(tmp_out_ctr));
2497a8e1175bSopenharmony_ci    memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
2498a8e1175bSopenharmony_ci           sizeof(ssl->cur_out_ctr));
2499a8e1175bSopenharmony_ci    memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr,
2500a8e1175bSopenharmony_ci           sizeof(ssl->handshake->alt_out_ctr));
2501a8e1175bSopenharmony_ci
2502a8e1175bSopenharmony_ci    /* Adjust to the newly activated transform */
2503a8e1175bSopenharmony_ci    mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
2504a8e1175bSopenharmony_ci
2505a8e1175bSopenharmony_ci    return 0;
2506a8e1175bSopenharmony_ci}
2507a8e1175bSopenharmony_ci
2508a8e1175bSopenharmony_ci/*
2509a8e1175bSopenharmony_ci * Retransmit the current flight of messages.
2510a8e1175bSopenharmony_ci */
2511a8e1175bSopenharmony_ciint mbedtls_ssl_resend(mbedtls_ssl_context *ssl)
2512a8e1175bSopenharmony_ci{
2513a8e1175bSopenharmony_ci    int ret = 0;
2514a8e1175bSopenharmony_ci
2515a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend"));
2516a8e1175bSopenharmony_ci
2517a8e1175bSopenharmony_ci    ret = mbedtls_ssl_flight_transmit(ssl);
2518a8e1175bSopenharmony_ci
2519a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend"));
2520a8e1175bSopenharmony_ci
2521a8e1175bSopenharmony_ci    return ret;
2522a8e1175bSopenharmony_ci}
2523a8e1175bSopenharmony_ci
2524a8e1175bSopenharmony_ci/*
2525a8e1175bSopenharmony_ci * Transmit or retransmit the current flight of messages.
2526a8e1175bSopenharmony_ci *
2527a8e1175bSopenharmony_ci * Need to remember the current message in case flush_output returns
2528a8e1175bSopenharmony_ci * WANT_WRITE, causing us to exit this function and come back later.
2529a8e1175bSopenharmony_ci * This function must be called until state is no longer SENDING.
2530a8e1175bSopenharmony_ci */
2531a8e1175bSopenharmony_ciint mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl)
2532a8e1175bSopenharmony_ci{
2533a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2534a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit"));
2535a8e1175bSopenharmony_ci
2536a8e1175bSopenharmony_ci    if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) {
2537a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission"));
2538a8e1175bSopenharmony_ci
2539a8e1175bSopenharmony_ci        ssl->handshake->cur_msg = ssl->handshake->flight;
2540a8e1175bSopenharmony_ci        ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
2541a8e1175bSopenharmony_ci        ret = ssl_swap_epochs(ssl);
2542a8e1175bSopenharmony_ci        if (ret != 0) {
2543a8e1175bSopenharmony_ci            return ret;
2544a8e1175bSopenharmony_ci        }
2545a8e1175bSopenharmony_ci
2546a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
2547a8e1175bSopenharmony_ci    }
2548a8e1175bSopenharmony_ci
2549a8e1175bSopenharmony_ci    while (ssl->handshake->cur_msg != NULL) {
2550a8e1175bSopenharmony_ci        size_t max_frag_len;
2551a8e1175bSopenharmony_ci        const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
2552a8e1175bSopenharmony_ci
2553a8e1175bSopenharmony_ci        int const is_finished =
2554a8e1175bSopenharmony_ci            (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
2555a8e1175bSopenharmony_ci             cur->p[0] == MBEDTLS_SSL_HS_FINISHED);
2556a8e1175bSopenharmony_ci
2557a8e1175bSopenharmony_ci        int const force_flush = ssl->disable_datagram_packing == 1 ?
2558a8e1175bSopenharmony_ci                                SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
2559a8e1175bSopenharmony_ci
2560a8e1175bSopenharmony_ci        /* Swap epochs before sending Finished: we can't do it after
2561a8e1175bSopenharmony_ci         * sending ChangeCipherSpec, in case write returns WANT_READ.
2562a8e1175bSopenharmony_ci         * Must be done before copying, may change out_msg pointer */
2563a8e1175bSopenharmony_ci        if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) {
2564a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message"));
2565a8e1175bSopenharmony_ci            ret = ssl_swap_epochs(ssl);
2566a8e1175bSopenharmony_ci            if (ret != 0) {
2567a8e1175bSopenharmony_ci                return ret;
2568a8e1175bSopenharmony_ci            }
2569a8e1175bSopenharmony_ci        }
2570a8e1175bSopenharmony_ci
2571a8e1175bSopenharmony_ci        ret = ssl_get_remaining_payload_in_datagram(ssl);
2572a8e1175bSopenharmony_ci        if (ret < 0) {
2573a8e1175bSopenharmony_ci            return ret;
2574a8e1175bSopenharmony_ci        }
2575a8e1175bSopenharmony_ci        max_frag_len = (size_t) ret;
2576a8e1175bSopenharmony_ci
2577a8e1175bSopenharmony_ci        /* CCS is copied as is, while HS messages may need fragmentation */
2578a8e1175bSopenharmony_ci        if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
2579a8e1175bSopenharmony_ci            if (max_frag_len == 0) {
2580a8e1175bSopenharmony_ci                if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
2581a8e1175bSopenharmony_ci                    return ret;
2582a8e1175bSopenharmony_ci                }
2583a8e1175bSopenharmony_ci
2584a8e1175bSopenharmony_ci                continue;
2585a8e1175bSopenharmony_ci            }
2586a8e1175bSopenharmony_ci
2587a8e1175bSopenharmony_ci            memcpy(ssl->out_msg, cur->p, cur->len);
2588a8e1175bSopenharmony_ci            ssl->out_msglen  = cur->len;
2589a8e1175bSopenharmony_ci            ssl->out_msgtype = cur->type;
2590a8e1175bSopenharmony_ci
2591a8e1175bSopenharmony_ci            /* Update position inside current message */
2592a8e1175bSopenharmony_ci            ssl->handshake->cur_msg_p += cur->len;
2593a8e1175bSopenharmony_ci        } else {
2594a8e1175bSopenharmony_ci            const unsigned char * const p = ssl->handshake->cur_msg_p;
2595a8e1175bSopenharmony_ci            const size_t hs_len = cur->len - 12;
2596a8e1175bSopenharmony_ci            const size_t frag_off = (size_t) (p - (cur->p + 12));
2597a8e1175bSopenharmony_ci            const size_t rem_len = hs_len - frag_off;
2598a8e1175bSopenharmony_ci            size_t cur_hs_frag_len, max_hs_frag_len;
2599a8e1175bSopenharmony_ci
2600a8e1175bSopenharmony_ci            if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) {
2601a8e1175bSopenharmony_ci                if (is_finished) {
2602a8e1175bSopenharmony_ci                    ret = ssl_swap_epochs(ssl);
2603a8e1175bSopenharmony_ci                    if (ret != 0) {
2604a8e1175bSopenharmony_ci                        return ret;
2605a8e1175bSopenharmony_ci                    }
2606a8e1175bSopenharmony_ci                }
2607a8e1175bSopenharmony_ci
2608a8e1175bSopenharmony_ci                if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
2609a8e1175bSopenharmony_ci                    return ret;
2610a8e1175bSopenharmony_ci                }
2611a8e1175bSopenharmony_ci
2612a8e1175bSopenharmony_ci                continue;
2613a8e1175bSopenharmony_ci            }
2614a8e1175bSopenharmony_ci            max_hs_frag_len = max_frag_len - 12;
2615a8e1175bSopenharmony_ci
2616a8e1175bSopenharmony_ci            cur_hs_frag_len = rem_len > max_hs_frag_len ?
2617a8e1175bSopenharmony_ci                              max_hs_frag_len : rem_len;
2618a8e1175bSopenharmony_ci
2619a8e1175bSopenharmony_ci            if (frag_off == 0 && cur_hs_frag_len != hs_len) {
2620a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting handshake message (%u > %u)",
2621a8e1175bSopenharmony_ci                                          (unsigned) cur_hs_frag_len,
2622a8e1175bSopenharmony_ci                                          (unsigned) max_hs_frag_len));
2623a8e1175bSopenharmony_ci            }
2624a8e1175bSopenharmony_ci
2625a8e1175bSopenharmony_ci            /* Messages are stored with handshake headers as if not fragmented,
2626a8e1175bSopenharmony_ci             * copy beginning of headers then fill fragmentation fields.
2627a8e1175bSopenharmony_ci             * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
2628a8e1175bSopenharmony_ci            memcpy(ssl->out_msg, cur->p, 6);
2629a8e1175bSopenharmony_ci
2630a8e1175bSopenharmony_ci            ssl->out_msg[6] = MBEDTLS_BYTE_2(frag_off);
2631a8e1175bSopenharmony_ci            ssl->out_msg[7] = MBEDTLS_BYTE_1(frag_off);
2632a8e1175bSopenharmony_ci            ssl->out_msg[8] = MBEDTLS_BYTE_0(frag_off);
2633a8e1175bSopenharmony_ci
2634a8e1175bSopenharmony_ci            ssl->out_msg[9] = MBEDTLS_BYTE_2(cur_hs_frag_len);
2635a8e1175bSopenharmony_ci            ssl->out_msg[10] = MBEDTLS_BYTE_1(cur_hs_frag_len);
2636a8e1175bSopenharmony_ci            ssl->out_msg[11] = MBEDTLS_BYTE_0(cur_hs_frag_len);
2637a8e1175bSopenharmony_ci
2638a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12);
2639a8e1175bSopenharmony_ci
2640a8e1175bSopenharmony_ci            /* Copy the handshake message content and set records fields */
2641a8e1175bSopenharmony_ci            memcpy(ssl->out_msg + 12, p, cur_hs_frag_len);
2642a8e1175bSopenharmony_ci            ssl->out_msglen = cur_hs_frag_len + 12;
2643a8e1175bSopenharmony_ci            ssl->out_msgtype = cur->type;
2644a8e1175bSopenharmony_ci
2645a8e1175bSopenharmony_ci            /* Update position inside current message */
2646a8e1175bSopenharmony_ci            ssl->handshake->cur_msg_p += cur_hs_frag_len;
2647a8e1175bSopenharmony_ci        }
2648a8e1175bSopenharmony_ci
2649a8e1175bSopenharmony_ci        /* If done with the current message move to the next one if any */
2650a8e1175bSopenharmony_ci        if (ssl->handshake->cur_msg_p >= cur->p + cur->len) {
2651a8e1175bSopenharmony_ci            if (cur->next != NULL) {
2652a8e1175bSopenharmony_ci                ssl->handshake->cur_msg = cur->next;
2653a8e1175bSopenharmony_ci                ssl->handshake->cur_msg_p = cur->next->p + 12;
2654a8e1175bSopenharmony_ci            } else {
2655a8e1175bSopenharmony_ci                ssl->handshake->cur_msg = NULL;
2656a8e1175bSopenharmony_ci                ssl->handshake->cur_msg_p = NULL;
2657a8e1175bSopenharmony_ci            }
2658a8e1175bSopenharmony_ci        }
2659a8e1175bSopenharmony_ci
2660a8e1175bSopenharmony_ci        /* Actually send the message out */
2661a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
2662a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
2663a8e1175bSopenharmony_ci            return ret;
2664a8e1175bSopenharmony_ci        }
2665a8e1175bSopenharmony_ci    }
2666a8e1175bSopenharmony_ci
2667a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
2668a8e1175bSopenharmony_ci        return ret;
2669a8e1175bSopenharmony_ci    }
2670a8e1175bSopenharmony_ci
2671a8e1175bSopenharmony_ci    /* Update state and set timer */
2672a8e1175bSopenharmony_ci    if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
2673a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2674a8e1175bSopenharmony_ci    } else {
2675a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
2676a8e1175bSopenharmony_ci        mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
2677a8e1175bSopenharmony_ci    }
2678a8e1175bSopenharmony_ci
2679a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit"));
2680a8e1175bSopenharmony_ci
2681a8e1175bSopenharmony_ci    return 0;
2682a8e1175bSopenharmony_ci}
2683a8e1175bSopenharmony_ci
2684a8e1175bSopenharmony_ci/*
2685a8e1175bSopenharmony_ci * To be called when the last message of an incoming flight is received.
2686a8e1175bSopenharmony_ci */
2687a8e1175bSopenharmony_civoid mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl)
2688a8e1175bSopenharmony_ci{
2689a8e1175bSopenharmony_ci    /* We won't need to resend that one any more */
2690a8e1175bSopenharmony_ci    mbedtls_ssl_flight_free(ssl->handshake->flight);
2691a8e1175bSopenharmony_ci    ssl->handshake->flight = NULL;
2692a8e1175bSopenharmony_ci    ssl->handshake->cur_msg = NULL;
2693a8e1175bSopenharmony_ci
2694a8e1175bSopenharmony_ci    /* The next incoming flight will start with this msg_seq */
2695a8e1175bSopenharmony_ci    ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
2696a8e1175bSopenharmony_ci
2697a8e1175bSopenharmony_ci    /* We don't want to remember CCS's across flight boundaries. */
2698a8e1175bSopenharmony_ci    ssl->handshake->buffering.seen_ccs = 0;
2699a8e1175bSopenharmony_ci
2700a8e1175bSopenharmony_ci    /* Clear future message buffering structure. */
2701a8e1175bSopenharmony_ci    mbedtls_ssl_buffering_free(ssl);
2702a8e1175bSopenharmony_ci
2703a8e1175bSopenharmony_ci    /* Cancel timer */
2704a8e1175bSopenharmony_ci    mbedtls_ssl_set_timer(ssl, 0);
2705a8e1175bSopenharmony_ci
2706a8e1175bSopenharmony_ci    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2707a8e1175bSopenharmony_ci        ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
2708a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2709a8e1175bSopenharmony_ci    } else {
2710a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
2711a8e1175bSopenharmony_ci    }
2712a8e1175bSopenharmony_ci}
2713a8e1175bSopenharmony_ci
2714a8e1175bSopenharmony_ci/*
2715a8e1175bSopenharmony_ci * To be called when the last message of an outgoing flight is send.
2716a8e1175bSopenharmony_ci */
2717a8e1175bSopenharmony_civoid mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl)
2718a8e1175bSopenharmony_ci{
2719a8e1175bSopenharmony_ci    ssl_reset_retransmit_timeout(ssl);
2720a8e1175bSopenharmony_ci    mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
2721a8e1175bSopenharmony_ci
2722a8e1175bSopenharmony_ci    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2723a8e1175bSopenharmony_ci        ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
2724a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
2725a8e1175bSopenharmony_ci    } else {
2726a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
2727a8e1175bSopenharmony_ci    }
2728a8e1175bSopenharmony_ci}
2729a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
2730a8e1175bSopenharmony_ci
2731a8e1175bSopenharmony_ci/*
2732a8e1175bSopenharmony_ci * Handshake layer functions
2733a8e1175bSopenharmony_ci */
2734a8e1175bSopenharmony_ciint mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
2735a8e1175bSopenharmony_ci                                    unsigned char **buf, size_t *buf_len)
2736a8e1175bSopenharmony_ci{
2737a8e1175bSopenharmony_ci    /*
2738a8e1175bSopenharmony_ci     * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 )
2739a8e1175bSopenharmony_ci     *    ...
2740a8e1175bSopenharmony_ci     *    HandshakeType msg_type;
2741a8e1175bSopenharmony_ci     *    uint24 length;
2742a8e1175bSopenharmony_ci     *    ...
2743a8e1175bSopenharmony_ci     */
2744a8e1175bSopenharmony_ci    *buf = ssl->out_msg + 4;
2745a8e1175bSopenharmony_ci    *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
2746a8e1175bSopenharmony_ci
2747a8e1175bSopenharmony_ci    ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2748a8e1175bSopenharmony_ci    ssl->out_msg[0]  = hs_type;
2749a8e1175bSopenharmony_ci
2750a8e1175bSopenharmony_ci    return 0;
2751a8e1175bSopenharmony_ci}
2752a8e1175bSopenharmony_ci
2753a8e1175bSopenharmony_ci/*
2754a8e1175bSopenharmony_ci * Write (DTLS: or queue) current handshake (including CCS) message.
2755a8e1175bSopenharmony_ci *
2756a8e1175bSopenharmony_ci *  - fill in handshake headers
2757a8e1175bSopenharmony_ci *  - update handshake checksum
2758a8e1175bSopenharmony_ci *  - DTLS: save message for resending
2759a8e1175bSopenharmony_ci *  - then pass to the record layer
2760a8e1175bSopenharmony_ci *
2761a8e1175bSopenharmony_ci * DTLS: except for HelloRequest, messages are only queued, and will only be
2762a8e1175bSopenharmony_ci * actually sent when calling flight_transmit() or resend().
2763a8e1175bSopenharmony_ci *
2764a8e1175bSopenharmony_ci * Inputs:
2765a8e1175bSopenharmony_ci *  - ssl->out_msglen: 4 + actual handshake message len
2766a8e1175bSopenharmony_ci *      (4 is the size of handshake headers for TLS)
2767a8e1175bSopenharmony_ci *  - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
2768a8e1175bSopenharmony_ci *  - ssl->out_msg + 4: the handshake message body
2769a8e1175bSopenharmony_ci *
2770a8e1175bSopenharmony_ci * Outputs, ie state before passing to flight_append() or write_record():
2771a8e1175bSopenharmony_ci *   - ssl->out_msglen: the length of the record contents
2772a8e1175bSopenharmony_ci *      (including handshake headers but excluding record headers)
2773a8e1175bSopenharmony_ci *   - ssl->out_msg: the record contents (handshake headers + content)
2774a8e1175bSopenharmony_ci */
2775a8e1175bSopenharmony_ciint mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl,
2776a8e1175bSopenharmony_ci                                        int update_checksum,
2777a8e1175bSopenharmony_ci                                        int force_flush)
2778a8e1175bSopenharmony_ci{
2779a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2780a8e1175bSopenharmony_ci    const size_t hs_len = ssl->out_msglen - 4;
2781a8e1175bSopenharmony_ci    const unsigned char hs_type = ssl->out_msg[0];
2782a8e1175bSopenharmony_ci
2783a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message"));
2784a8e1175bSopenharmony_ci
2785a8e1175bSopenharmony_ci    /*
2786a8e1175bSopenharmony_ci     * Sanity checks
2787a8e1175bSopenharmony_ci     */
2788a8e1175bSopenharmony_ci    if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE          &&
2789a8e1175bSopenharmony_ci        ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
2790a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2791a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2792a8e1175bSopenharmony_ci    }
2793a8e1175bSopenharmony_ci
2794a8e1175bSopenharmony_ci    /* Whenever we send anything different from a
2795a8e1175bSopenharmony_ci     * HelloRequest we should be in a handshake - double check. */
2796a8e1175bSopenharmony_ci    if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2797a8e1175bSopenharmony_ci          hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST) &&
2798a8e1175bSopenharmony_ci        ssl->handshake == NULL) {
2799a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2800a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2801a8e1175bSopenharmony_ci    }
2802a8e1175bSopenharmony_ci
2803a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2804a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2805a8e1175bSopenharmony_ci        ssl->handshake != NULL &&
2806a8e1175bSopenharmony_ci        ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
2807a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2808a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2809a8e1175bSopenharmony_ci    }
2810a8e1175bSopenharmony_ci#endif
2811a8e1175bSopenharmony_ci
2812a8e1175bSopenharmony_ci    /* Double-check that we did not exceed the bounds
2813a8e1175bSopenharmony_ci     * of the outgoing record buffer.
2814a8e1175bSopenharmony_ci     * This should never fail as the various message
2815a8e1175bSopenharmony_ci     * writing functions must obey the bounds of the
2816a8e1175bSopenharmony_ci     * outgoing record buffer, but better be safe.
2817a8e1175bSopenharmony_ci     *
2818a8e1175bSopenharmony_ci     * Note: We deliberately do not check for the MTU or MFL here.
2819a8e1175bSopenharmony_ci     */
2820a8e1175bSopenharmony_ci    if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) {
2821a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: "
2822a8e1175bSopenharmony_ci                                  "size %" MBEDTLS_PRINTF_SIZET
2823a8e1175bSopenharmony_ci                                  ", maximum %" MBEDTLS_PRINTF_SIZET,
2824a8e1175bSopenharmony_ci                                  ssl->out_msglen,
2825a8e1175bSopenharmony_ci                                  (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
2826a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2827a8e1175bSopenharmony_ci    }
2828a8e1175bSopenharmony_ci
2829a8e1175bSopenharmony_ci    /*
2830a8e1175bSopenharmony_ci     * Fill handshake headers
2831a8e1175bSopenharmony_ci     */
2832a8e1175bSopenharmony_ci    if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
2833a8e1175bSopenharmony_ci        ssl->out_msg[1] = MBEDTLS_BYTE_2(hs_len);
2834a8e1175bSopenharmony_ci        ssl->out_msg[2] = MBEDTLS_BYTE_1(hs_len);
2835a8e1175bSopenharmony_ci        ssl->out_msg[3] = MBEDTLS_BYTE_0(hs_len);
2836a8e1175bSopenharmony_ci
2837a8e1175bSopenharmony_ci        /*
2838a8e1175bSopenharmony_ci         * DTLS has additional fields in the Handshake layer,
2839a8e1175bSopenharmony_ci         * between the length field and the actual payload:
2840a8e1175bSopenharmony_ci         *      uint16 message_seq;
2841a8e1175bSopenharmony_ci         *      uint24 fragment_offset;
2842a8e1175bSopenharmony_ci         *      uint24 fragment_length;
2843a8e1175bSopenharmony_ci         */
2844a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2845a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
2846a8e1175bSopenharmony_ci            /* Make room for the additional DTLS fields */
2847a8e1175bSopenharmony_ci            if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) {
2848a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS handshake message too large: "
2849a8e1175bSopenharmony_ci                                          "size %" MBEDTLS_PRINTF_SIZET ", maximum %"
2850a8e1175bSopenharmony_ci                                          MBEDTLS_PRINTF_SIZET,
2851a8e1175bSopenharmony_ci                                          hs_len,
2852a8e1175bSopenharmony_ci                                          (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - 12)));
2853a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2854a8e1175bSopenharmony_ci            }
2855a8e1175bSopenharmony_ci
2856a8e1175bSopenharmony_ci            memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len);
2857a8e1175bSopenharmony_ci            ssl->out_msglen += 8;
2858a8e1175bSopenharmony_ci
2859a8e1175bSopenharmony_ci            /* Write message_seq and update it, except for HelloRequest */
2860a8e1175bSopenharmony_ci            if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) {
2861a8e1175bSopenharmony_ci                MBEDTLS_PUT_UINT16_BE(ssl->handshake->out_msg_seq, ssl->out_msg, 4);
2862a8e1175bSopenharmony_ci                ++(ssl->handshake->out_msg_seq);
2863a8e1175bSopenharmony_ci            } else {
2864a8e1175bSopenharmony_ci                ssl->out_msg[4] = 0;
2865a8e1175bSopenharmony_ci                ssl->out_msg[5] = 0;
2866a8e1175bSopenharmony_ci            }
2867a8e1175bSopenharmony_ci
2868a8e1175bSopenharmony_ci            /* Handshake hashes are computed without fragmentation,
2869a8e1175bSopenharmony_ci             * so set frag_offset = 0 and frag_len = hs_len for now */
2870a8e1175bSopenharmony_ci            memset(ssl->out_msg + 6, 0x00, 3);
2871a8e1175bSopenharmony_ci            memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3);
2872a8e1175bSopenharmony_ci        }
2873a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
2874a8e1175bSopenharmony_ci
2875a8e1175bSopenharmony_ci        /* Update running hashes of handshake messages seen */
2876a8e1175bSopenharmony_ci        if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) {
2877a8e1175bSopenharmony_ci            ret = ssl->handshake->update_checksum(ssl, ssl->out_msg,
2878a8e1175bSopenharmony_ci                                                  ssl->out_msglen);
2879a8e1175bSopenharmony_ci            if (ret != 0) {
2880a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
2881a8e1175bSopenharmony_ci                return ret;
2882a8e1175bSopenharmony_ci            }
2883a8e1175bSopenharmony_ci        }
2884a8e1175bSopenharmony_ci    }
2885a8e1175bSopenharmony_ci
2886a8e1175bSopenharmony_ci    /* Either send now, or just save to be sent (and resent) later */
2887a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2888a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2889a8e1175bSopenharmony_ci        !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
2890a8e1175bSopenharmony_ci          hs_type          == MBEDTLS_SSL_HS_HELLO_REQUEST)) {
2891a8e1175bSopenharmony_ci        if ((ret = ssl_flight_append(ssl)) != 0) {
2892a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret);
2893a8e1175bSopenharmony_ci            return ret;
2894a8e1175bSopenharmony_ci        }
2895a8e1175bSopenharmony_ci    } else
2896a8e1175bSopenharmony_ci#endif
2897a8e1175bSopenharmony_ci    {
2898a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
2899a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret);
2900a8e1175bSopenharmony_ci            return ret;
2901a8e1175bSopenharmony_ci        }
2902a8e1175bSopenharmony_ci    }
2903a8e1175bSopenharmony_ci
2904a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message"));
2905a8e1175bSopenharmony_ci
2906a8e1175bSopenharmony_ci    return 0;
2907a8e1175bSopenharmony_ci}
2908a8e1175bSopenharmony_ci
2909a8e1175bSopenharmony_ciint mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl,
2910a8e1175bSopenharmony_ci                                     size_t buf_len, size_t msg_len)
2911a8e1175bSopenharmony_ci{
2912a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2913a8e1175bSopenharmony_ci    size_t msg_with_header_len;
2914a8e1175bSopenharmony_ci    ((void) buf_len);
2915a8e1175bSopenharmony_ci
2916a8e1175bSopenharmony_ci    /* Add reserved 4 bytes for handshake header */
2917a8e1175bSopenharmony_ci    msg_with_header_len = msg_len + 4;
2918a8e1175bSopenharmony_ci    ssl->out_msglen = msg_with_header_len;
2919a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_handshake_msg_ext(ssl, 0, 0));
2920a8e1175bSopenharmony_ci
2921a8e1175bSopenharmony_cicleanup:
2922a8e1175bSopenharmony_ci    return ret;
2923a8e1175bSopenharmony_ci}
2924a8e1175bSopenharmony_ci
2925a8e1175bSopenharmony_ci/*
2926a8e1175bSopenharmony_ci * Record layer functions
2927a8e1175bSopenharmony_ci */
2928a8e1175bSopenharmony_ci
2929a8e1175bSopenharmony_ci/*
2930a8e1175bSopenharmony_ci * Write current record.
2931a8e1175bSopenharmony_ci *
2932a8e1175bSopenharmony_ci * Uses:
2933a8e1175bSopenharmony_ci *  - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
2934a8e1175bSopenharmony_ci *  - ssl->out_msglen: length of the record content (excl headers)
2935a8e1175bSopenharmony_ci *  - ssl->out_msg: record content
2936a8e1175bSopenharmony_ci */
2937a8e1175bSopenharmony_ciint mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush)
2938a8e1175bSopenharmony_ci{
2939a8e1175bSopenharmony_ci    int ret, done = 0;
2940a8e1175bSopenharmony_ci    size_t len = ssl->out_msglen;
2941a8e1175bSopenharmony_ci    int flush = force_flush;
2942a8e1175bSopenharmony_ci
2943a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record"));
2944a8e1175bSopenharmony_ci
2945a8e1175bSopenharmony_ci    if (!done) {
2946a8e1175bSopenharmony_ci        unsigned i;
2947a8e1175bSopenharmony_ci        size_t protected_record_size;
2948a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2949a8e1175bSopenharmony_ci        size_t out_buf_len = ssl->out_buf_len;
2950a8e1175bSopenharmony_ci#else
2951a8e1175bSopenharmony_ci        size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
2952a8e1175bSopenharmony_ci#endif
2953a8e1175bSopenharmony_ci        /* Skip writing the record content type to after the encryption,
2954a8e1175bSopenharmony_ci         * as it may change when using the CID extension. */
2955a8e1175bSopenharmony_ci        mbedtls_ssl_protocol_version tls_ver = ssl->tls_version;
2956a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2957a8e1175bSopenharmony_ci        /* TLS 1.3 still uses the TLS 1.2 version identifier
2958a8e1175bSopenharmony_ci         * for backwards compatibility. */
2959a8e1175bSopenharmony_ci        if (tls_ver == MBEDTLS_SSL_VERSION_TLS1_3) {
2960a8e1175bSopenharmony_ci            tls_ver = MBEDTLS_SSL_VERSION_TLS1_2;
2961a8e1175bSopenharmony_ci        }
2962a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2963a8e1175bSopenharmony_ci        mbedtls_ssl_write_version(ssl->out_hdr + 1, ssl->conf->transport,
2964a8e1175bSopenharmony_ci                                  tls_ver);
2965a8e1175bSopenharmony_ci
2966a8e1175bSopenharmony_ci        memcpy(ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
2967a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(len, ssl->out_len, 0);
2968a8e1175bSopenharmony_ci
2969a8e1175bSopenharmony_ci        if (ssl->transform_out != NULL) {
2970a8e1175bSopenharmony_ci            mbedtls_record rec;
2971a8e1175bSopenharmony_ci
2972a8e1175bSopenharmony_ci            rec.buf         = ssl->out_iv;
2973a8e1175bSopenharmony_ci            rec.buf_len     = out_buf_len - (size_t) (ssl->out_iv - ssl->out_buf);
2974a8e1175bSopenharmony_ci            rec.data_len    = ssl->out_msglen;
2975a8e1175bSopenharmony_ci            rec.data_offset = (size_t) (ssl->out_msg - rec.buf);
2976a8e1175bSopenharmony_ci
2977a8e1175bSopenharmony_ci            memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr));
2978a8e1175bSopenharmony_ci            mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver);
2979a8e1175bSopenharmony_ci            rec.type = ssl->out_msgtype;
2980a8e1175bSopenharmony_ci
2981a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2982a8e1175bSopenharmony_ci            /* The CID is set by mbedtls_ssl_encrypt_buf(). */
2983a8e1175bSopenharmony_ci            rec.cid_len = 0;
2984a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2985a8e1175bSopenharmony_ci
2986a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec,
2987a8e1175bSopenharmony_ci                                               ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2988a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret);
2989a8e1175bSopenharmony_ci                return ret;
2990a8e1175bSopenharmony_ci            }
2991a8e1175bSopenharmony_ci
2992a8e1175bSopenharmony_ci            if (rec.data_offset != 0) {
2993a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2994a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2995a8e1175bSopenharmony_ci            }
2996a8e1175bSopenharmony_ci
2997a8e1175bSopenharmony_ci            /* Update the record content type and CID. */
2998a8e1175bSopenharmony_ci            ssl->out_msgtype = rec.type;
2999a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3000a8e1175bSopenharmony_ci            memcpy(ssl->out_cid, rec.cid, rec.cid_len);
3001a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3002a8e1175bSopenharmony_ci            ssl->out_msglen = len = rec.data_len;
3003a8e1175bSopenharmony_ci            MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->out_len, 0);
3004a8e1175bSopenharmony_ci        }
3005a8e1175bSopenharmony_ci
3006a8e1175bSopenharmony_ci        protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl);
3007a8e1175bSopenharmony_ci
3008a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3009a8e1175bSopenharmony_ci        /* In case of DTLS, double-check that we don't exceed
3010a8e1175bSopenharmony_ci         * the remaining space in the datagram. */
3011a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3012a8e1175bSopenharmony_ci            ret = ssl_get_remaining_space_in_datagram(ssl);
3013a8e1175bSopenharmony_ci            if (ret < 0) {
3014a8e1175bSopenharmony_ci                return ret;
3015a8e1175bSopenharmony_ci            }
3016a8e1175bSopenharmony_ci
3017a8e1175bSopenharmony_ci            if (protected_record_size > (size_t) ret) {
3018a8e1175bSopenharmony_ci                /* Should never happen */
3019a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3020a8e1175bSopenharmony_ci            }
3021a8e1175bSopenharmony_ci        }
3022a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3023a8e1175bSopenharmony_ci
3024a8e1175bSopenharmony_ci        /* Now write the potentially updated record content type. */
3025a8e1175bSopenharmony_ci        ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
3026a8e1175bSopenharmony_ci
3027a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("output record: msgtype = %u, "
3028a8e1175bSopenharmony_ci                                  "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
3029a8e1175bSopenharmony_ci                                  ssl->out_hdr[0], ssl->out_hdr[1],
3030a8e1175bSopenharmony_ci                                  ssl->out_hdr[2], len));
3031a8e1175bSopenharmony_ci
3032a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
3033a8e1175bSopenharmony_ci                              ssl->out_hdr, protected_record_size);
3034a8e1175bSopenharmony_ci
3035a8e1175bSopenharmony_ci        ssl->out_left += protected_record_size;
3036a8e1175bSopenharmony_ci        ssl->out_hdr  += protected_record_size;
3037a8e1175bSopenharmony_ci        mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
3038a8e1175bSopenharmony_ci
3039a8e1175bSopenharmony_ci        for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--) {
3040a8e1175bSopenharmony_ci            if (++ssl->cur_out_ctr[i - 1] != 0) {
3041a8e1175bSopenharmony_ci                break;
3042a8e1175bSopenharmony_ci            }
3043a8e1175bSopenharmony_ci        }
3044a8e1175bSopenharmony_ci
3045a8e1175bSopenharmony_ci        /* The loop goes to its end if the counter is wrapping */
3046a8e1175bSopenharmony_ci        if (i == mbedtls_ssl_ep_len(ssl)) {
3047a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap"));
3048a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
3049a8e1175bSopenharmony_ci        }
3050a8e1175bSopenharmony_ci    }
3051a8e1175bSopenharmony_ci
3052a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3053a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3054a8e1175bSopenharmony_ci        flush == SSL_DONT_FORCE_FLUSH) {
3055a8e1175bSopenharmony_ci        size_t remaining;
3056a8e1175bSopenharmony_ci        ret = ssl_get_remaining_payload_in_datagram(ssl);
3057a8e1175bSopenharmony_ci        if (ret < 0) {
3058a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram",
3059a8e1175bSopenharmony_ci                                  ret);
3060a8e1175bSopenharmony_ci            return ret;
3061a8e1175bSopenharmony_ci        }
3062a8e1175bSopenharmony_ci
3063a8e1175bSopenharmony_ci        remaining = (size_t) ret;
3064a8e1175bSopenharmony_ci        if (remaining == 0) {
3065a8e1175bSopenharmony_ci            flush = SSL_FORCE_FLUSH;
3066a8e1175bSopenharmony_ci        } else {
3067a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2,
3068a8e1175bSopenharmony_ci                                  ("Still %u bytes available in current datagram",
3069a8e1175bSopenharmony_ci                                   (unsigned) remaining));
3070a8e1175bSopenharmony_ci        }
3071a8e1175bSopenharmony_ci    }
3072a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3073a8e1175bSopenharmony_ci
3074a8e1175bSopenharmony_ci    if ((flush == SSL_FORCE_FLUSH) &&
3075a8e1175bSopenharmony_ci        (ret = mbedtls_ssl_flush_output(ssl)) != 0) {
3076a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
3077a8e1175bSopenharmony_ci        return ret;
3078a8e1175bSopenharmony_ci    }
3079a8e1175bSopenharmony_ci
3080a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record"));
3081a8e1175bSopenharmony_ci
3082a8e1175bSopenharmony_ci    return 0;
3083a8e1175bSopenharmony_ci}
3084a8e1175bSopenharmony_ci
3085a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3086a8e1175bSopenharmony_ci
3087a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3088a8e1175bSopenharmony_cistatic int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl)
3089a8e1175bSopenharmony_ci{
3090a8e1175bSopenharmony_ci    if (ssl->in_msglen < ssl->in_hslen ||
3091a8e1175bSopenharmony_ci        memcmp(ssl->in_msg + 6, "\0\0\0",        3) != 0 ||
3092a8e1175bSopenharmony_ci        memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) {
3093a8e1175bSopenharmony_ci        return 1;
3094a8e1175bSopenharmony_ci    }
3095a8e1175bSopenharmony_ci    return 0;
3096a8e1175bSopenharmony_ci}
3097a8e1175bSopenharmony_ci
3098a8e1175bSopenharmony_cistatic uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
3099a8e1175bSopenharmony_ci{
3100a8e1175bSopenharmony_ci    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
3101a8e1175bSopenharmony_ci}
3102a8e1175bSopenharmony_ci
3103a8e1175bSopenharmony_cistatic uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
3104a8e1175bSopenharmony_ci{
3105a8e1175bSopenharmony_ci    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
3106a8e1175bSopenharmony_ci}
3107a8e1175bSopenharmony_ci
3108a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3109a8e1175bSopenharmony_cistatic int ssl_check_hs_header(mbedtls_ssl_context const *ssl)
3110a8e1175bSopenharmony_ci{
3111a8e1175bSopenharmony_ci    uint32_t msg_len, frag_off, frag_len;
3112a8e1175bSopenharmony_ci
3113a8e1175bSopenharmony_ci    msg_len  = ssl_get_hs_total_len(ssl);
3114a8e1175bSopenharmony_ci    frag_off = ssl_get_hs_frag_off(ssl);
3115a8e1175bSopenharmony_ci    frag_len = ssl_get_hs_frag_len(ssl);
3116a8e1175bSopenharmony_ci
3117a8e1175bSopenharmony_ci    if (frag_off > msg_len) {
3118a8e1175bSopenharmony_ci        return -1;
3119a8e1175bSopenharmony_ci    }
3120a8e1175bSopenharmony_ci
3121a8e1175bSopenharmony_ci    if (frag_len > msg_len - frag_off) {
3122a8e1175bSopenharmony_ci        return -1;
3123a8e1175bSopenharmony_ci    }
3124a8e1175bSopenharmony_ci
3125a8e1175bSopenharmony_ci    if (frag_len + 12 > ssl->in_msglen) {
3126a8e1175bSopenharmony_ci        return -1;
3127a8e1175bSopenharmony_ci    }
3128a8e1175bSopenharmony_ci
3129a8e1175bSopenharmony_ci    return 0;
3130a8e1175bSopenharmony_ci}
3131a8e1175bSopenharmony_ci
3132a8e1175bSopenharmony_ci/*
3133a8e1175bSopenharmony_ci * Mark bits in bitmask (used for DTLS HS reassembly)
3134a8e1175bSopenharmony_ci */
3135a8e1175bSopenharmony_cistatic void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len)
3136a8e1175bSopenharmony_ci{
3137a8e1175bSopenharmony_ci    unsigned int start_bits, end_bits;
3138a8e1175bSopenharmony_ci
3139a8e1175bSopenharmony_ci    start_bits = 8 - (offset % 8);
3140a8e1175bSopenharmony_ci    if (start_bits != 8) {
3141a8e1175bSopenharmony_ci        size_t first_byte_idx = offset / 8;
3142a8e1175bSopenharmony_ci
3143a8e1175bSopenharmony_ci        /* Special case */
3144a8e1175bSopenharmony_ci        if (len <= start_bits) {
3145a8e1175bSopenharmony_ci            for (; len != 0; len--) {
3146a8e1175bSopenharmony_ci                mask[first_byte_idx] |= 1 << (start_bits - len);
3147a8e1175bSopenharmony_ci            }
3148a8e1175bSopenharmony_ci
3149a8e1175bSopenharmony_ci            /* Avoid potential issues with offset or len becoming invalid */
3150a8e1175bSopenharmony_ci            return;
3151a8e1175bSopenharmony_ci        }
3152a8e1175bSopenharmony_ci
3153a8e1175bSopenharmony_ci        offset += start_bits; /* Now offset % 8 == 0 */
3154a8e1175bSopenharmony_ci        len -= start_bits;
3155a8e1175bSopenharmony_ci
3156a8e1175bSopenharmony_ci        for (; start_bits != 0; start_bits--) {
3157a8e1175bSopenharmony_ci            mask[first_byte_idx] |= 1 << (start_bits - 1);
3158a8e1175bSopenharmony_ci        }
3159a8e1175bSopenharmony_ci    }
3160a8e1175bSopenharmony_ci
3161a8e1175bSopenharmony_ci    end_bits = len % 8;
3162a8e1175bSopenharmony_ci    if (end_bits != 0) {
3163a8e1175bSopenharmony_ci        size_t last_byte_idx = (offset + len) / 8;
3164a8e1175bSopenharmony_ci
3165a8e1175bSopenharmony_ci        len -= end_bits; /* Now len % 8 == 0 */
3166a8e1175bSopenharmony_ci
3167a8e1175bSopenharmony_ci        for (; end_bits != 0; end_bits--) {
3168a8e1175bSopenharmony_ci            mask[last_byte_idx] |= 1 << (8 - end_bits);
3169a8e1175bSopenharmony_ci        }
3170a8e1175bSopenharmony_ci    }
3171a8e1175bSopenharmony_ci
3172a8e1175bSopenharmony_ci    memset(mask + offset / 8, 0xFF, len / 8);
3173a8e1175bSopenharmony_ci}
3174a8e1175bSopenharmony_ci
3175a8e1175bSopenharmony_ci/*
3176a8e1175bSopenharmony_ci * Check that bitmask is full
3177a8e1175bSopenharmony_ci */
3178a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3179a8e1175bSopenharmony_cistatic int ssl_bitmask_check(unsigned char *mask, size_t len)
3180a8e1175bSopenharmony_ci{
3181a8e1175bSopenharmony_ci    size_t i;
3182a8e1175bSopenharmony_ci
3183a8e1175bSopenharmony_ci    for (i = 0; i < len / 8; i++) {
3184a8e1175bSopenharmony_ci        if (mask[i] != 0xFF) {
3185a8e1175bSopenharmony_ci            return -1;
3186a8e1175bSopenharmony_ci        }
3187a8e1175bSopenharmony_ci    }
3188a8e1175bSopenharmony_ci
3189a8e1175bSopenharmony_ci    for (i = 0; i < len % 8; i++) {
3190a8e1175bSopenharmony_ci        if ((mask[len / 8] & (1 << (7 - i))) == 0) {
3191a8e1175bSopenharmony_ci            return -1;
3192a8e1175bSopenharmony_ci        }
3193a8e1175bSopenharmony_ci    }
3194a8e1175bSopenharmony_ci
3195a8e1175bSopenharmony_ci    return 0;
3196a8e1175bSopenharmony_ci}
3197a8e1175bSopenharmony_ci
3198a8e1175bSopenharmony_ci/* msg_len does not include the handshake header */
3199a8e1175bSopenharmony_cistatic size_t ssl_get_reassembly_buffer_size(size_t msg_len,
3200a8e1175bSopenharmony_ci                                             unsigned add_bitmap)
3201a8e1175bSopenharmony_ci{
3202a8e1175bSopenharmony_ci    size_t alloc_len;
3203a8e1175bSopenharmony_ci
3204a8e1175bSopenharmony_ci    alloc_len  = 12;                                 /* Handshake header */
3205a8e1175bSopenharmony_ci    alloc_len += msg_len;                            /* Content buffer   */
3206a8e1175bSopenharmony_ci
3207a8e1175bSopenharmony_ci    if (add_bitmap) {
3208a8e1175bSopenharmony_ci        alloc_len += msg_len / 8 + (msg_len % 8 != 0);   /* Bitmap       */
3209a8e1175bSopenharmony_ci
3210a8e1175bSopenharmony_ci    }
3211a8e1175bSopenharmony_ci    return alloc_len;
3212a8e1175bSopenharmony_ci}
3213a8e1175bSopenharmony_ci
3214a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3215a8e1175bSopenharmony_ci
3216a8e1175bSopenharmony_cistatic uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
3217a8e1175bSopenharmony_ci{
3218a8e1175bSopenharmony_ci    return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
3219a8e1175bSopenharmony_ci}
3220a8e1175bSopenharmony_ci
3221a8e1175bSopenharmony_ciint mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
3222a8e1175bSopenharmony_ci{
3223a8e1175bSopenharmony_ci    if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
3224a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
3225a8e1175bSopenharmony_ci                                  ssl->in_msglen));
3226a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
3227a8e1175bSopenharmony_ci    }
3228a8e1175bSopenharmony_ci
3229a8e1175bSopenharmony_ci    ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
3230a8e1175bSopenharmony_ci
3231a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
3232a8e1175bSopenharmony_ci                              " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
3233a8e1175bSopenharmony_ci                              MBEDTLS_PRINTF_SIZET,
3234a8e1175bSopenharmony_ci                              ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
3235a8e1175bSopenharmony_ci
3236a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3237a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3238a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3239a8e1175bSopenharmony_ci        unsigned int recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
3240a8e1175bSopenharmony_ci
3241a8e1175bSopenharmony_ci        if (ssl_check_hs_header(ssl) != 0) {
3242a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header"));
3243a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
3244a8e1175bSopenharmony_ci        }
3245a8e1175bSopenharmony_ci
3246a8e1175bSopenharmony_ci        if (ssl->handshake != NULL &&
3247a8e1175bSopenharmony_ci            ((mbedtls_ssl_is_handshake_over(ssl) == 0 &&
3248a8e1175bSopenharmony_ci              recv_msg_seq != ssl->handshake->in_msg_seq) ||
3249a8e1175bSopenharmony_ci             (mbedtls_ssl_is_handshake_over(ssl) == 1 &&
3250a8e1175bSopenharmony_ci              ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) {
3251a8e1175bSopenharmony_ci            if (recv_msg_seq > ssl->handshake->in_msg_seq) {
3252a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2,
3253a8e1175bSopenharmony_ci                                      (
3254a8e1175bSopenharmony_ci                                          "received future handshake message of sequence number %u (next %u)",
3255a8e1175bSopenharmony_ci                                          recv_msg_seq,
3256a8e1175bSopenharmony_ci                                          ssl->handshake->in_msg_seq));
3257a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
3258a8e1175bSopenharmony_ci            }
3259a8e1175bSopenharmony_ci
3260a8e1175bSopenharmony_ci            /* Retransmit only on last message from previous flight, to avoid
3261a8e1175bSopenharmony_ci             * too many retransmissions.
3262a8e1175bSopenharmony_ci             * Besides, No sane server ever retransmits HelloVerifyRequest */
3263a8e1175bSopenharmony_ci            if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
3264a8e1175bSopenharmony_ci                ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
3265a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("received message from last flight, "
3266a8e1175bSopenharmony_ci                                          "message_seq = %u, start_of_flight = %u",
3267a8e1175bSopenharmony_ci                                          recv_msg_seq,
3268a8e1175bSopenharmony_ci                                          ssl->handshake->in_flight_start_seq));
3269a8e1175bSopenharmony_ci
3270a8e1175bSopenharmony_ci                if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
3271a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
3272a8e1175bSopenharmony_ci                    return ret;
3273a8e1175bSopenharmony_ci                }
3274a8e1175bSopenharmony_ci            } else {
3275a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: "
3276a8e1175bSopenharmony_ci                                          "message_seq = %u, expected = %u",
3277a8e1175bSopenharmony_ci                                          recv_msg_seq,
3278a8e1175bSopenharmony_ci                                          ssl->handshake->in_msg_seq));
3279a8e1175bSopenharmony_ci            }
3280a8e1175bSopenharmony_ci
3281a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3282a8e1175bSopenharmony_ci        }
3283a8e1175bSopenharmony_ci        /* Wait until message completion to increment in_msg_seq */
3284a8e1175bSopenharmony_ci
3285a8e1175bSopenharmony_ci        /* Message reassembly is handled alongside buffering of future
3286a8e1175bSopenharmony_ci         * messages; the commonality is that both handshake fragments and
3287a8e1175bSopenharmony_ci         * future messages cannot be forwarded immediately to the
3288a8e1175bSopenharmony_ci         * handshake logic layer. */
3289a8e1175bSopenharmony_ci        if (ssl_hs_is_proper_fragment(ssl) == 1) {
3290a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("found fragmented DTLS handshake message"));
3291a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
3292a8e1175bSopenharmony_ci        }
3293a8e1175bSopenharmony_ci    } else
3294a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3295a8e1175bSopenharmony_ci    /* With TLS we don't handle fragmentation (for now) */
3296a8e1175bSopenharmony_ci    if (ssl->in_msglen < ssl->in_hslen) {
3297a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("TLS handshake fragmentation not supported"));
3298a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3299a8e1175bSopenharmony_ci    }
3300a8e1175bSopenharmony_ci
3301a8e1175bSopenharmony_ci    return 0;
3302a8e1175bSopenharmony_ci}
3303a8e1175bSopenharmony_ci
3304a8e1175bSopenharmony_ciint mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
3305a8e1175bSopenharmony_ci{
3306a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3307a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
3308a8e1175bSopenharmony_ci
3309a8e1175bSopenharmony_ci    if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) {
3310a8e1175bSopenharmony_ci        ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
3311a8e1175bSopenharmony_ci        if (ret != 0) {
3312a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
3313a8e1175bSopenharmony_ci            return ret;
3314a8e1175bSopenharmony_ci        }
3315a8e1175bSopenharmony_ci    }
3316a8e1175bSopenharmony_ci
3317a8e1175bSopenharmony_ci    /* Handshake message is complete, increment counter */
3318a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3319a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3320a8e1175bSopenharmony_ci        ssl->handshake != NULL) {
3321a8e1175bSopenharmony_ci        unsigned offset;
3322a8e1175bSopenharmony_ci        mbedtls_ssl_hs_buffer *hs_buf;
3323a8e1175bSopenharmony_ci
3324a8e1175bSopenharmony_ci        /* Increment handshake sequence number */
3325a8e1175bSopenharmony_ci        hs->in_msg_seq++;
3326a8e1175bSopenharmony_ci
3327a8e1175bSopenharmony_ci        /*
3328a8e1175bSopenharmony_ci         * Clear up handshake buffering and reassembly structure.
3329a8e1175bSopenharmony_ci         */
3330a8e1175bSopenharmony_ci
3331a8e1175bSopenharmony_ci        /* Free first entry */
3332a8e1175bSopenharmony_ci        ssl_buffering_free_slot(ssl, 0);
3333a8e1175bSopenharmony_ci
3334a8e1175bSopenharmony_ci        /* Shift all other entries */
3335a8e1175bSopenharmony_ci        for (offset = 0, hs_buf = &hs->buffering.hs[0];
3336a8e1175bSopenharmony_ci             offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
3337a8e1175bSopenharmony_ci             offset++, hs_buf++) {
3338a8e1175bSopenharmony_ci            *hs_buf = *(hs_buf + 1);
3339a8e1175bSopenharmony_ci        }
3340a8e1175bSopenharmony_ci
3341a8e1175bSopenharmony_ci        /* Create a fresh last entry */
3342a8e1175bSopenharmony_ci        memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
3343a8e1175bSopenharmony_ci    }
3344a8e1175bSopenharmony_ci#endif
3345a8e1175bSopenharmony_ci    return 0;
3346a8e1175bSopenharmony_ci}
3347a8e1175bSopenharmony_ci
3348a8e1175bSopenharmony_ci/*
3349a8e1175bSopenharmony_ci * DTLS anti-replay: RFC 6347 4.1.2.6
3350a8e1175bSopenharmony_ci *
3351a8e1175bSopenharmony_ci * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
3352a8e1175bSopenharmony_ci * Bit n is set iff record number in_window_top - n has been seen.
3353a8e1175bSopenharmony_ci *
3354a8e1175bSopenharmony_ci * Usually, in_window_top is the last record number seen and the lsb of
3355a8e1175bSopenharmony_ci * in_window is set. The only exception is the initial state (record number 0
3356a8e1175bSopenharmony_ci * not seen yet).
3357a8e1175bSopenharmony_ci */
3358a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3359a8e1175bSopenharmony_civoid mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl)
3360a8e1175bSopenharmony_ci{
3361a8e1175bSopenharmony_ci    ssl->in_window_top = 0;
3362a8e1175bSopenharmony_ci    ssl->in_window = 0;
3363a8e1175bSopenharmony_ci}
3364a8e1175bSopenharmony_ci
3365a8e1175bSopenharmony_cistatic inline uint64_t ssl_load_six_bytes(unsigned char *buf)
3366a8e1175bSopenharmony_ci{
3367a8e1175bSopenharmony_ci    return ((uint64_t) buf[0] << 40) |
3368a8e1175bSopenharmony_ci           ((uint64_t) buf[1] << 32) |
3369a8e1175bSopenharmony_ci           ((uint64_t) buf[2] << 24) |
3370a8e1175bSopenharmony_ci           ((uint64_t) buf[3] << 16) |
3371a8e1175bSopenharmony_ci           ((uint64_t) buf[4] <<  8) |
3372a8e1175bSopenharmony_ci           ((uint64_t) buf[5]);
3373a8e1175bSopenharmony_ci}
3374a8e1175bSopenharmony_ci
3375a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3376a8e1175bSopenharmony_cistatic int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr)
3377a8e1175bSopenharmony_ci{
3378a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3379a8e1175bSopenharmony_ci    unsigned char *original_in_ctr;
3380a8e1175bSopenharmony_ci
3381a8e1175bSopenharmony_ci    // save original in_ctr
3382a8e1175bSopenharmony_ci    original_in_ctr = ssl->in_ctr;
3383a8e1175bSopenharmony_ci
3384a8e1175bSopenharmony_ci    // use counter from record
3385a8e1175bSopenharmony_ci    ssl->in_ctr = record_in_ctr;
3386a8e1175bSopenharmony_ci
3387a8e1175bSopenharmony_ci    ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *) ssl);
3388a8e1175bSopenharmony_ci
3389a8e1175bSopenharmony_ci    // restore the counter
3390a8e1175bSopenharmony_ci    ssl->in_ctr = original_in_ctr;
3391a8e1175bSopenharmony_ci
3392a8e1175bSopenharmony_ci    return ret;
3393a8e1175bSopenharmony_ci}
3394a8e1175bSopenharmony_ci
3395a8e1175bSopenharmony_ci/*
3396a8e1175bSopenharmony_ci * Return 0 if sequence number is acceptable, -1 otherwise
3397a8e1175bSopenharmony_ci */
3398a8e1175bSopenharmony_ciint mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl)
3399a8e1175bSopenharmony_ci{
3400a8e1175bSopenharmony_ci    uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
3401a8e1175bSopenharmony_ci    uint64_t bit;
3402a8e1175bSopenharmony_ci
3403a8e1175bSopenharmony_ci    if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
3404a8e1175bSopenharmony_ci        return 0;
3405a8e1175bSopenharmony_ci    }
3406a8e1175bSopenharmony_ci
3407a8e1175bSopenharmony_ci    if (rec_seqnum > ssl->in_window_top) {
3408a8e1175bSopenharmony_ci        return 0;
3409a8e1175bSopenharmony_ci    }
3410a8e1175bSopenharmony_ci
3411a8e1175bSopenharmony_ci    bit = ssl->in_window_top - rec_seqnum;
3412a8e1175bSopenharmony_ci
3413a8e1175bSopenharmony_ci    if (bit >= 64) {
3414a8e1175bSopenharmony_ci        return -1;
3415a8e1175bSopenharmony_ci    }
3416a8e1175bSopenharmony_ci
3417a8e1175bSopenharmony_ci    if ((ssl->in_window & ((uint64_t) 1 << bit)) != 0) {
3418a8e1175bSopenharmony_ci        return -1;
3419a8e1175bSopenharmony_ci    }
3420a8e1175bSopenharmony_ci
3421a8e1175bSopenharmony_ci    return 0;
3422a8e1175bSopenharmony_ci}
3423a8e1175bSopenharmony_ci
3424a8e1175bSopenharmony_ci/*
3425a8e1175bSopenharmony_ci * Update replay window on new validated record
3426a8e1175bSopenharmony_ci */
3427a8e1175bSopenharmony_civoid mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl)
3428a8e1175bSopenharmony_ci{
3429a8e1175bSopenharmony_ci    uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
3430a8e1175bSopenharmony_ci
3431a8e1175bSopenharmony_ci    if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
3432a8e1175bSopenharmony_ci        return;
3433a8e1175bSopenharmony_ci    }
3434a8e1175bSopenharmony_ci
3435a8e1175bSopenharmony_ci    if (rec_seqnum > ssl->in_window_top) {
3436a8e1175bSopenharmony_ci        /* Update window_top and the contents of the window */
3437a8e1175bSopenharmony_ci        uint64_t shift = rec_seqnum - ssl->in_window_top;
3438a8e1175bSopenharmony_ci
3439a8e1175bSopenharmony_ci        if (shift >= 64) {
3440a8e1175bSopenharmony_ci            ssl->in_window = 1;
3441a8e1175bSopenharmony_ci        } else {
3442a8e1175bSopenharmony_ci            ssl->in_window <<= shift;
3443a8e1175bSopenharmony_ci            ssl->in_window |= 1;
3444a8e1175bSopenharmony_ci        }
3445a8e1175bSopenharmony_ci
3446a8e1175bSopenharmony_ci        ssl->in_window_top = rec_seqnum;
3447a8e1175bSopenharmony_ci    } else {
3448a8e1175bSopenharmony_ci        /* Mark that number as seen in the current window */
3449a8e1175bSopenharmony_ci        uint64_t bit = ssl->in_window_top - rec_seqnum;
3450a8e1175bSopenharmony_ci
3451a8e1175bSopenharmony_ci        if (bit < 64) { /* Always true, but be extra sure */
3452a8e1175bSopenharmony_ci            ssl->in_window |= (uint64_t) 1 << bit;
3453a8e1175bSopenharmony_ci        }
3454a8e1175bSopenharmony_ci    }
3455a8e1175bSopenharmony_ci}
3456a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
3457a8e1175bSopenharmony_ci
3458a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
3459a8e1175bSopenharmony_ci/*
3460a8e1175bSopenharmony_ci * Check if a datagram looks like a ClientHello with a valid cookie,
3461a8e1175bSopenharmony_ci * and if it doesn't, generate a HelloVerifyRequest message.
3462a8e1175bSopenharmony_ci * Both input and output include full DTLS headers.
3463a8e1175bSopenharmony_ci *
3464a8e1175bSopenharmony_ci * - if cookie is valid, return 0
3465a8e1175bSopenharmony_ci * - if ClientHello looks superficially valid but cookie is not,
3466a8e1175bSopenharmony_ci *   fill obuf and set olen, then
3467a8e1175bSopenharmony_ci *   return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
3468a8e1175bSopenharmony_ci * - otherwise return a specific error code
3469a8e1175bSopenharmony_ci */
3470a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3471a8e1175bSopenharmony_ciMBEDTLS_STATIC_TESTABLE
3472a8e1175bSopenharmony_ciint mbedtls_ssl_check_dtls_clihlo_cookie(
3473a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl,
3474a8e1175bSopenharmony_ci    const unsigned char *cli_id, size_t cli_id_len,
3475a8e1175bSopenharmony_ci    const unsigned char *in, size_t in_len,
3476a8e1175bSopenharmony_ci    unsigned char *obuf, size_t buf_len, size_t *olen)
3477a8e1175bSopenharmony_ci{
3478a8e1175bSopenharmony_ci    size_t sid_len, cookie_len, epoch, fragment_offset;
3479a8e1175bSopenharmony_ci    unsigned char *p;
3480a8e1175bSopenharmony_ci
3481a8e1175bSopenharmony_ci    /*
3482a8e1175bSopenharmony_ci     * Structure of ClientHello with record and handshake headers,
3483a8e1175bSopenharmony_ci     * and expected values. We don't need to check a lot, more checks will be
3484a8e1175bSopenharmony_ci     * done when actually parsing the ClientHello - skipping those checks
3485a8e1175bSopenharmony_ci     * avoids code duplication and does not make cookie forging any easier.
3486a8e1175bSopenharmony_ci     *
3487a8e1175bSopenharmony_ci     *  0-0  ContentType type;                  copied, must be handshake
3488a8e1175bSopenharmony_ci     *  1-2  ProtocolVersion version;           copied
3489a8e1175bSopenharmony_ci     *  3-4  uint16 epoch;                      copied, must be 0
3490a8e1175bSopenharmony_ci     *  5-10 uint48 sequence_number;            copied
3491a8e1175bSopenharmony_ci     * 11-12 uint16 length;                     (ignored)
3492a8e1175bSopenharmony_ci     *
3493a8e1175bSopenharmony_ci     * 13-13 HandshakeType msg_type;            (ignored)
3494a8e1175bSopenharmony_ci     * 14-16 uint24 length;                     (ignored)
3495a8e1175bSopenharmony_ci     * 17-18 uint16 message_seq;                copied
3496a8e1175bSopenharmony_ci     * 19-21 uint24 fragment_offset;            copied, must be 0
3497a8e1175bSopenharmony_ci     * 22-24 uint24 fragment_length;            (ignored)
3498a8e1175bSopenharmony_ci     *
3499a8e1175bSopenharmony_ci     * 25-26 ProtocolVersion client_version;    (ignored)
3500a8e1175bSopenharmony_ci     * 27-58 Random random;                     (ignored)
3501a8e1175bSopenharmony_ci     * 59-xx SessionID session_id;              1 byte len + sid_len content
3502a8e1175bSopenharmony_ci     * 60+   opaque cookie<0..2^8-1>;           1 byte len + content
3503a8e1175bSopenharmony_ci     *       ...
3504a8e1175bSopenharmony_ci     *
3505a8e1175bSopenharmony_ci     * Minimum length is 61 bytes.
3506a8e1175bSopenharmony_ci     */
3507a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: in_len=%u",
3508a8e1175bSopenharmony_ci                              (unsigned) in_len));
3509a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "cli_id", cli_id, cli_id_len);
3510a8e1175bSopenharmony_ci    if (in_len < 61) {
3511a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: record too short"));
3512a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
3513a8e1175bSopenharmony_ci    }
3514a8e1175bSopenharmony_ci
3515a8e1175bSopenharmony_ci    epoch = MBEDTLS_GET_UINT16_BE(in, 3);
3516a8e1175bSopenharmony_ci    fragment_offset = MBEDTLS_GET_UINT24_BE(in, 19);
3517a8e1175bSopenharmony_ci
3518a8e1175bSopenharmony_ci    if (in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 ||
3519a8e1175bSopenharmony_ci        fragment_offset != 0) {
3520a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: not a good ClientHello"));
3521a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("    type=%u epoch=%u fragment_offset=%u",
3522a8e1175bSopenharmony_ci                                  in[0], (unsigned) epoch,
3523a8e1175bSopenharmony_ci                                  (unsigned) fragment_offset));
3524a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
3525a8e1175bSopenharmony_ci    }
3526a8e1175bSopenharmony_ci
3527a8e1175bSopenharmony_ci    sid_len = in[59];
3528a8e1175bSopenharmony_ci    if (59 + 1 + sid_len + 1 > in_len) {
3529a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: sid_len=%u > %u",
3530a8e1175bSopenharmony_ci                                  (unsigned) sid_len,
3531a8e1175bSopenharmony_ci                                  (unsigned) in_len - 61));
3532a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
3533a8e1175bSopenharmony_ci    }
3534a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "sid received from network",
3535a8e1175bSopenharmony_ci                          in + 60, sid_len);
3536a8e1175bSopenharmony_ci
3537a8e1175bSopenharmony_ci    cookie_len = in[60 + sid_len];
3538a8e1175bSopenharmony_ci    if (59 + 1 + sid_len + 1 + cookie_len > in_len) {
3539a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: cookie_len=%u > %u",
3540a8e1175bSopenharmony_ci                                  (unsigned) cookie_len,
3541a8e1175bSopenharmony_ci                                  (unsigned) (in_len - sid_len - 61)));
3542a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
3543a8e1175bSopenharmony_ci    }
3544a8e1175bSopenharmony_ci
3545a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "cookie received from network",
3546a8e1175bSopenharmony_ci                          in + sid_len + 61, cookie_len);
3547a8e1175bSopenharmony_ci    if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
3548a8e1175bSopenharmony_ci                                  in + sid_len + 61, cookie_len,
3549a8e1175bSopenharmony_ci                                  cli_id, cli_id_len) == 0) {
3550a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: valid"));
3551a8e1175bSopenharmony_ci        return 0;
3552a8e1175bSopenharmony_ci    }
3553a8e1175bSopenharmony_ci
3554a8e1175bSopenharmony_ci    /*
3555a8e1175bSopenharmony_ci     * If we get here, we've got an invalid cookie, let's prepare HVR.
3556a8e1175bSopenharmony_ci     *
3557a8e1175bSopenharmony_ci     *  0-0  ContentType type;                  copied
3558a8e1175bSopenharmony_ci     *  1-2  ProtocolVersion version;           copied
3559a8e1175bSopenharmony_ci     *  3-4  uint16 epoch;                      copied
3560a8e1175bSopenharmony_ci     *  5-10 uint48 sequence_number;            copied
3561a8e1175bSopenharmony_ci     * 11-12 uint16 length;                     olen - 13
3562a8e1175bSopenharmony_ci     *
3563a8e1175bSopenharmony_ci     * 13-13 HandshakeType msg_type;            hello_verify_request
3564a8e1175bSopenharmony_ci     * 14-16 uint24 length;                     olen - 25
3565a8e1175bSopenharmony_ci     * 17-18 uint16 message_seq;                copied
3566a8e1175bSopenharmony_ci     * 19-21 uint24 fragment_offset;            copied
3567a8e1175bSopenharmony_ci     * 22-24 uint24 fragment_length;            olen - 25
3568a8e1175bSopenharmony_ci     *
3569a8e1175bSopenharmony_ci     * 25-26 ProtocolVersion server_version;    0xfe 0xff
3570a8e1175bSopenharmony_ci     * 27-27 opaque cookie<0..2^8-1>;           cookie_len = olen - 27, cookie
3571a8e1175bSopenharmony_ci     *
3572a8e1175bSopenharmony_ci     * Minimum length is 28.
3573a8e1175bSopenharmony_ci     */
3574a8e1175bSopenharmony_ci    if (buf_len < 28) {
3575a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
3576a8e1175bSopenharmony_ci    }
3577a8e1175bSopenharmony_ci
3578a8e1175bSopenharmony_ci    /* Copy most fields and adapt others */
3579a8e1175bSopenharmony_ci    memcpy(obuf, in, 25);
3580a8e1175bSopenharmony_ci    obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
3581a8e1175bSopenharmony_ci    obuf[25] = 0xfe;
3582a8e1175bSopenharmony_ci    obuf[26] = 0xff;
3583a8e1175bSopenharmony_ci
3584a8e1175bSopenharmony_ci    /* Generate and write actual cookie */
3585a8e1175bSopenharmony_ci    p = obuf + 28;
3586a8e1175bSopenharmony_ci    if (ssl->conf->f_cookie_write(ssl->conf->p_cookie,
3587a8e1175bSopenharmony_ci                                  &p, obuf + buf_len,
3588a8e1175bSopenharmony_ci                                  cli_id, cli_id_len) != 0) {
3589a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3590a8e1175bSopenharmony_ci    }
3591a8e1175bSopenharmony_ci
3592a8e1175bSopenharmony_ci    *olen = (size_t) (p - obuf);
3593a8e1175bSopenharmony_ci
3594a8e1175bSopenharmony_ci    /* Go back and fill length fields */
3595a8e1175bSopenharmony_ci    obuf[27] = (unsigned char) (*olen - 28);
3596a8e1175bSopenharmony_ci
3597a8e1175bSopenharmony_ci    obuf[14] = obuf[22] = MBEDTLS_BYTE_2(*olen - 25);
3598a8e1175bSopenharmony_ci    obuf[15] = obuf[23] = MBEDTLS_BYTE_1(*olen - 25);
3599a8e1175bSopenharmony_ci    obuf[16] = obuf[24] = MBEDTLS_BYTE_0(*olen - 25);
3600a8e1175bSopenharmony_ci
3601a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(*olen - 13, obuf, 11);
3602a8e1175bSopenharmony_ci
3603a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
3604a8e1175bSopenharmony_ci}
3605a8e1175bSopenharmony_ci
3606a8e1175bSopenharmony_ci/*
3607a8e1175bSopenharmony_ci * Handle possible client reconnect with the same UDP quadruplet
3608a8e1175bSopenharmony_ci * (RFC 6347 Section 4.2.8).
3609a8e1175bSopenharmony_ci *
3610a8e1175bSopenharmony_ci * Called by ssl_parse_record_header() in case we receive an epoch 0 record
3611a8e1175bSopenharmony_ci * that looks like a ClientHello.
3612a8e1175bSopenharmony_ci *
3613a8e1175bSopenharmony_ci * - if the input looks like a ClientHello without cookies,
3614a8e1175bSopenharmony_ci *   send back HelloVerifyRequest, then return 0
3615a8e1175bSopenharmony_ci * - if the input looks like a ClientHello with a valid cookie,
3616a8e1175bSopenharmony_ci *   reset the session of the current context, and
3617a8e1175bSopenharmony_ci *   return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
3618a8e1175bSopenharmony_ci * - if anything goes wrong, return a specific error code
3619a8e1175bSopenharmony_ci *
3620a8e1175bSopenharmony_ci * This function is called (through ssl_check_client_reconnect()) when an
3621a8e1175bSopenharmony_ci * unexpected record is found in ssl_get_next_record(), which will discard the
3622a8e1175bSopenharmony_ci * record if we return 0, and bubble up the return value otherwise (this
3623a8e1175bSopenharmony_ci * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
3624a8e1175bSopenharmony_ci * errors, and is the right thing to do in both cases).
3625a8e1175bSopenharmony_ci */
3626a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3627a8e1175bSopenharmony_cistatic int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl)
3628a8e1175bSopenharmony_ci{
3629a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3630a8e1175bSopenharmony_ci    size_t len = 0;
3631a8e1175bSopenharmony_ci
3632a8e1175bSopenharmony_ci    if (ssl->conf->f_cookie_write == NULL ||
3633a8e1175bSopenharmony_ci        ssl->conf->f_cookie_check == NULL) {
3634a8e1175bSopenharmony_ci        /* If we can't use cookies to verify reachability of the peer,
3635a8e1175bSopenharmony_ci         * drop the record. */
3636a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, "
3637a8e1175bSopenharmony_ci                                  "can't check reconnect validity"));
3638a8e1175bSopenharmony_ci        return 0;
3639a8e1175bSopenharmony_ci    }
3640a8e1175bSopenharmony_ci
3641a8e1175bSopenharmony_ci    ret = mbedtls_ssl_check_dtls_clihlo_cookie(
3642a8e1175bSopenharmony_ci        ssl,
3643a8e1175bSopenharmony_ci        ssl->cli_id, ssl->cli_id_len,
3644a8e1175bSopenharmony_ci        ssl->in_buf, ssl->in_left,
3645a8e1175bSopenharmony_ci        ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len);
3646a8e1175bSopenharmony_ci
3647a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret);
3648a8e1175bSopenharmony_ci
3649a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
3650a8e1175bSopenharmony_ci        int send_ret;
3651a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest"));
3652a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
3653a8e1175bSopenharmony_ci                              ssl->out_buf, len);
3654a8e1175bSopenharmony_ci        /* Don't check write errors as we can't do anything here.
3655a8e1175bSopenharmony_ci         * If the error is permanent we'll catch it later,
3656a8e1175bSopenharmony_ci         * if it's not, then hopefully it'll work next time. */
3657a8e1175bSopenharmony_ci        send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len);
3658a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret);
3659a8e1175bSopenharmony_ci        (void) send_ret;
3660a8e1175bSopenharmony_ci
3661a8e1175bSopenharmony_ci        return 0;
3662a8e1175bSopenharmony_ci    }
3663a8e1175bSopenharmony_ci
3664a8e1175bSopenharmony_ci    if (ret == 0) {
3665a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context"));
3666a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) {
3667a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "reset", ret);
3668a8e1175bSopenharmony_ci            return ret;
3669a8e1175bSopenharmony_ci        }
3670a8e1175bSopenharmony_ci
3671a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_CLIENT_RECONNECT;
3672a8e1175bSopenharmony_ci    }
3673a8e1175bSopenharmony_ci
3674a8e1175bSopenharmony_ci    return ret;
3675a8e1175bSopenharmony_ci}
3676a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
3677a8e1175bSopenharmony_ci
3678a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3679a8e1175bSopenharmony_cistatic int ssl_check_record_type(uint8_t record_type)
3680a8e1175bSopenharmony_ci{
3681a8e1175bSopenharmony_ci    if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
3682a8e1175bSopenharmony_ci        record_type != MBEDTLS_SSL_MSG_ALERT &&
3683a8e1175bSopenharmony_ci        record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
3684a8e1175bSopenharmony_ci        record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
3685a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
3686a8e1175bSopenharmony_ci    }
3687a8e1175bSopenharmony_ci
3688a8e1175bSopenharmony_ci    return 0;
3689a8e1175bSopenharmony_ci}
3690a8e1175bSopenharmony_ci
3691a8e1175bSopenharmony_ci/*
3692a8e1175bSopenharmony_ci * ContentType type;
3693a8e1175bSopenharmony_ci * ProtocolVersion version;
3694a8e1175bSopenharmony_ci * uint16 epoch;            // DTLS only
3695a8e1175bSopenharmony_ci * uint48 sequence_number;  // DTLS only
3696a8e1175bSopenharmony_ci * uint16 length;
3697a8e1175bSopenharmony_ci *
3698a8e1175bSopenharmony_ci * Return 0 if header looks sane (and, for DTLS, the record is expected)
3699a8e1175bSopenharmony_ci * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
3700a8e1175bSopenharmony_ci * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
3701a8e1175bSopenharmony_ci *
3702a8e1175bSopenharmony_ci * With DTLS, mbedtls_ssl_read_record() will:
3703a8e1175bSopenharmony_ci * 1. proceed with the record if this function returns 0
3704a8e1175bSopenharmony_ci * 2. drop only the current record if this function returns UNEXPECTED_RECORD
3705a8e1175bSopenharmony_ci * 3. return CLIENT_RECONNECT if this function return that value
3706a8e1175bSopenharmony_ci * 4. drop the whole datagram if this function returns anything else.
3707a8e1175bSopenharmony_ci * Point 2 is needed when the peer is resending, and we have already received
3708a8e1175bSopenharmony_ci * the first record from a datagram but are still waiting for the others.
3709a8e1175bSopenharmony_ci */
3710a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3711a8e1175bSopenharmony_cistatic int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
3712a8e1175bSopenharmony_ci                                   unsigned char *buf,
3713a8e1175bSopenharmony_ci                                   size_t len,
3714a8e1175bSopenharmony_ci                                   mbedtls_record *rec)
3715a8e1175bSopenharmony_ci{
3716a8e1175bSopenharmony_ci    mbedtls_ssl_protocol_version tls_version;
3717a8e1175bSopenharmony_ci
3718a8e1175bSopenharmony_ci    size_t const rec_hdr_type_offset    = 0;
3719a8e1175bSopenharmony_ci    size_t const rec_hdr_type_len       = 1;
3720a8e1175bSopenharmony_ci
3721a8e1175bSopenharmony_ci    size_t const rec_hdr_version_offset = rec_hdr_type_offset +
3722a8e1175bSopenharmony_ci                                          rec_hdr_type_len;
3723a8e1175bSopenharmony_ci    size_t const rec_hdr_version_len    = 2;
3724a8e1175bSopenharmony_ci
3725a8e1175bSopenharmony_ci    size_t const rec_hdr_ctr_len        = 8;
3726a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3727a8e1175bSopenharmony_ci    uint32_t     rec_epoch;
3728a8e1175bSopenharmony_ci    size_t const rec_hdr_ctr_offset     = rec_hdr_version_offset +
3729a8e1175bSopenharmony_ci                                          rec_hdr_version_len;
3730a8e1175bSopenharmony_ci
3731a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3732a8e1175bSopenharmony_ci    size_t const rec_hdr_cid_offset     = rec_hdr_ctr_offset +
3733a8e1175bSopenharmony_ci                                          rec_hdr_ctr_len;
3734a8e1175bSopenharmony_ci    size_t       rec_hdr_cid_len        = 0;
3735a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3736a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3737a8e1175bSopenharmony_ci
3738a8e1175bSopenharmony_ci    size_t       rec_hdr_len_offset; /* To be determined */
3739a8e1175bSopenharmony_ci    size_t const rec_hdr_len_len    = 2;
3740a8e1175bSopenharmony_ci
3741a8e1175bSopenharmony_ci    /*
3742a8e1175bSopenharmony_ci     * Check minimum lengths for record header.
3743a8e1175bSopenharmony_ci     */
3744a8e1175bSopenharmony_ci
3745a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3746a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3747a8e1175bSopenharmony_ci        rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
3748a8e1175bSopenharmony_ci    } else
3749a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3750a8e1175bSopenharmony_ci    {
3751a8e1175bSopenharmony_ci        rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
3752a8e1175bSopenharmony_ci    }
3753a8e1175bSopenharmony_ci
3754a8e1175bSopenharmony_ci    if (len < rec_hdr_len_offset + rec_hdr_len_len) {
3755a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1,
3756a8e1175bSopenharmony_ci                              (
3757a8e1175bSopenharmony_ci                                  "datagram of length %u too small to hold DTLS record header of length %u",
3758a8e1175bSopenharmony_ci                                  (unsigned) len,
3759a8e1175bSopenharmony_ci                                  (unsigned) (rec_hdr_len_len + rec_hdr_len_len)));
3760a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
3761a8e1175bSopenharmony_ci    }
3762a8e1175bSopenharmony_ci
3763a8e1175bSopenharmony_ci    /*
3764a8e1175bSopenharmony_ci     * Parse and validate record content type
3765a8e1175bSopenharmony_ci     */
3766a8e1175bSopenharmony_ci
3767a8e1175bSopenharmony_ci    rec->type = buf[rec_hdr_type_offset];
3768a8e1175bSopenharmony_ci
3769a8e1175bSopenharmony_ci    /* Check record content type */
3770a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3771a8e1175bSopenharmony_ci    rec->cid_len = 0;
3772a8e1175bSopenharmony_ci
3773a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3774a8e1175bSopenharmony_ci        ssl->conf->cid_len != 0                                &&
3775a8e1175bSopenharmony_ci        rec->type == MBEDTLS_SSL_MSG_CID) {
3776a8e1175bSopenharmony_ci        /* Shift pointers to account for record header including CID
3777a8e1175bSopenharmony_ci         * struct {
3778a8e1175bSopenharmony_ci         *   ContentType outer_type = tls12_cid;
3779a8e1175bSopenharmony_ci         *   ProtocolVersion version;
3780a8e1175bSopenharmony_ci         *   uint16 epoch;
3781a8e1175bSopenharmony_ci         *   uint48 sequence_number;
3782a8e1175bSopenharmony_ci         *   opaque cid[cid_length]; // Additional field compared to
3783a8e1175bSopenharmony_ci         *                           // default DTLS record format
3784a8e1175bSopenharmony_ci         *   uint16 length;
3785a8e1175bSopenharmony_ci         *   opaque enc_content[DTLSCiphertext.length];
3786a8e1175bSopenharmony_ci         * } DTLSCiphertext;
3787a8e1175bSopenharmony_ci         */
3788a8e1175bSopenharmony_ci
3789a8e1175bSopenharmony_ci        /* So far, we only support static CID lengths
3790a8e1175bSopenharmony_ci         * fixed in the configuration. */
3791a8e1175bSopenharmony_ci        rec_hdr_cid_len = ssl->conf->cid_len;
3792a8e1175bSopenharmony_ci        rec_hdr_len_offset += rec_hdr_cid_len;
3793a8e1175bSopenharmony_ci
3794a8e1175bSopenharmony_ci        if (len < rec_hdr_len_offset + rec_hdr_len_len) {
3795a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
3796a8e1175bSopenharmony_ci                                  (
3797a8e1175bSopenharmony_ci                                      "datagram of length %u too small to hold DTLS record header including CID, length %u",
3798a8e1175bSopenharmony_ci                                      (unsigned) len,
3799a8e1175bSopenharmony_ci                                      (unsigned) (rec_hdr_len_offset + rec_hdr_len_len)));
3800a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
3801a8e1175bSopenharmony_ci        }
3802a8e1175bSopenharmony_ci
3803a8e1175bSopenharmony_ci        /* configured CID len is guaranteed at most 255, see
3804a8e1175bSopenharmony_ci         * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
3805a8e1175bSopenharmony_ci        rec->cid_len = (uint8_t) rec_hdr_cid_len;
3806a8e1175bSopenharmony_ci        memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len);
3807a8e1175bSopenharmony_ci    } else
3808a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3809a8e1175bSopenharmony_ci    {
3810a8e1175bSopenharmony_ci        if (ssl_check_record_type(rec->type)) {
3811a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u",
3812a8e1175bSopenharmony_ci                                      (unsigned) rec->type));
3813a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
3814a8e1175bSopenharmony_ci        }
3815a8e1175bSopenharmony_ci    }
3816a8e1175bSopenharmony_ci
3817a8e1175bSopenharmony_ci    /*
3818a8e1175bSopenharmony_ci     * Parse and validate record version
3819a8e1175bSopenharmony_ci     */
3820a8e1175bSopenharmony_ci    rec->ver[0] = buf[rec_hdr_version_offset + 0];
3821a8e1175bSopenharmony_ci    rec->ver[1] = buf[rec_hdr_version_offset + 1];
3822a8e1175bSopenharmony_ci    tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(
3823a8e1175bSopenharmony_ci        buf + rec_hdr_version_offset,
3824a8e1175bSopenharmony_ci        ssl->conf->transport);
3825a8e1175bSopenharmony_ci
3826a8e1175bSopenharmony_ci    if (tls_version > ssl->conf->max_tls_version) {
3827a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u",
3828a8e1175bSopenharmony_ci                                  (unsigned) tls_version,
3829a8e1175bSopenharmony_ci                                  (unsigned) ssl->conf->max_tls_version));
3830a8e1175bSopenharmony_ci
3831a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
3832a8e1175bSopenharmony_ci    }
3833a8e1175bSopenharmony_ci    /*
3834a8e1175bSopenharmony_ci     * Parse/Copy record sequence number.
3835a8e1175bSopenharmony_ci     */
3836a8e1175bSopenharmony_ci
3837a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3838a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3839a8e1175bSopenharmony_ci        /* Copy explicit record sequence number from input buffer. */
3840a8e1175bSopenharmony_ci        memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset,
3841a8e1175bSopenharmony_ci               rec_hdr_ctr_len);
3842a8e1175bSopenharmony_ci    } else
3843a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3844a8e1175bSopenharmony_ci    {
3845a8e1175bSopenharmony_ci        /* Copy implicit record sequence number from SSL context structure. */
3846a8e1175bSopenharmony_ci        memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len);
3847a8e1175bSopenharmony_ci    }
3848a8e1175bSopenharmony_ci
3849a8e1175bSopenharmony_ci    /*
3850a8e1175bSopenharmony_ci     * Parse record length.
3851a8e1175bSopenharmony_ci     */
3852a8e1175bSopenharmony_ci
3853a8e1175bSopenharmony_ci    rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
3854a8e1175bSopenharmony_ci    rec->data_len    = MBEDTLS_GET_UINT16_BE(buf, rec_hdr_len_offset);
3855a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset);
3856a8e1175bSopenharmony_ci
3857a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, "
3858a8e1175bSopenharmony_ci                              "version = [0x%x], msglen = %" MBEDTLS_PRINTF_SIZET,
3859a8e1175bSopenharmony_ci                              rec->type, (unsigned) tls_version, rec->data_len));
3860a8e1175bSopenharmony_ci
3861a8e1175bSopenharmony_ci    rec->buf     = buf;
3862a8e1175bSopenharmony_ci    rec->buf_len = rec->data_offset + rec->data_len;
3863a8e1175bSopenharmony_ci
3864a8e1175bSopenharmony_ci    if (rec->data_len == 0) {
3865a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
3866a8e1175bSopenharmony_ci    }
3867a8e1175bSopenharmony_ci
3868a8e1175bSopenharmony_ci    /*
3869a8e1175bSopenharmony_ci     * DTLS-related tests.
3870a8e1175bSopenharmony_ci     * Check epoch before checking length constraint because
3871a8e1175bSopenharmony_ci     * the latter varies with the epoch. E.g., if a ChangeCipherSpec
3872a8e1175bSopenharmony_ci     * message gets duplicated before the corresponding Finished message,
3873a8e1175bSopenharmony_ci     * the second ChangeCipherSpec should be discarded because it belongs
3874a8e1175bSopenharmony_ci     * to an old epoch, but not because its length is shorter than
3875a8e1175bSopenharmony_ci     * the minimum record length for packets using the new record transform.
3876a8e1175bSopenharmony_ci     * Note that these two kinds of failures are handled differently,
3877a8e1175bSopenharmony_ci     * as an unexpected record is silently skipped but an invalid
3878a8e1175bSopenharmony_ci     * record leads to the entire datagram being dropped.
3879a8e1175bSopenharmony_ci     */
3880a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3881a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3882a8e1175bSopenharmony_ci        rec_epoch = MBEDTLS_GET_UINT16_BE(rec->ctr, 0);
3883a8e1175bSopenharmony_ci
3884a8e1175bSopenharmony_ci        /* Check that the datagram is large enough to contain a record
3885a8e1175bSopenharmony_ci         * of the advertised length. */
3886a8e1175bSopenharmony_ci        if (len < rec->data_offset + rec->data_len) {
3887a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
3888a8e1175bSopenharmony_ci                                  (
3889a8e1175bSopenharmony_ci                                      "Datagram of length %u too small to contain record of advertised length %u.",
3890a8e1175bSopenharmony_ci                                      (unsigned) len,
3891a8e1175bSopenharmony_ci                                      (unsigned) (rec->data_offset + rec->data_len)));
3892a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
3893a8e1175bSopenharmony_ci        }
3894a8e1175bSopenharmony_ci
3895a8e1175bSopenharmony_ci        /* Records from other, non-matching epochs are silently discarded.
3896a8e1175bSopenharmony_ci         * (The case of same-port Client reconnects must be considered in
3897a8e1175bSopenharmony_ci         *  the caller). */
3898a8e1175bSopenharmony_ci        if (rec_epoch != ssl->in_epoch) {
3899a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: "
3900a8e1175bSopenharmony_ci                                      "expected %u, received %lu",
3901a8e1175bSopenharmony_ci                                      ssl->in_epoch, (unsigned long) rec_epoch));
3902a8e1175bSopenharmony_ci
3903a8e1175bSopenharmony_ci            /* Records from the next epoch are considered for buffering
3904a8e1175bSopenharmony_ci             * (concretely: early Finished messages). */
3905a8e1175bSopenharmony_ci            if (rec_epoch == (unsigned) ssl->in_epoch + 1) {
3906a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering"));
3907a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
3908a8e1175bSopenharmony_ci            }
3909a8e1175bSopenharmony_ci
3910a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
3911a8e1175bSopenharmony_ci        }
3912a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3913a8e1175bSopenharmony_ci        /* For records from the correct epoch, check whether their
3914a8e1175bSopenharmony_ci         * sequence number has been seen before. */
3915a8e1175bSopenharmony_ci        else if (mbedtls_ssl_dtls_record_replay_check((mbedtls_ssl_context *) ssl,
3916a8e1175bSopenharmony_ci                                                      &rec->ctr[0]) != 0) {
3917a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record"));
3918a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
3919a8e1175bSopenharmony_ci        }
3920a8e1175bSopenharmony_ci#endif
3921a8e1175bSopenharmony_ci    }
3922a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3923a8e1175bSopenharmony_ci
3924a8e1175bSopenharmony_ci    return 0;
3925a8e1175bSopenharmony_ci}
3926a8e1175bSopenharmony_ci
3927a8e1175bSopenharmony_ci
3928a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
3929a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3930a8e1175bSopenharmony_cistatic int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
3931a8e1175bSopenharmony_ci{
3932a8e1175bSopenharmony_ci    unsigned int rec_epoch = MBEDTLS_GET_UINT16_BE(ssl->in_ctr, 0);
3933a8e1175bSopenharmony_ci
3934a8e1175bSopenharmony_ci    /*
3935a8e1175bSopenharmony_ci     * Check for an epoch 0 ClientHello. We can't use in_msg here to
3936a8e1175bSopenharmony_ci     * access the first byte of record content (handshake type), as we
3937a8e1175bSopenharmony_ci     * have an active transform (possibly iv_len != 0), so use the
3938a8e1175bSopenharmony_ci     * fact that the record header len is 13 instead.
3939a8e1175bSopenharmony_ci     */
3940a8e1175bSopenharmony_ci    if (rec_epoch == 0 &&
3941a8e1175bSopenharmony_ci        ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
3942a8e1175bSopenharmony_ci        mbedtls_ssl_is_handshake_over(ssl) == 1 &&
3943a8e1175bSopenharmony_ci        ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
3944a8e1175bSopenharmony_ci        ssl->in_left > 13 &&
3945a8e1175bSopenharmony_ci        ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) {
3946a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect "
3947a8e1175bSopenharmony_ci                                  "from the same port"));
3948a8e1175bSopenharmony_ci        return ssl_handle_possible_reconnect(ssl);
3949a8e1175bSopenharmony_ci    }
3950a8e1175bSopenharmony_ci
3951a8e1175bSopenharmony_ci    return 0;
3952a8e1175bSopenharmony_ci}
3953a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
3954a8e1175bSopenharmony_ci
3955a8e1175bSopenharmony_ci/*
3956a8e1175bSopenharmony_ci * If applicable, decrypt record content
3957a8e1175bSopenharmony_ci */
3958a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3959a8e1175bSopenharmony_cistatic int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
3960a8e1175bSopenharmony_ci                                      mbedtls_record *rec)
3961a8e1175bSopenharmony_ci{
3962a8e1175bSopenharmony_ci    int ret, done = 0;
3963a8e1175bSopenharmony_ci
3964a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "input record from network",
3965a8e1175bSopenharmony_ci                          rec->buf, rec->buf_len);
3966a8e1175bSopenharmony_ci
3967a8e1175bSopenharmony_ci    /*
3968a8e1175bSopenharmony_ci     * In TLS 1.3, always treat ChangeCipherSpec records
3969a8e1175bSopenharmony_ci     * as unencrypted. The only thing we do with them is
3970a8e1175bSopenharmony_ci     * check the length and content and ignore them.
3971a8e1175bSopenharmony_ci     */
3972a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
3973a8e1175bSopenharmony_ci    if (ssl->transform_in != NULL &&
3974a8e1175bSopenharmony_ci        ssl->transform_in->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
3975a8e1175bSopenharmony_ci        if (rec->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
3976a8e1175bSopenharmony_ci            done = 1;
3977a8e1175bSopenharmony_ci        }
3978a8e1175bSopenharmony_ci    }
3979a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
3980a8e1175bSopenharmony_ci
3981a8e1175bSopenharmony_ci    if (!done && ssl->transform_in != NULL) {
3982a8e1175bSopenharmony_ci        unsigned char const old_msg_type = rec->type;
3983a8e1175bSopenharmony_ci
3984a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in,
3985a8e1175bSopenharmony_ci                                           rec)) != 0) {
3986a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret);
3987a8e1175bSopenharmony_ci
3988a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
3989a8e1175bSopenharmony_ci            /*
3990a8e1175bSopenharmony_ci             * Although the server rejected early data, it might receive early
3991a8e1175bSopenharmony_ci             * data as long as it has not received the client Finished message.
3992a8e1175bSopenharmony_ci             * It is encrypted with early keys and should be ignored as stated
3993a8e1175bSopenharmony_ci             * in section 4.2.10 of RFC 8446:
3994a8e1175bSopenharmony_ci             *
3995a8e1175bSopenharmony_ci             * "Ignore the extension and return a regular 1-RTT response. The
3996a8e1175bSopenharmony_ci             * server then skips past early data by attempting to deprotect
3997a8e1175bSopenharmony_ci             * received records using the handshake traffic key, discarding
3998a8e1175bSopenharmony_ci             * records which fail deprotection (up to the configured
3999a8e1175bSopenharmony_ci             * max_early_data_size). Once a record is deprotected successfully,
4000a8e1175bSopenharmony_ci             * it is treated as the start of the client's second flight and the
4001a8e1175bSopenharmony_ci             * server proceeds as with an ordinary 1-RTT handshake."
4002a8e1175bSopenharmony_ci             */
4003a8e1175bSopenharmony_ci            if ((old_msg_type == MBEDTLS_SSL_MSG_APPLICATION_DATA) &&
4004a8e1175bSopenharmony_ci                (ssl->discard_early_data_record ==
4005a8e1175bSopenharmony_ci                 MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
4006a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(
4007a8e1175bSopenharmony_ci                    3, ("EarlyData: deprotect and discard app data records."));
4008a8e1175bSopenharmony_ci
4009a8e1175bSopenharmony_ci                ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4010a8e1175bSopenharmony_ci                if (ret != 0) {
4011a8e1175bSopenharmony_ci                    return ret;
4012a8e1175bSopenharmony_ci                }
4013a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4014a8e1175bSopenharmony_ci            }
4015a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4016a8e1175bSopenharmony_ci
4017a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4018a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
4019a8e1175bSopenharmony_ci                ssl->conf->ignore_unexpected_cid
4020a8e1175bSopenharmony_ci                == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
4021a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID"));
4022a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4023a8e1175bSopenharmony_ci            }
4024a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4025a8e1175bSopenharmony_ci
4026a8e1175bSopenharmony_ci            /*
4027a8e1175bSopenharmony_ci             * The decryption of the record failed, no reason to ignore it,
4028a8e1175bSopenharmony_ci             * return in error with the decryption error code.
4029a8e1175bSopenharmony_ci             */
4030a8e1175bSopenharmony_ci            return ret;
4031a8e1175bSopenharmony_ci        }
4032a8e1175bSopenharmony_ci
4033a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4034a8e1175bSopenharmony_ci        /*
4035a8e1175bSopenharmony_ci         * If the server were discarding protected records that it fails to
4036a8e1175bSopenharmony_ci         * deprotect because it has rejected early data, as we have just
4037a8e1175bSopenharmony_ci         * deprotected successfully a record, the server has to resume normal
4038a8e1175bSopenharmony_ci         * operation and fail the connection if the deprotection of a record
4039a8e1175bSopenharmony_ci         * fails.
4040a8e1175bSopenharmony_ci         */
4041a8e1175bSopenharmony_ci        if (ssl->discard_early_data_record ==
4042a8e1175bSopenharmony_ci            MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD) {
4043a8e1175bSopenharmony_ci            ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4044a8e1175bSopenharmony_ci        }
4045a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4046a8e1175bSopenharmony_ci
4047a8e1175bSopenharmony_ci        if (old_msg_type != rec->type) {
4048a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d",
4049a8e1175bSopenharmony_ci                                      old_msg_type, rec->type));
4050a8e1175bSopenharmony_ci        }
4051a8e1175bSopenharmony_ci
4052a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt",
4053a8e1175bSopenharmony_ci                              rec->buf + rec->data_offset, rec->data_len);
4054a8e1175bSopenharmony_ci
4055a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4056a8e1175bSopenharmony_ci        /* We have already checked the record content type
4057a8e1175bSopenharmony_ci         * in ssl_parse_record_header(), failing or silently
4058a8e1175bSopenharmony_ci         * dropping the record in the case of an unknown type.
4059a8e1175bSopenharmony_ci         *
4060a8e1175bSopenharmony_ci         * Since with the use of CIDs, the record content type
4061a8e1175bSopenharmony_ci         * might change during decryption, re-check the record
4062a8e1175bSopenharmony_ci         * content type, but treat a failure as fatal this time. */
4063a8e1175bSopenharmony_ci        if (ssl_check_record_type(rec->type)) {
4064a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type"));
4065a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
4066a8e1175bSopenharmony_ci        }
4067a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4068a8e1175bSopenharmony_ci
4069a8e1175bSopenharmony_ci        if (rec->data_len == 0) {
4070a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
4071a8e1175bSopenharmony_ci            if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2
4072a8e1175bSopenharmony_ci                && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
4073a8e1175bSopenharmony_ci                /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
4074a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("invalid zero-length message type: %d", ssl->in_msgtype));
4075a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INVALID_RECORD;
4076a8e1175bSopenharmony_ci            }
4077a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
4078a8e1175bSopenharmony_ci
4079a8e1175bSopenharmony_ci            ssl->nb_zero++;
4080a8e1175bSopenharmony_ci
4081a8e1175bSopenharmony_ci            /*
4082a8e1175bSopenharmony_ci             * Three or more empty messages may be a DoS attack
4083a8e1175bSopenharmony_ci             * (excessive CPU consumption).
4084a8e1175bSopenharmony_ci             */
4085a8e1175bSopenharmony_ci            if (ssl->nb_zero > 3) {
4086a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty "
4087a8e1175bSopenharmony_ci                                          "messages, possible DoS attack"));
4088a8e1175bSopenharmony_ci                /* Treat the records as if they were not properly authenticated,
4089a8e1175bSopenharmony_ci                 * thereby failing the connection if we see more than allowed
4090a8e1175bSopenharmony_ci                 * by the configured bad MAC threshold. */
4091a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INVALID_MAC;
4092a8e1175bSopenharmony_ci            }
4093a8e1175bSopenharmony_ci        } else {
4094a8e1175bSopenharmony_ci            ssl->nb_zero = 0;
4095a8e1175bSopenharmony_ci        }
4096a8e1175bSopenharmony_ci
4097a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4098a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4099a8e1175bSopenharmony_ci            ; /* in_ctr read from peer, not maintained internally */
4100a8e1175bSopenharmony_ci        } else
4101a8e1175bSopenharmony_ci#endif
4102a8e1175bSopenharmony_ci        {
4103a8e1175bSopenharmony_ci            unsigned i;
4104a8e1175bSopenharmony_ci            for (i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
4105a8e1175bSopenharmony_ci                 i > mbedtls_ssl_ep_len(ssl); i--) {
4106a8e1175bSopenharmony_ci                if (++ssl->in_ctr[i - 1] != 0) {
4107a8e1175bSopenharmony_ci                    break;
4108a8e1175bSopenharmony_ci                }
4109a8e1175bSopenharmony_ci            }
4110a8e1175bSopenharmony_ci
4111a8e1175bSopenharmony_ci            /* The loop goes to its end iff the counter is wrapping */
4112a8e1175bSopenharmony_ci            if (i == mbedtls_ssl_ep_len(ssl)) {
4113a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("incoming message counter would wrap"));
4114a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
4115a8e1175bSopenharmony_ci            }
4116a8e1175bSopenharmony_ci        }
4117a8e1175bSopenharmony_ci
4118a8e1175bSopenharmony_ci    }
4119a8e1175bSopenharmony_ci
4120a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4121a8e1175bSopenharmony_ci    /*
4122a8e1175bSopenharmony_ci     * Although the server rejected early data because it needed to send an
4123a8e1175bSopenharmony_ci     * HelloRetryRequest message, it might receive early data as long as it has
4124a8e1175bSopenharmony_ci     * not received the client Finished message.
4125a8e1175bSopenharmony_ci     * The early data is encrypted with early keys and should be ignored as
4126a8e1175bSopenharmony_ci     * stated in section 4.2.10 of RFC 8446 (second case):
4127a8e1175bSopenharmony_ci     *
4128a8e1175bSopenharmony_ci     * "The server then ignores early data by skipping all records with an
4129a8e1175bSopenharmony_ci     * external content type of "application_data" (indicating that they are
4130a8e1175bSopenharmony_ci     * encrypted), up to the configured max_early_data_size. Ignore application
4131a8e1175bSopenharmony_ci     * data message before 2nd ClientHello when early_data was received in 1st
4132a8e1175bSopenharmony_ci     * ClientHello."
4133a8e1175bSopenharmony_ci     */
4134a8e1175bSopenharmony_ci    if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
4135a8e1175bSopenharmony_ci        if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
4136a8e1175bSopenharmony_ci
4137a8e1175bSopenharmony_ci            ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4138a8e1175bSopenharmony_ci            if (ret != 0) {
4139a8e1175bSopenharmony_ci                return ret;
4140a8e1175bSopenharmony_ci            }
4141a8e1175bSopenharmony_ci
4142a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(
4143a8e1175bSopenharmony_ci                3, ("EarlyData: Ignore application message before 2nd ClientHello"));
4144a8e1175bSopenharmony_ci
4145a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4146a8e1175bSopenharmony_ci        } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
4147a8e1175bSopenharmony_ci            ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4148a8e1175bSopenharmony_ci        }
4149a8e1175bSopenharmony_ci    }
4150a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4151a8e1175bSopenharmony_ci
4152a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
4153a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4154a8e1175bSopenharmony_ci        mbedtls_ssl_dtls_replay_update(ssl);
4155a8e1175bSopenharmony_ci    }
4156a8e1175bSopenharmony_ci#endif
4157a8e1175bSopenharmony_ci
4158a8e1175bSopenharmony_ci    /* Check actual (decrypted) record content length against
4159a8e1175bSopenharmony_ci     * configured maximum. */
4160a8e1175bSopenharmony_ci    if (rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
4161a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length"));
4162a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INVALID_RECORD;
4163a8e1175bSopenharmony_ci    }
4164a8e1175bSopenharmony_ci
4165a8e1175bSopenharmony_ci    return 0;
4166a8e1175bSopenharmony_ci}
4167a8e1175bSopenharmony_ci
4168a8e1175bSopenharmony_ci/*
4169a8e1175bSopenharmony_ci * Read a record.
4170a8e1175bSopenharmony_ci *
4171a8e1175bSopenharmony_ci * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
4172a8e1175bSopenharmony_ci * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
4173a8e1175bSopenharmony_ci *
4174a8e1175bSopenharmony_ci */
4175a8e1175bSopenharmony_ci
4176a8e1175bSopenharmony_ci/* Helper functions for mbedtls_ssl_read_record(). */
4177a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4178a8e1175bSopenharmony_cistatic int ssl_consume_current_message(mbedtls_ssl_context *ssl);
4179a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4180a8e1175bSopenharmony_cistatic int ssl_get_next_record(mbedtls_ssl_context *ssl);
4181a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4182a8e1175bSopenharmony_cistatic int ssl_record_is_in_progress(mbedtls_ssl_context *ssl);
4183a8e1175bSopenharmony_ci
4184a8e1175bSopenharmony_ciint mbedtls_ssl_read_record(mbedtls_ssl_context *ssl,
4185a8e1175bSopenharmony_ci                            unsigned update_hs_digest)
4186a8e1175bSopenharmony_ci{
4187a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4188a8e1175bSopenharmony_ci
4189a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record"));
4190a8e1175bSopenharmony_ci
4191a8e1175bSopenharmony_ci    if (ssl->keep_current_message == 0) {
4192a8e1175bSopenharmony_ci        do {
4193a8e1175bSopenharmony_ci
4194a8e1175bSopenharmony_ci            ret = ssl_consume_current_message(ssl);
4195a8e1175bSopenharmony_ci            if (ret != 0) {
4196a8e1175bSopenharmony_ci                return ret;
4197a8e1175bSopenharmony_ci            }
4198a8e1175bSopenharmony_ci
4199a8e1175bSopenharmony_ci            if (ssl_record_is_in_progress(ssl) == 0) {
4200a8e1175bSopenharmony_ci                int dtls_have_buffered = 0;
4201a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4202a8e1175bSopenharmony_ci
4203a8e1175bSopenharmony_ci                /* We only check for buffered messages if the
4204a8e1175bSopenharmony_ci                 * current datagram is fully consumed. */
4205a8e1175bSopenharmony_ci                if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
4206a8e1175bSopenharmony_ci                    ssl_next_record_is_in_datagram(ssl) == 0) {
4207a8e1175bSopenharmony_ci                    if (ssl_load_buffered_message(ssl) == 0) {
4208a8e1175bSopenharmony_ci                        dtls_have_buffered = 1;
4209a8e1175bSopenharmony_ci                    }
4210a8e1175bSopenharmony_ci                }
4211a8e1175bSopenharmony_ci
4212a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
4213a8e1175bSopenharmony_ci                if (dtls_have_buffered == 0) {
4214a8e1175bSopenharmony_ci                    ret = ssl_get_next_record(ssl);
4215a8e1175bSopenharmony_ci                    if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) {
4216a8e1175bSopenharmony_ci                        continue;
4217a8e1175bSopenharmony_ci                    }
4218a8e1175bSopenharmony_ci
4219a8e1175bSopenharmony_ci                    if (ret != 0) {
4220a8e1175bSopenharmony_ci                        MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret);
4221a8e1175bSopenharmony_ci                        return ret;
4222a8e1175bSopenharmony_ci                    }
4223a8e1175bSopenharmony_ci                }
4224a8e1175bSopenharmony_ci            }
4225a8e1175bSopenharmony_ci
4226a8e1175bSopenharmony_ci            ret = mbedtls_ssl_handle_message_type(ssl);
4227a8e1175bSopenharmony_ci
4228a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4229a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
4230a8e1175bSopenharmony_ci                /* Buffer future message */
4231a8e1175bSopenharmony_ci                ret = ssl_buffer_message(ssl);
4232a8e1175bSopenharmony_ci                if (ret != 0) {
4233a8e1175bSopenharmony_ci                    return ret;
4234a8e1175bSopenharmony_ci                }
4235a8e1175bSopenharmony_ci
4236a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4237a8e1175bSopenharmony_ci            }
4238a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
4239a8e1175bSopenharmony_ci
4240a8e1175bSopenharmony_ci        } while (MBEDTLS_ERR_SSL_NON_FATAL           == ret  ||
4241a8e1175bSopenharmony_ci                 MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret);
4242a8e1175bSopenharmony_ci
4243a8e1175bSopenharmony_ci        if (0 != ret) {
4244a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret);
4245a8e1175bSopenharmony_ci            return ret;
4246a8e1175bSopenharmony_ci        }
4247a8e1175bSopenharmony_ci
4248a8e1175bSopenharmony_ci        if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
4249a8e1175bSopenharmony_ci            update_hs_digest == 1) {
4250a8e1175bSopenharmony_ci            ret = mbedtls_ssl_update_handshake_status(ssl);
4251a8e1175bSopenharmony_ci            if (0 != ret) {
4252a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
4253a8e1175bSopenharmony_ci                return ret;
4254a8e1175bSopenharmony_ci            }
4255a8e1175bSopenharmony_ci        }
4256a8e1175bSopenharmony_ci    } else {
4257a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message"));
4258a8e1175bSopenharmony_ci        ssl->keep_current_message = 0;
4259a8e1175bSopenharmony_ci    }
4260a8e1175bSopenharmony_ci
4261a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record"));
4262a8e1175bSopenharmony_ci
4263a8e1175bSopenharmony_ci    return 0;
4264a8e1175bSopenharmony_ci}
4265a8e1175bSopenharmony_ci
4266a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4267a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4268a8e1175bSopenharmony_cistatic int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl)
4269a8e1175bSopenharmony_ci{
4270a8e1175bSopenharmony_ci    if (ssl->in_left > ssl->next_record_offset) {
4271a8e1175bSopenharmony_ci        return 1;
4272a8e1175bSopenharmony_ci    }
4273a8e1175bSopenharmony_ci
4274a8e1175bSopenharmony_ci    return 0;
4275a8e1175bSopenharmony_ci}
4276a8e1175bSopenharmony_ci
4277a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4278a8e1175bSopenharmony_cistatic int ssl_load_buffered_message(mbedtls_ssl_context *ssl)
4279a8e1175bSopenharmony_ci{
4280a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4281a8e1175bSopenharmony_ci    mbedtls_ssl_hs_buffer *hs_buf;
4282a8e1175bSopenharmony_ci    int ret = 0;
4283a8e1175bSopenharmony_ci
4284a8e1175bSopenharmony_ci    if (hs == NULL) {
4285a8e1175bSopenharmony_ci        return -1;
4286a8e1175bSopenharmony_ci    }
4287a8e1175bSopenharmony_ci
4288a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_message"));
4289a8e1175bSopenharmony_ci
4290a8e1175bSopenharmony_ci    if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
4291a8e1175bSopenharmony_ci        ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
4292a8e1175bSopenharmony_ci        /* Check if we have seen a ChangeCipherSpec before.
4293a8e1175bSopenharmony_ci         * If yes, synthesize a CCS record. */
4294a8e1175bSopenharmony_ci        if (!hs->buffering.seen_ccs) {
4295a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight"));
4296a8e1175bSopenharmony_ci            ret = -1;
4297a8e1175bSopenharmony_ci            goto exit;
4298a8e1175bSopenharmony_ci        }
4299a8e1175bSopenharmony_ci
4300a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message"));
4301a8e1175bSopenharmony_ci        ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
4302a8e1175bSopenharmony_ci        ssl->in_msglen = 1;
4303a8e1175bSopenharmony_ci        ssl->in_msg[0] = 1;
4304a8e1175bSopenharmony_ci
4305a8e1175bSopenharmony_ci        /* As long as they are equal, the exact value doesn't matter. */
4306a8e1175bSopenharmony_ci        ssl->in_left            = 0;
4307a8e1175bSopenharmony_ci        ssl->next_record_offset = 0;
4308a8e1175bSopenharmony_ci
4309a8e1175bSopenharmony_ci        hs->buffering.seen_ccs = 0;
4310a8e1175bSopenharmony_ci        goto exit;
4311a8e1175bSopenharmony_ci    }
4312a8e1175bSopenharmony_ci
4313a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C)
4314a8e1175bSopenharmony_ci    /* Debug only */
4315a8e1175bSopenharmony_ci    {
4316a8e1175bSopenharmony_ci        unsigned offset;
4317a8e1175bSopenharmony_ci        for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
4318a8e1175bSopenharmony_ci            hs_buf = &hs->buffering.hs[offset];
4319a8e1175bSopenharmony_ci            if (hs_buf->is_valid == 1) {
4320a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("Future message with sequence number %u %s buffered.",
4321a8e1175bSopenharmony_ci                                          hs->in_msg_seq + offset,
4322a8e1175bSopenharmony_ci                                          hs_buf->is_complete ? "fully" : "partially"));
4323a8e1175bSopenharmony_ci            }
4324a8e1175bSopenharmony_ci        }
4325a8e1175bSopenharmony_ci    }
4326a8e1175bSopenharmony_ci#endif /* MBEDTLS_DEBUG_C */
4327a8e1175bSopenharmony_ci
4328a8e1175bSopenharmony_ci    /* Check if we have buffered and/or fully reassembled the
4329a8e1175bSopenharmony_ci     * next handshake message. */
4330a8e1175bSopenharmony_ci    hs_buf = &hs->buffering.hs[0];
4331a8e1175bSopenharmony_ci    if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) {
4332a8e1175bSopenharmony_ci        /* Synthesize a record containing the buffered HS message. */
4333a8e1175bSopenharmony_ci        size_t msg_len = MBEDTLS_GET_UINT24_BE(hs_buf->data, 1);
4334a8e1175bSopenharmony_ci
4335a8e1175bSopenharmony_ci        /* Double-check that we haven't accidentally buffered
4336a8e1175bSopenharmony_ci         * a message that doesn't fit into the input buffer. */
4337a8e1175bSopenharmony_ci        if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
4338a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4339a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4340a8e1175bSopenharmony_ci        }
4341a8e1175bSopenharmony_ci
4342a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message has been buffered - load"));
4343a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)",
4344a8e1175bSopenharmony_ci                              hs_buf->data, msg_len + 12);
4345a8e1175bSopenharmony_ci
4346a8e1175bSopenharmony_ci        ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
4347a8e1175bSopenharmony_ci        ssl->in_hslen   = msg_len + 12;
4348a8e1175bSopenharmony_ci        ssl->in_msglen  = msg_len + 12;
4349a8e1175bSopenharmony_ci        memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen);
4350a8e1175bSopenharmony_ci
4351a8e1175bSopenharmony_ci        ret = 0;
4352a8e1175bSopenharmony_ci        goto exit;
4353a8e1175bSopenharmony_ci    } else {
4354a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially bufffered",
4355a8e1175bSopenharmony_ci                                  hs->in_msg_seq));
4356a8e1175bSopenharmony_ci    }
4357a8e1175bSopenharmony_ci
4358a8e1175bSopenharmony_ci    ret = -1;
4359a8e1175bSopenharmony_ci
4360a8e1175bSopenharmony_ciexit:
4361a8e1175bSopenharmony_ci
4362a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message"));
4363a8e1175bSopenharmony_ci    return ret;
4364a8e1175bSopenharmony_ci}
4365a8e1175bSopenharmony_ci
4366a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4367a8e1175bSopenharmony_cistatic int ssl_buffer_make_space(mbedtls_ssl_context *ssl,
4368a8e1175bSopenharmony_ci                                 size_t desired)
4369a8e1175bSopenharmony_ci{
4370a8e1175bSopenharmony_ci    int offset;
4371a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4372a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("Attempt to free buffered messages to have %u bytes available",
4373a8e1175bSopenharmony_ci                              (unsigned) desired));
4374a8e1175bSopenharmony_ci
4375a8e1175bSopenharmony_ci    /* Get rid of future records epoch first, if such exist. */
4376a8e1175bSopenharmony_ci    ssl_free_buffered_record(ssl);
4377a8e1175bSopenharmony_ci
4378a8e1175bSopenharmony_ci    /* Check if we have enough space available now. */
4379a8e1175bSopenharmony_ci    if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4380a8e1175bSopenharmony_ci                    hs->buffering.total_bytes_buffered)) {
4381a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing future epoch record"));
4382a8e1175bSopenharmony_ci        return 0;
4383a8e1175bSopenharmony_ci    }
4384a8e1175bSopenharmony_ci
4385a8e1175bSopenharmony_ci    /* We don't have enough space to buffer the next expected handshake
4386a8e1175bSopenharmony_ci     * message. Remove buffers used for future messages to gain space,
4387a8e1175bSopenharmony_ci     * starting with the most distant one. */
4388a8e1175bSopenharmony_ci    for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
4389a8e1175bSopenharmony_ci         offset >= 0; offset--) {
4390a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2,
4391a8e1175bSopenharmony_ci                              (
4392a8e1175bSopenharmony_ci                                  "Free buffering slot %d to make space for reassembly of next handshake message",
4393a8e1175bSopenharmony_ci                                  offset));
4394a8e1175bSopenharmony_ci
4395a8e1175bSopenharmony_ci        ssl_buffering_free_slot(ssl, (uint8_t) offset);
4396a8e1175bSopenharmony_ci
4397a8e1175bSopenharmony_ci        /* Check if we have enough space available now. */
4398a8e1175bSopenharmony_ci        if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4399a8e1175bSopenharmony_ci                        hs->buffering.total_bytes_buffered)) {
4400a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing buffered HS messages"));
4401a8e1175bSopenharmony_ci            return 0;
4402a8e1175bSopenharmony_ci        }
4403a8e1175bSopenharmony_ci    }
4404a8e1175bSopenharmony_ci
4405a8e1175bSopenharmony_ci    return -1;
4406a8e1175bSopenharmony_ci}
4407a8e1175bSopenharmony_ci
4408a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4409a8e1175bSopenharmony_cistatic int ssl_buffer_message(mbedtls_ssl_context *ssl)
4410a8e1175bSopenharmony_ci{
4411a8e1175bSopenharmony_ci    int ret = 0;
4412a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4413a8e1175bSopenharmony_ci
4414a8e1175bSopenharmony_ci    if (hs == NULL) {
4415a8e1175bSopenharmony_ci        return 0;
4416a8e1175bSopenharmony_ci    }
4417a8e1175bSopenharmony_ci
4418a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message"));
4419a8e1175bSopenharmony_ci
4420a8e1175bSopenharmony_ci    switch (ssl->in_msgtype) {
4421a8e1175bSopenharmony_ci        case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
4422a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message"));
4423a8e1175bSopenharmony_ci
4424a8e1175bSopenharmony_ci            hs->buffering.seen_ccs = 1;
4425a8e1175bSopenharmony_ci            break;
4426a8e1175bSopenharmony_ci
4427a8e1175bSopenharmony_ci        case MBEDTLS_SSL_MSG_HANDSHAKE:
4428a8e1175bSopenharmony_ci        {
4429a8e1175bSopenharmony_ci            unsigned recv_msg_seq_offset;
4430a8e1175bSopenharmony_ci            unsigned recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
4431a8e1175bSopenharmony_ci            mbedtls_ssl_hs_buffer *hs_buf;
4432a8e1175bSopenharmony_ci            size_t msg_len = ssl->in_hslen - 12;
4433a8e1175bSopenharmony_ci
4434a8e1175bSopenharmony_ci            /* We should never receive an old handshake
4435a8e1175bSopenharmony_ci             * message - double-check nonetheless. */
4436a8e1175bSopenharmony_ci            if (recv_msg_seq < ssl->handshake->in_msg_seq) {
4437a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4438a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4439a8e1175bSopenharmony_ci            }
4440a8e1175bSopenharmony_ci
4441a8e1175bSopenharmony_ci            recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
4442a8e1175bSopenharmony_ci            if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
4443a8e1175bSopenharmony_ci                /* Silently ignore -- message too far in the future */
4444a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2,
4445a8e1175bSopenharmony_ci                                      ("Ignore future HS message with sequence number %u, "
4446a8e1175bSopenharmony_ci                                       "buffering window %u - %u",
4447a8e1175bSopenharmony_ci                                       recv_msg_seq, ssl->handshake->in_msg_seq,
4448a8e1175bSopenharmony_ci                                       ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS -
4449a8e1175bSopenharmony_ci                                       1));
4450a8e1175bSopenharmony_ci
4451a8e1175bSopenharmony_ci                goto exit;
4452a8e1175bSopenharmony_ci            }
4453a8e1175bSopenharmony_ci
4454a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering HS message with sequence number %u, offset %u ",
4455a8e1175bSopenharmony_ci                                      recv_msg_seq, recv_msg_seq_offset));
4456a8e1175bSopenharmony_ci
4457a8e1175bSopenharmony_ci            hs_buf = &hs->buffering.hs[recv_msg_seq_offset];
4458a8e1175bSopenharmony_ci
4459a8e1175bSopenharmony_ci            /* Check if the buffering for this seq nr has already commenced. */
4460a8e1175bSopenharmony_ci            if (!hs_buf->is_valid) {
4461a8e1175bSopenharmony_ci                size_t reassembly_buf_sz;
4462a8e1175bSopenharmony_ci
4463a8e1175bSopenharmony_ci                hs_buf->is_fragmented =
4464a8e1175bSopenharmony_ci                    (ssl_hs_is_proper_fragment(ssl) == 1);
4465a8e1175bSopenharmony_ci
4466a8e1175bSopenharmony_ci                /* We copy the message back into the input buffer
4467a8e1175bSopenharmony_ci                 * after reassembly, so check that it's not too large.
4468a8e1175bSopenharmony_ci                 * This is an implementation-specific limitation
4469a8e1175bSopenharmony_ci                 * and not one from the standard, hence it is not
4470a8e1175bSopenharmony_ci                 * checked in ssl_check_hs_header(). */
4471a8e1175bSopenharmony_ci                if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
4472a8e1175bSopenharmony_ci                    /* Ignore message */
4473a8e1175bSopenharmony_ci                    goto exit;
4474a8e1175bSopenharmony_ci                }
4475a8e1175bSopenharmony_ci
4476a8e1175bSopenharmony_ci                /* Check if we have enough space to buffer the message. */
4477a8e1175bSopenharmony_ci                if (hs->buffering.total_bytes_buffered >
4478a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DTLS_MAX_BUFFERING) {
4479a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4480a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4481a8e1175bSopenharmony_ci                }
4482a8e1175bSopenharmony_ci
4483a8e1175bSopenharmony_ci                reassembly_buf_sz = ssl_get_reassembly_buffer_size(msg_len,
4484a8e1175bSopenharmony_ci                                                                   hs_buf->is_fragmented);
4485a8e1175bSopenharmony_ci
4486a8e1175bSopenharmony_ci                if (reassembly_buf_sz > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4487a8e1175bSopenharmony_ci                                         hs->buffering.total_bytes_buffered)) {
4488a8e1175bSopenharmony_ci                    if (recv_msg_seq_offset > 0) {
4489a8e1175bSopenharmony_ci                        /* If we can't buffer a future message because
4490a8e1175bSopenharmony_ci                         * of space limitations -- ignore. */
4491a8e1175bSopenharmony_ci                        MBEDTLS_SSL_DEBUG_MSG(2,
4492a8e1175bSopenharmony_ci                                              ("Buffering of future message of size %"
4493a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4494a8e1175bSopenharmony_ci                                               " would exceed the compile-time limit %"
4495a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4496a8e1175bSopenharmony_ci                                               " (already %" MBEDTLS_PRINTF_SIZET
4497a8e1175bSopenharmony_ci                                               " bytes buffered) -- ignore\n",
4498a8e1175bSopenharmony_ci                                               msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4499a8e1175bSopenharmony_ci                                               hs->buffering.total_bytes_buffered));
4500a8e1175bSopenharmony_ci                        goto exit;
4501a8e1175bSopenharmony_ci                    } else {
4502a8e1175bSopenharmony_ci                        MBEDTLS_SSL_DEBUG_MSG(2,
4503a8e1175bSopenharmony_ci                                              ("Buffering of future message of size %"
4504a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4505a8e1175bSopenharmony_ci                                               " would exceed the compile-time limit %"
4506a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4507a8e1175bSopenharmony_ci                                               " (already %" MBEDTLS_PRINTF_SIZET
4508a8e1175bSopenharmony_ci                                               " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
4509a8e1175bSopenharmony_ci                                               msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4510a8e1175bSopenharmony_ci                                               hs->buffering.total_bytes_buffered));
4511a8e1175bSopenharmony_ci                    }
4512a8e1175bSopenharmony_ci
4513a8e1175bSopenharmony_ci                    if (ssl_buffer_make_space(ssl, reassembly_buf_sz) != 0) {
4514a8e1175bSopenharmony_ci                        MBEDTLS_SSL_DEBUG_MSG(2,
4515a8e1175bSopenharmony_ci                                              ("Reassembly of next message of size %"
4516a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4517a8e1175bSopenharmony_ci                                               " (%" MBEDTLS_PRINTF_SIZET
4518a8e1175bSopenharmony_ci                                               " with bitmap) would exceed"
4519a8e1175bSopenharmony_ci                                               " the compile-time limit %"
4520a8e1175bSopenharmony_ci                                               MBEDTLS_PRINTF_SIZET
4521a8e1175bSopenharmony_ci                                               " (already %" MBEDTLS_PRINTF_SIZET
4522a8e1175bSopenharmony_ci                                               " bytes buffered) -- fail\n",
4523a8e1175bSopenharmony_ci                                               msg_len,
4524a8e1175bSopenharmony_ci                                               reassembly_buf_sz,
4525a8e1175bSopenharmony_ci                                               (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4526a8e1175bSopenharmony_ci                                               hs->buffering.total_bytes_buffered));
4527a8e1175bSopenharmony_ci                        ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
4528a8e1175bSopenharmony_ci                        goto exit;
4529a8e1175bSopenharmony_ci                    }
4530a8e1175bSopenharmony_ci                }
4531a8e1175bSopenharmony_ci
4532a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2,
4533a8e1175bSopenharmony_ci                                      ("initialize reassembly, total length = %"
4534a8e1175bSopenharmony_ci                                       MBEDTLS_PRINTF_SIZET,
4535a8e1175bSopenharmony_ci                                       msg_len));
4536a8e1175bSopenharmony_ci
4537a8e1175bSopenharmony_ci                hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz);
4538a8e1175bSopenharmony_ci                if (hs_buf->data == NULL) {
4539a8e1175bSopenharmony_ci                    ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
4540a8e1175bSopenharmony_ci                    goto exit;
4541a8e1175bSopenharmony_ci                }
4542a8e1175bSopenharmony_ci                hs_buf->data_len = reassembly_buf_sz;
4543a8e1175bSopenharmony_ci
4544a8e1175bSopenharmony_ci                /* Prepare final header: copy msg_type, length and message_seq,
4545a8e1175bSopenharmony_ci                 * then add standardised fragment_offset and fragment_length */
4546a8e1175bSopenharmony_ci                memcpy(hs_buf->data, ssl->in_msg, 6);
4547a8e1175bSopenharmony_ci                memset(hs_buf->data + 6, 0, 3);
4548a8e1175bSopenharmony_ci                memcpy(hs_buf->data + 9, hs_buf->data + 1, 3);
4549a8e1175bSopenharmony_ci
4550a8e1175bSopenharmony_ci                hs_buf->is_valid = 1;
4551a8e1175bSopenharmony_ci
4552a8e1175bSopenharmony_ci                hs->buffering.total_bytes_buffered += reassembly_buf_sz;
4553a8e1175bSopenharmony_ci            } else {
4554a8e1175bSopenharmony_ci                /* Make sure msg_type and length are consistent */
4555a8e1175bSopenharmony_ci                if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) {
4556a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_MSG(1, ("Fragment header mismatch - ignore"));
4557a8e1175bSopenharmony_ci                    /* Ignore */
4558a8e1175bSopenharmony_ci                    goto exit;
4559a8e1175bSopenharmony_ci                }
4560a8e1175bSopenharmony_ci            }
4561a8e1175bSopenharmony_ci
4562a8e1175bSopenharmony_ci            if (!hs_buf->is_complete) {
4563a8e1175bSopenharmony_ci                size_t frag_len, frag_off;
4564a8e1175bSopenharmony_ci                unsigned char * const msg = hs_buf->data + 12;
4565a8e1175bSopenharmony_ci
4566a8e1175bSopenharmony_ci                /*
4567a8e1175bSopenharmony_ci                 * Check and copy current fragment
4568a8e1175bSopenharmony_ci                 */
4569a8e1175bSopenharmony_ci
4570a8e1175bSopenharmony_ci                /* Validation of header fields already done in
4571a8e1175bSopenharmony_ci                 * mbedtls_ssl_prepare_handshake_record(). */
4572a8e1175bSopenharmony_ci                frag_off = ssl_get_hs_frag_off(ssl);
4573a8e1175bSopenharmony_ci                frag_len = ssl_get_hs_frag_len(ssl);
4574a8e1175bSopenharmony_ci
4575a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
4576a8e1175bSopenharmony_ci                                          ", length = %" MBEDTLS_PRINTF_SIZET,
4577a8e1175bSopenharmony_ci                                          frag_off, frag_len));
4578a8e1175bSopenharmony_ci                memcpy(msg + frag_off, ssl->in_msg + 12, frag_len);
4579a8e1175bSopenharmony_ci
4580a8e1175bSopenharmony_ci                if (hs_buf->is_fragmented) {
4581a8e1175bSopenharmony_ci                    unsigned char * const bitmask = msg + msg_len;
4582a8e1175bSopenharmony_ci                    ssl_bitmask_set(bitmask, frag_off, frag_len);
4583a8e1175bSopenharmony_ci                    hs_buf->is_complete = (ssl_bitmask_check(bitmask,
4584a8e1175bSopenharmony_ci                                                             msg_len) == 0);
4585a8e1175bSopenharmony_ci                } else {
4586a8e1175bSopenharmony_ci                    hs_buf->is_complete = 1;
4587a8e1175bSopenharmony_ci                }
4588a8e1175bSopenharmony_ci
4589a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(2, ("message %scomplete",
4590a8e1175bSopenharmony_ci                                          hs_buf->is_complete ? "" : "not yet "));
4591a8e1175bSopenharmony_ci            }
4592a8e1175bSopenharmony_ci
4593a8e1175bSopenharmony_ci            break;
4594a8e1175bSopenharmony_ci        }
4595a8e1175bSopenharmony_ci
4596a8e1175bSopenharmony_ci        default:
4597a8e1175bSopenharmony_ci            /* We don't buffer other types of messages. */
4598a8e1175bSopenharmony_ci            break;
4599a8e1175bSopenharmony_ci    }
4600a8e1175bSopenharmony_ci
4601a8e1175bSopenharmony_ciexit:
4602a8e1175bSopenharmony_ci
4603a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message"));
4604a8e1175bSopenharmony_ci    return ret;
4605a8e1175bSopenharmony_ci}
4606a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
4607a8e1175bSopenharmony_ci
4608a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4609a8e1175bSopenharmony_cistatic int ssl_consume_current_message(mbedtls_ssl_context *ssl)
4610a8e1175bSopenharmony_ci{
4611a8e1175bSopenharmony_ci    /*
4612a8e1175bSopenharmony_ci     * Consume last content-layer message and potentially
4613a8e1175bSopenharmony_ci     * update in_msglen which keeps track of the contents'
4614a8e1175bSopenharmony_ci     * consumption state.
4615a8e1175bSopenharmony_ci     *
4616a8e1175bSopenharmony_ci     * (1) Handshake messages:
4617a8e1175bSopenharmony_ci     *     Remove last handshake message, move content
4618a8e1175bSopenharmony_ci     *     and adapt in_msglen.
4619a8e1175bSopenharmony_ci     *
4620a8e1175bSopenharmony_ci     * (2) Alert messages:
4621a8e1175bSopenharmony_ci     *     Consume whole record content, in_msglen = 0.
4622a8e1175bSopenharmony_ci     *
4623a8e1175bSopenharmony_ci     * (3) Change cipher spec:
4624a8e1175bSopenharmony_ci     *     Consume whole record content, in_msglen = 0.
4625a8e1175bSopenharmony_ci     *
4626a8e1175bSopenharmony_ci     * (4) Application data:
4627a8e1175bSopenharmony_ci     *     Don't do anything - the record layer provides
4628a8e1175bSopenharmony_ci     *     the application data as a stream transport
4629a8e1175bSopenharmony_ci     *     and consumes through mbedtls_ssl_read only.
4630a8e1175bSopenharmony_ci     *
4631a8e1175bSopenharmony_ci     */
4632a8e1175bSopenharmony_ci
4633a8e1175bSopenharmony_ci    /* Case (1): Handshake messages */
4634a8e1175bSopenharmony_ci    if (ssl->in_hslen != 0) {
4635a8e1175bSopenharmony_ci        /* Hard assertion to be sure that no application data
4636a8e1175bSopenharmony_ci         * is in flight, as corrupting ssl->in_msglen during
4637a8e1175bSopenharmony_ci         * ssl->in_offt != NULL is fatal. */
4638a8e1175bSopenharmony_ci        if (ssl->in_offt != NULL) {
4639a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4640a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4641a8e1175bSopenharmony_ci        }
4642a8e1175bSopenharmony_ci
4643a8e1175bSopenharmony_ci        /*
4644a8e1175bSopenharmony_ci         * Get next Handshake message in the current record
4645a8e1175bSopenharmony_ci         */
4646a8e1175bSopenharmony_ci
4647a8e1175bSopenharmony_ci        /* Notes:
4648a8e1175bSopenharmony_ci         * (1) in_hslen is not necessarily the size of the
4649a8e1175bSopenharmony_ci         *     current handshake content: If DTLS handshake
4650a8e1175bSopenharmony_ci         *     fragmentation is used, that's the fragment
4651a8e1175bSopenharmony_ci         *     size instead. Using the total handshake message
4652a8e1175bSopenharmony_ci         *     size here is faulty and should be changed at
4653a8e1175bSopenharmony_ci         *     some point.
4654a8e1175bSopenharmony_ci         * (2) While it doesn't seem to cause problems, one
4655a8e1175bSopenharmony_ci         *     has to be very careful not to assume that in_hslen
4656a8e1175bSopenharmony_ci         *     is always <= in_msglen in a sensible communication.
4657a8e1175bSopenharmony_ci         *     Again, it's wrong for DTLS handshake fragmentation.
4658a8e1175bSopenharmony_ci         *     The following check is therefore mandatory, and
4659a8e1175bSopenharmony_ci         *     should not be treated as a silently corrected assertion.
4660a8e1175bSopenharmony_ci         *     Additionally, ssl->in_hslen might be arbitrarily out of
4661a8e1175bSopenharmony_ci         *     bounds after handling a DTLS message with an unexpected
4662a8e1175bSopenharmony_ci         *     sequence number, see mbedtls_ssl_prepare_handshake_record.
4663a8e1175bSopenharmony_ci         */
4664a8e1175bSopenharmony_ci        if (ssl->in_hslen < ssl->in_msglen) {
4665a8e1175bSopenharmony_ci            ssl->in_msglen -= ssl->in_hslen;
4666a8e1175bSopenharmony_ci            memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen,
4667a8e1175bSopenharmony_ci                    ssl->in_msglen);
4668a8e1175bSopenharmony_ci
4669a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record",
4670a8e1175bSopenharmony_ci                                  ssl->in_msg, ssl->in_msglen);
4671a8e1175bSopenharmony_ci        } else {
4672a8e1175bSopenharmony_ci            ssl->in_msglen = 0;
4673a8e1175bSopenharmony_ci        }
4674a8e1175bSopenharmony_ci
4675a8e1175bSopenharmony_ci        ssl->in_hslen   = 0;
4676a8e1175bSopenharmony_ci    }
4677a8e1175bSopenharmony_ci    /* Case (4): Application data */
4678a8e1175bSopenharmony_ci    else if (ssl->in_offt != NULL) {
4679a8e1175bSopenharmony_ci        return 0;
4680a8e1175bSopenharmony_ci    }
4681a8e1175bSopenharmony_ci    /* Everything else (CCS & Alerts) */
4682a8e1175bSopenharmony_ci    else {
4683a8e1175bSopenharmony_ci        ssl->in_msglen = 0;
4684a8e1175bSopenharmony_ci    }
4685a8e1175bSopenharmony_ci
4686a8e1175bSopenharmony_ci    return 0;
4687a8e1175bSopenharmony_ci}
4688a8e1175bSopenharmony_ci
4689a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4690a8e1175bSopenharmony_cistatic int ssl_record_is_in_progress(mbedtls_ssl_context *ssl)
4691a8e1175bSopenharmony_ci{
4692a8e1175bSopenharmony_ci    if (ssl->in_msglen > 0) {
4693a8e1175bSopenharmony_ci        return 1;
4694a8e1175bSopenharmony_ci    }
4695a8e1175bSopenharmony_ci
4696a8e1175bSopenharmony_ci    return 0;
4697a8e1175bSopenharmony_ci}
4698a8e1175bSopenharmony_ci
4699a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4700a8e1175bSopenharmony_ci
4701a8e1175bSopenharmony_cistatic void ssl_free_buffered_record(mbedtls_ssl_context *ssl)
4702a8e1175bSopenharmony_ci{
4703a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4704a8e1175bSopenharmony_ci    if (hs == NULL) {
4705a8e1175bSopenharmony_ci        return;
4706a8e1175bSopenharmony_ci    }
4707a8e1175bSopenharmony_ci
4708a8e1175bSopenharmony_ci    if (hs->buffering.future_record.data != NULL) {
4709a8e1175bSopenharmony_ci        hs->buffering.total_bytes_buffered -=
4710a8e1175bSopenharmony_ci            hs->buffering.future_record.len;
4711a8e1175bSopenharmony_ci
4712a8e1175bSopenharmony_ci        mbedtls_free(hs->buffering.future_record.data);
4713a8e1175bSopenharmony_ci        hs->buffering.future_record.data = NULL;
4714a8e1175bSopenharmony_ci    }
4715a8e1175bSopenharmony_ci}
4716a8e1175bSopenharmony_ci
4717a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4718a8e1175bSopenharmony_cistatic int ssl_load_buffered_record(mbedtls_ssl_context *ssl)
4719a8e1175bSopenharmony_ci{
4720a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4721a8e1175bSopenharmony_ci    unsigned char *rec;
4722a8e1175bSopenharmony_ci    size_t rec_len;
4723a8e1175bSopenharmony_ci    unsigned rec_epoch;
4724a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
4725a8e1175bSopenharmony_ci    size_t in_buf_len = ssl->in_buf_len;
4726a8e1175bSopenharmony_ci#else
4727a8e1175bSopenharmony_ci    size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
4728a8e1175bSopenharmony_ci#endif
4729a8e1175bSopenharmony_ci    if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4730a8e1175bSopenharmony_ci        return 0;
4731a8e1175bSopenharmony_ci    }
4732a8e1175bSopenharmony_ci
4733a8e1175bSopenharmony_ci    if (hs == NULL) {
4734a8e1175bSopenharmony_ci        return 0;
4735a8e1175bSopenharmony_ci    }
4736a8e1175bSopenharmony_ci
4737a8e1175bSopenharmony_ci    rec       = hs->buffering.future_record.data;
4738a8e1175bSopenharmony_ci    rec_len   = hs->buffering.future_record.len;
4739a8e1175bSopenharmony_ci    rec_epoch = hs->buffering.future_record.epoch;
4740a8e1175bSopenharmony_ci
4741a8e1175bSopenharmony_ci    if (rec == NULL) {
4742a8e1175bSopenharmony_ci        return 0;
4743a8e1175bSopenharmony_ci    }
4744a8e1175bSopenharmony_ci
4745a8e1175bSopenharmony_ci    /* Only consider loading future records if the
4746a8e1175bSopenharmony_ci     * input buffer is empty. */
4747a8e1175bSopenharmony_ci    if (ssl_next_record_is_in_datagram(ssl) == 1) {
4748a8e1175bSopenharmony_ci        return 0;
4749a8e1175bSopenharmony_ci    }
4750a8e1175bSopenharmony_ci
4751a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record"));
4752a8e1175bSopenharmony_ci
4753a8e1175bSopenharmony_ci    if (rec_epoch != ssl->in_epoch) {
4754a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch."));
4755a8e1175bSopenharmony_ci        goto exit;
4756a8e1175bSopenharmony_ci    }
4757a8e1175bSopenharmony_ci
4758a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("Found buffered record from current epoch - load"));
4759a8e1175bSopenharmony_ci
4760a8e1175bSopenharmony_ci    /* Double-check that the record is not too large */
4761a8e1175bSopenharmony_ci    if (rec_len > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
4762a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4763a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4764a8e1175bSopenharmony_ci    }
4765a8e1175bSopenharmony_ci
4766a8e1175bSopenharmony_ci    memcpy(ssl->in_hdr, rec, rec_len);
4767a8e1175bSopenharmony_ci    ssl->in_left = rec_len;
4768a8e1175bSopenharmony_ci    ssl->next_record_offset = 0;
4769a8e1175bSopenharmony_ci
4770a8e1175bSopenharmony_ci    ssl_free_buffered_record(ssl);
4771a8e1175bSopenharmony_ci
4772a8e1175bSopenharmony_ciexit:
4773a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record"));
4774a8e1175bSopenharmony_ci    return 0;
4775a8e1175bSopenharmony_ci}
4776a8e1175bSopenharmony_ci
4777a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4778a8e1175bSopenharmony_cistatic int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
4779a8e1175bSopenharmony_ci                                    mbedtls_record const *rec)
4780a8e1175bSopenharmony_ci{
4781a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
4782a8e1175bSopenharmony_ci
4783a8e1175bSopenharmony_ci    /* Don't buffer future records outside handshakes. */
4784a8e1175bSopenharmony_ci    if (hs == NULL) {
4785a8e1175bSopenharmony_ci        return 0;
4786a8e1175bSopenharmony_ci    }
4787a8e1175bSopenharmony_ci
4788a8e1175bSopenharmony_ci    /* Only buffer handshake records (we are only interested
4789a8e1175bSopenharmony_ci     * in Finished messages). */
4790a8e1175bSopenharmony_ci    if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE) {
4791a8e1175bSopenharmony_ci        return 0;
4792a8e1175bSopenharmony_ci    }
4793a8e1175bSopenharmony_ci
4794a8e1175bSopenharmony_ci    /* Don't buffer more than one future epoch record. */
4795a8e1175bSopenharmony_ci    if (hs->buffering.future_record.data != NULL) {
4796a8e1175bSopenharmony_ci        return 0;
4797a8e1175bSopenharmony_ci    }
4798a8e1175bSopenharmony_ci
4799a8e1175bSopenharmony_ci    /* Don't buffer record if there's not enough buffering space remaining. */
4800a8e1175bSopenharmony_ci    if (rec->buf_len > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
4801a8e1175bSopenharmony_ci                        hs->buffering.total_bytes_buffered)) {
4802a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
4803a8e1175bSopenharmony_ci                                  " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
4804a8e1175bSopenharmony_ci                                  " (already %" MBEDTLS_PRINTF_SIZET
4805a8e1175bSopenharmony_ci                                  " bytes buffered) -- ignore\n",
4806a8e1175bSopenharmony_ci                                  rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
4807a8e1175bSopenharmony_ci                                  hs->buffering.total_bytes_buffered));
4808a8e1175bSopenharmony_ci        return 0;
4809a8e1175bSopenharmony_ci    }
4810a8e1175bSopenharmony_ci
4811a8e1175bSopenharmony_ci    /* Buffer record */
4812a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("Buffer record from epoch %u",
4813a8e1175bSopenharmony_ci                              ssl->in_epoch + 1U));
4814a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len);
4815a8e1175bSopenharmony_ci
4816a8e1175bSopenharmony_ci    /* ssl_parse_record_header() only considers records
4817a8e1175bSopenharmony_ci     * of the next epoch as candidates for buffering. */
4818a8e1175bSopenharmony_ci    hs->buffering.future_record.epoch = ssl->in_epoch + 1;
4819a8e1175bSopenharmony_ci    hs->buffering.future_record.len   = rec->buf_len;
4820a8e1175bSopenharmony_ci
4821a8e1175bSopenharmony_ci    hs->buffering.future_record.data =
4822a8e1175bSopenharmony_ci        mbedtls_calloc(1, hs->buffering.future_record.len);
4823a8e1175bSopenharmony_ci    if (hs->buffering.future_record.data == NULL) {
4824a8e1175bSopenharmony_ci        /* If we run out of RAM trying to buffer a
4825a8e1175bSopenharmony_ci         * record from the next epoch, just ignore. */
4826a8e1175bSopenharmony_ci        return 0;
4827a8e1175bSopenharmony_ci    }
4828a8e1175bSopenharmony_ci
4829a8e1175bSopenharmony_ci    memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len);
4830a8e1175bSopenharmony_ci
4831a8e1175bSopenharmony_ci    hs->buffering.total_bytes_buffered += rec->buf_len;
4832a8e1175bSopenharmony_ci    return 0;
4833a8e1175bSopenharmony_ci}
4834a8e1175bSopenharmony_ci
4835a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
4836a8e1175bSopenharmony_ci
4837a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
4838a8e1175bSopenharmony_cistatic int ssl_get_next_record(mbedtls_ssl_context *ssl)
4839a8e1175bSopenharmony_ci{
4840a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4841a8e1175bSopenharmony_ci    mbedtls_record rec;
4842a8e1175bSopenharmony_ci
4843a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4844a8e1175bSopenharmony_ci    /* We might have buffered a future record; if so,
4845a8e1175bSopenharmony_ci     * and if the epoch matches now, load it.
4846a8e1175bSopenharmony_ci     * On success, this call will set ssl->in_left to
4847a8e1175bSopenharmony_ci     * the length of the buffered record, so that
4848a8e1175bSopenharmony_ci     * the calls to ssl_fetch_input() below will
4849a8e1175bSopenharmony_ci     * essentially be no-ops. */
4850a8e1175bSopenharmony_ci    ret = ssl_load_buffered_record(ssl);
4851a8e1175bSopenharmony_ci    if (ret != 0) {
4852a8e1175bSopenharmony_ci        return ret;
4853a8e1175bSopenharmony_ci    }
4854a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
4855a8e1175bSopenharmony_ci
4856a8e1175bSopenharmony_ci    /* Ensure that we have enough space available for the default form
4857a8e1175bSopenharmony_ci     * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
4858a8e1175bSopenharmony_ci     * with no space for CIDs counted in). */
4859a8e1175bSopenharmony_ci    ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl));
4860a8e1175bSopenharmony_ci    if (ret != 0) {
4861a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
4862a8e1175bSopenharmony_ci        return ret;
4863a8e1175bSopenharmony_ci    }
4864a8e1175bSopenharmony_ci
4865a8e1175bSopenharmony_ci    ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec);
4866a8e1175bSopenharmony_ci    if (ret != 0) {
4867a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4868a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4869a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
4870a8e1175bSopenharmony_ci                ret = ssl_buffer_future_record(ssl, &rec);
4871a8e1175bSopenharmony_ci                if (ret != 0) {
4872a8e1175bSopenharmony_ci                    return ret;
4873a8e1175bSopenharmony_ci                }
4874a8e1175bSopenharmony_ci
4875a8e1175bSopenharmony_ci                /* Fall through to handling of unexpected records */
4876a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
4877a8e1175bSopenharmony_ci            }
4878a8e1175bSopenharmony_ci
4879a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) {
4880a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
4881a8e1175bSopenharmony_ci                /* Reset in pointers to default state for TLS/DTLS records,
4882a8e1175bSopenharmony_ci                 * assuming no CID and no offset between record content and
4883a8e1175bSopenharmony_ci                 * record plaintext. */
4884a8e1175bSopenharmony_ci                mbedtls_ssl_update_in_pointers(ssl);
4885a8e1175bSopenharmony_ci
4886a8e1175bSopenharmony_ci                /* Setup internal message pointers from record structure. */
4887a8e1175bSopenharmony_ci                ssl->in_msgtype = rec.type;
4888a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
4889a8e1175bSopenharmony_ci                ssl->in_len = ssl->in_cid + rec.cid_len;
4890a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
4891a8e1175bSopenharmony_ci                ssl->in_iv  = ssl->in_msg = ssl->in_len + 2;
4892a8e1175bSopenharmony_ci                ssl->in_msglen = rec.data_len;
4893a8e1175bSopenharmony_ci
4894a8e1175bSopenharmony_ci                ret = ssl_check_client_reconnect(ssl);
4895a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret);
4896a8e1175bSopenharmony_ci                if (ret != 0) {
4897a8e1175bSopenharmony_ci                    return ret;
4898a8e1175bSopenharmony_ci                }
4899a8e1175bSopenharmony_ci#endif
4900a8e1175bSopenharmony_ci
4901a8e1175bSopenharmony_ci                /* Skip unexpected record (but not whole datagram) */
4902a8e1175bSopenharmony_ci                ssl->next_record_offset = rec.buf_len;
4903a8e1175bSopenharmony_ci
4904a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record "
4905a8e1175bSopenharmony_ci                                          "(header)"));
4906a8e1175bSopenharmony_ci            } else {
4907a8e1175bSopenharmony_ci                /* Skip invalid record and the rest of the datagram */
4908a8e1175bSopenharmony_ci                ssl->next_record_offset = 0;
4909a8e1175bSopenharmony_ci                ssl->in_left = 0;
4910a8e1175bSopenharmony_ci
4911a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record "
4912a8e1175bSopenharmony_ci                                          "(header)"));
4913a8e1175bSopenharmony_ci            }
4914a8e1175bSopenharmony_ci
4915a8e1175bSopenharmony_ci            /* Get next record */
4916a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4917a8e1175bSopenharmony_ci        } else
4918a8e1175bSopenharmony_ci#endif
4919a8e1175bSopenharmony_ci        {
4920a8e1175bSopenharmony_ci            return ret;
4921a8e1175bSopenharmony_ci        }
4922a8e1175bSopenharmony_ci    }
4923a8e1175bSopenharmony_ci
4924a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4925a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4926a8e1175bSopenharmony_ci        /* Remember offset of next record within datagram. */
4927a8e1175bSopenharmony_ci        ssl->next_record_offset = rec.buf_len;
4928a8e1175bSopenharmony_ci        if (ssl->next_record_offset < ssl->in_left) {
4929a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram"));
4930a8e1175bSopenharmony_ci        }
4931a8e1175bSopenharmony_ci    } else
4932a8e1175bSopenharmony_ci#endif
4933a8e1175bSopenharmony_ci    {
4934a8e1175bSopenharmony_ci        /*
4935a8e1175bSopenharmony_ci         * Fetch record contents from underlying transport.
4936a8e1175bSopenharmony_ci         */
4937a8e1175bSopenharmony_ci        ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len);
4938a8e1175bSopenharmony_ci        if (ret != 0) {
4939a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
4940a8e1175bSopenharmony_ci            return ret;
4941a8e1175bSopenharmony_ci        }
4942a8e1175bSopenharmony_ci
4943a8e1175bSopenharmony_ci        ssl->in_left = 0;
4944a8e1175bSopenharmony_ci    }
4945a8e1175bSopenharmony_ci
4946a8e1175bSopenharmony_ci    /*
4947a8e1175bSopenharmony_ci     * Decrypt record contents.
4948a8e1175bSopenharmony_ci     */
4949a8e1175bSopenharmony_ci
4950a8e1175bSopenharmony_ci    if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) {
4951a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
4952a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
4953a8e1175bSopenharmony_ci            /* Silently discard invalid records */
4954a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
4955a8e1175bSopenharmony_ci                /* Except when waiting for Finished as a bad mac here
4956a8e1175bSopenharmony_ci                 * probably means something went wrong in the handshake
4957a8e1175bSopenharmony_ci                 * (eg wrong psk used, mitm downgrade attempt, etc.) */
4958a8e1175bSopenharmony_ci                if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
4959a8e1175bSopenharmony_ci                    ssl->state == MBEDTLS_SSL_SERVER_FINISHED) {
4960a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4961a8e1175bSopenharmony_ci                    if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
4962a8e1175bSopenharmony_ci                        mbedtls_ssl_send_alert_message(ssl,
4963a8e1175bSopenharmony_ci                                                       MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4964a8e1175bSopenharmony_ci                                                       MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
4965a8e1175bSopenharmony_ci                    }
4966a8e1175bSopenharmony_ci#endif
4967a8e1175bSopenharmony_ci                    return ret;
4968a8e1175bSopenharmony_ci                }
4969a8e1175bSopenharmony_ci
4970a8e1175bSopenharmony_ci                if (ssl->conf->badmac_limit != 0 &&
4971a8e1175bSopenharmony_ci                    ++ssl->badmac_seen >= ssl->conf->badmac_limit) {
4972a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
4973a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_SSL_INVALID_MAC;
4974a8e1175bSopenharmony_ci                }
4975a8e1175bSopenharmony_ci
4976a8e1175bSopenharmony_ci                /* As above, invalid records cause
4977a8e1175bSopenharmony_ci                 * dismissal of the whole datagram. */
4978a8e1175bSopenharmony_ci
4979a8e1175bSopenharmony_ci                ssl->next_record_offset = 0;
4980a8e1175bSopenharmony_ci                ssl->in_left = 0;
4981a8e1175bSopenharmony_ci
4982a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)"));
4983a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4984a8e1175bSopenharmony_ci            }
4985a8e1175bSopenharmony_ci
4986a8e1175bSopenharmony_ci            return ret;
4987a8e1175bSopenharmony_ci        } else
4988a8e1175bSopenharmony_ci#endif
4989a8e1175bSopenharmony_ci        {
4990a8e1175bSopenharmony_ci            /* Error out (and send alert) on invalid records */
4991a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
4992a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
4993a8e1175bSopenharmony_ci                mbedtls_ssl_send_alert_message(ssl,
4994a8e1175bSopenharmony_ci                                               MBEDTLS_SSL_ALERT_LEVEL_FATAL,
4995a8e1175bSopenharmony_ci                                               MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
4996a8e1175bSopenharmony_ci            }
4997a8e1175bSopenharmony_ci#endif
4998a8e1175bSopenharmony_ci            return ret;
4999a8e1175bSopenharmony_ci        }
5000a8e1175bSopenharmony_ci    }
5001a8e1175bSopenharmony_ci
5002a8e1175bSopenharmony_ci
5003a8e1175bSopenharmony_ci    /* Reset in pointers to default state for TLS/DTLS records,
5004a8e1175bSopenharmony_ci     * assuming no CID and no offset between record content and
5005a8e1175bSopenharmony_ci     * record plaintext. */
5006a8e1175bSopenharmony_ci    mbedtls_ssl_update_in_pointers(ssl);
5007a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5008a8e1175bSopenharmony_ci    ssl->in_len = ssl->in_cid + rec.cid_len;
5009a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5010a8e1175bSopenharmony_ci    ssl->in_iv  = ssl->in_len + 2;
5011a8e1175bSopenharmony_ci
5012a8e1175bSopenharmony_ci    /* The record content type may change during decryption,
5013a8e1175bSopenharmony_ci     * so re-read it. */
5014a8e1175bSopenharmony_ci    ssl->in_msgtype = rec.type;
5015a8e1175bSopenharmony_ci    /* Also update the input buffer, because unfortunately
5016a8e1175bSopenharmony_ci     * the server-side ssl_parse_client_hello() reparses the
5017a8e1175bSopenharmony_ci     * record header when receiving a ClientHello initiating
5018a8e1175bSopenharmony_ci     * a renegotiation. */
5019a8e1175bSopenharmony_ci    ssl->in_hdr[0] = rec.type;
5020a8e1175bSopenharmony_ci    ssl->in_msg    = rec.buf + rec.data_offset;
5021a8e1175bSopenharmony_ci    ssl->in_msglen = rec.data_len;
5022a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0);
5023a8e1175bSopenharmony_ci
5024a8e1175bSopenharmony_ci    return 0;
5025a8e1175bSopenharmony_ci}
5026a8e1175bSopenharmony_ci
5027a8e1175bSopenharmony_ciint mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
5028a8e1175bSopenharmony_ci{
5029a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5030a8e1175bSopenharmony_ci
5031a8e1175bSopenharmony_ci    /*
5032a8e1175bSopenharmony_ci     * Handle particular types of records
5033a8e1175bSopenharmony_ci     */
5034a8e1175bSopenharmony_ci    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
5035a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) {
5036a8e1175bSopenharmony_ci            return ret;
5037a8e1175bSopenharmony_ci        }
5038a8e1175bSopenharmony_ci    }
5039a8e1175bSopenharmony_ci
5040a8e1175bSopenharmony_ci    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
5041a8e1175bSopenharmony_ci        if (ssl->in_msglen != 1) {
5042a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
5043a8e1175bSopenharmony_ci                                      ssl->in_msglen));
5044a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
5045a8e1175bSopenharmony_ci        }
5046a8e1175bSopenharmony_ci
5047a8e1175bSopenharmony_ci        if (ssl->in_msg[0] != 1) {
5048a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x",
5049a8e1175bSopenharmony_ci                                      ssl->in_msg[0]));
5050a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
5051a8e1175bSopenharmony_ci        }
5052a8e1175bSopenharmony_ci
5053a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5054a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5055a8e1175bSopenharmony_ci            ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC    &&
5056a8e1175bSopenharmony_ci            ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
5057a8e1175bSopenharmony_ci            if (ssl->handshake == NULL) {
5058a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("dropping ChangeCipherSpec outside handshake"));
5059a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
5060a8e1175bSopenharmony_ci            }
5061a8e1175bSopenharmony_ci
5062a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("received out-of-order ChangeCipherSpec - remember"));
5063a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
5064a8e1175bSopenharmony_ci        }
5065a8e1175bSopenharmony_ci#endif
5066a8e1175bSopenharmony_ci
5067a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
5068a8e1175bSopenharmony_ci        if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
5069a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
5070a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
5071a8e1175bSopenharmony_ci                                  ("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"));
5072a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
5073a8e1175bSopenharmony_ci#else
5074a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1,
5075a8e1175bSopenharmony_ci                                  ("ChangeCipherSpec invalid in TLS 1.3 without compatibility mode"));
5076a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
5077a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
5078a8e1175bSopenharmony_ci        }
5079a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
5080a8e1175bSopenharmony_ci    }
5081a8e1175bSopenharmony_ci
5082a8e1175bSopenharmony_ci    if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
5083a8e1175bSopenharmony_ci        if (ssl->in_msglen != 2) {
5084a8e1175bSopenharmony_ci            /* Note: Standard allows for more than one 2 byte alert
5085a8e1175bSopenharmony_ci               to be packed in a single message, but Mbed TLS doesn't
5086a8e1175bSopenharmony_ci               currently support this. */
5087a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
5088a8e1175bSopenharmony_ci                                      ssl->in_msglen));
5089a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_RECORD;
5090a8e1175bSopenharmony_ci        }
5091a8e1175bSopenharmony_ci
5092a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]",
5093a8e1175bSopenharmony_ci                                  ssl->in_msg[0], ssl->in_msg[1]));
5094a8e1175bSopenharmony_ci
5095a8e1175bSopenharmony_ci        /*
5096a8e1175bSopenharmony_ci         * Ignore non-fatal alerts, except close_notify and no_renegotiation
5097a8e1175bSopenharmony_ci         */
5098a8e1175bSopenharmony_ci        if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) {
5099a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)",
5100a8e1175bSopenharmony_ci                                      ssl->in_msg[1]));
5101a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
5102a8e1175bSopenharmony_ci        }
5103a8e1175bSopenharmony_ci
5104a8e1175bSopenharmony_ci        if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
5105a8e1175bSopenharmony_ci            ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) {
5106a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message"));
5107a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
5108a8e1175bSopenharmony_ci        }
5109a8e1175bSopenharmony_ci
5110a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
5111a8e1175bSopenharmony_ci        if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
5112a8e1175bSopenharmony_ci            ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) {
5113a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert"));
5114a8e1175bSopenharmony_ci            /* Will be handled when trying to parse ServerHello */
5115a8e1175bSopenharmony_ci            return 0;
5116a8e1175bSopenharmony_ci        }
5117a8e1175bSopenharmony_ci#endif
5118a8e1175bSopenharmony_ci        /* Silently ignore: fetch new message */
5119a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_NON_FATAL;
5120a8e1175bSopenharmony_ci    }
5121a8e1175bSopenharmony_ci
5122a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5123a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5124a8e1175bSopenharmony_ci        /* Drop unexpected ApplicationData records,
5125a8e1175bSopenharmony_ci         * except at the beginning of renegotiations */
5126a8e1175bSopenharmony_ci        if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
5127a8e1175bSopenharmony_ci            mbedtls_ssl_is_handshake_over(ssl) == 0
5128a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
5129a8e1175bSopenharmony_ci            && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
5130a8e1175bSopenharmony_ci                 ssl->state == MBEDTLS_SSL_SERVER_HELLO)
5131a8e1175bSopenharmony_ci#endif
5132a8e1175bSopenharmony_ci            ) {
5133a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData"));
5134a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_NON_FATAL;
5135a8e1175bSopenharmony_ci        }
5136a8e1175bSopenharmony_ci
5137a8e1175bSopenharmony_ci        if (ssl->handshake != NULL &&
5138a8e1175bSopenharmony_ci            mbedtls_ssl_is_handshake_over(ssl) == 1) {
5139a8e1175bSopenharmony_ci            mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
5140a8e1175bSopenharmony_ci        }
5141a8e1175bSopenharmony_ci    }
5142a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
5143a8e1175bSopenharmony_ci
5144a8e1175bSopenharmony_ci    return 0;
5145a8e1175bSopenharmony_ci}
5146a8e1175bSopenharmony_ci
5147a8e1175bSopenharmony_ciint mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl)
5148a8e1175bSopenharmony_ci{
5149a8e1175bSopenharmony_ci    return mbedtls_ssl_send_alert_message(ssl,
5150a8e1175bSopenharmony_ci                                          MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5151a8e1175bSopenharmony_ci                                          MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
5152a8e1175bSopenharmony_ci}
5153a8e1175bSopenharmony_ci
5154a8e1175bSopenharmony_ciint mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
5155a8e1175bSopenharmony_ci                                   unsigned char level,
5156a8e1175bSopenharmony_ci                                   unsigned char message)
5157a8e1175bSopenharmony_ci{
5158a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5159a8e1175bSopenharmony_ci
5160a8e1175bSopenharmony_ci    if (ssl == NULL || ssl->conf == NULL) {
5161a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5162a8e1175bSopenharmony_ci    }
5163a8e1175bSopenharmony_ci
5164a8e1175bSopenharmony_ci    if (ssl->out_left != 0) {
5165a8e1175bSopenharmony_ci        return mbedtls_ssl_flush_output(ssl);
5166a8e1175bSopenharmony_ci    }
5167a8e1175bSopenharmony_ci
5168a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message"));
5169a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("send alert level=%u message=%u", level, message));
5170a8e1175bSopenharmony_ci
5171a8e1175bSopenharmony_ci    ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
5172a8e1175bSopenharmony_ci    ssl->out_msglen = 2;
5173a8e1175bSopenharmony_ci    ssl->out_msg[0] = level;
5174a8e1175bSopenharmony_ci    ssl->out_msg[1] = message;
5175a8e1175bSopenharmony_ci
5176a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
5177a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
5178a8e1175bSopenharmony_ci        return ret;
5179a8e1175bSopenharmony_ci    }
5180a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message"));
5181a8e1175bSopenharmony_ci
5182a8e1175bSopenharmony_ci    return 0;
5183a8e1175bSopenharmony_ci}
5184a8e1175bSopenharmony_ci
5185a8e1175bSopenharmony_ciint mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
5186a8e1175bSopenharmony_ci{
5187a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5188a8e1175bSopenharmony_ci
5189a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
5190a8e1175bSopenharmony_ci
5191a8e1175bSopenharmony_ci    ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
5192a8e1175bSopenharmony_ci    ssl->out_msglen  = 1;
5193a8e1175bSopenharmony_ci    ssl->out_msg[0]  = 1;
5194a8e1175bSopenharmony_ci
5195a8e1175bSopenharmony_ci    ssl->state++;
5196a8e1175bSopenharmony_ci
5197a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
5198a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
5199a8e1175bSopenharmony_ci        return ret;
5200a8e1175bSopenharmony_ci    }
5201a8e1175bSopenharmony_ci
5202a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));
5203a8e1175bSopenharmony_ci
5204a8e1175bSopenharmony_ci    return 0;
5205a8e1175bSopenharmony_ci}
5206a8e1175bSopenharmony_ci
5207a8e1175bSopenharmony_ciint mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
5208a8e1175bSopenharmony_ci{
5209a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5210a8e1175bSopenharmony_ci
5211a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec"));
5212a8e1175bSopenharmony_ci
5213a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
5214a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
5215a8e1175bSopenharmony_ci        return ret;
5216a8e1175bSopenharmony_ci    }
5217a8e1175bSopenharmony_ci
5218a8e1175bSopenharmony_ci    if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
5219a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message"));
5220a8e1175bSopenharmony_ci        mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
5221a8e1175bSopenharmony_ci                                       MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
5222a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5223a8e1175bSopenharmony_ci    }
5224a8e1175bSopenharmony_ci
5225a8e1175bSopenharmony_ci    /* CCS records are only accepted if they have length 1 and content '1',
5226a8e1175bSopenharmony_ci     * so we don't need to check this here. */
5227a8e1175bSopenharmony_ci
5228a8e1175bSopenharmony_ci    /*
5229a8e1175bSopenharmony_ci     * Switch to our negotiated transform and session parameters for inbound
5230a8e1175bSopenharmony_ci     * data.
5231a8e1175bSopenharmony_ci     */
5232a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for inbound data"));
5233a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5234a8e1175bSopenharmony_ci    ssl->transform_in = ssl->transform_negotiate;
5235a8e1175bSopenharmony_ci#endif
5236a8e1175bSopenharmony_ci    ssl->session_in = ssl->session_negotiate;
5237a8e1175bSopenharmony_ci
5238a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5239a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5240a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
5241a8e1175bSopenharmony_ci        mbedtls_ssl_dtls_replay_reset(ssl);
5242a8e1175bSopenharmony_ci#endif
5243a8e1175bSopenharmony_ci
5244a8e1175bSopenharmony_ci        /* Increment epoch */
5245a8e1175bSopenharmony_ci        if (++ssl->in_epoch == 0) {
5246a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
5247a8e1175bSopenharmony_ci            /* This is highly unlikely to happen for legitimate reasons, so
5248a8e1175bSopenharmony_ci               treat it as an attack and don't send an alert. */
5249a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
5250a8e1175bSopenharmony_ci        }
5251a8e1175bSopenharmony_ci    } else
5252a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
5253a8e1175bSopenharmony_ci    memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
5254a8e1175bSopenharmony_ci
5255a8e1175bSopenharmony_ci    mbedtls_ssl_update_in_pointers(ssl);
5256a8e1175bSopenharmony_ci
5257a8e1175bSopenharmony_ci    ssl->state++;
5258a8e1175bSopenharmony_ci
5259a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec"));
5260a8e1175bSopenharmony_ci
5261a8e1175bSopenharmony_ci    return 0;
5262a8e1175bSopenharmony_ci}
5263a8e1175bSopenharmony_ci
5264a8e1175bSopenharmony_ci/* Once ssl->out_hdr as the address of the beginning of the
5265a8e1175bSopenharmony_ci * next outgoing record is set, deduce the other pointers.
5266a8e1175bSopenharmony_ci *
5267a8e1175bSopenharmony_ci * Note: For TLS, we save the implicit record sequence number
5268a8e1175bSopenharmony_ci *       (entering MAC computation) in the 8 bytes before ssl->out_hdr,
5269a8e1175bSopenharmony_ci *       and the caller has to make sure there's space for this.
5270a8e1175bSopenharmony_ci */
5271a8e1175bSopenharmony_ci
5272a8e1175bSopenharmony_cistatic size_t ssl_transform_get_explicit_iv_len(
5273a8e1175bSopenharmony_ci    mbedtls_ssl_transform const *transform)
5274a8e1175bSopenharmony_ci{
5275a8e1175bSopenharmony_ci    return transform->ivlen - transform->fixed_ivlen;
5276a8e1175bSopenharmony_ci}
5277a8e1175bSopenharmony_ci
5278a8e1175bSopenharmony_civoid mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
5279a8e1175bSopenharmony_ci                                     mbedtls_ssl_transform *transform)
5280a8e1175bSopenharmony_ci{
5281a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5282a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5283a8e1175bSopenharmony_ci        ssl->out_ctr = ssl->out_hdr +  3;
5284a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5285a8e1175bSopenharmony_ci        ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5286a8e1175bSopenharmony_ci        ssl->out_len = ssl->out_cid;
5287a8e1175bSopenharmony_ci        if (transform != NULL) {
5288a8e1175bSopenharmony_ci            ssl->out_len += transform->out_cid_len;
5289a8e1175bSopenharmony_ci        }
5290a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5291a8e1175bSopenharmony_ci        ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5292a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5293a8e1175bSopenharmony_ci        ssl->out_iv  = ssl->out_len + 2;
5294a8e1175bSopenharmony_ci    } else
5295a8e1175bSopenharmony_ci#endif
5296a8e1175bSopenharmony_ci    {
5297a8e1175bSopenharmony_ci        ssl->out_len = ssl->out_hdr + 3;
5298a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5299a8e1175bSopenharmony_ci        ssl->out_cid = ssl->out_len;
5300a8e1175bSopenharmony_ci#endif
5301a8e1175bSopenharmony_ci        ssl->out_iv  = ssl->out_hdr + 5;
5302a8e1175bSopenharmony_ci    }
5303a8e1175bSopenharmony_ci
5304a8e1175bSopenharmony_ci    ssl->out_msg = ssl->out_iv;
5305a8e1175bSopenharmony_ci    /* Adjust out_msg to make space for explicit IV, if used. */
5306a8e1175bSopenharmony_ci    if (transform != NULL) {
5307a8e1175bSopenharmony_ci        ssl->out_msg += ssl_transform_get_explicit_iv_len(transform);
5308a8e1175bSopenharmony_ci    }
5309a8e1175bSopenharmony_ci}
5310a8e1175bSopenharmony_ci
5311a8e1175bSopenharmony_ci/* Once ssl->in_hdr as the address of the beginning of the
5312a8e1175bSopenharmony_ci * next incoming record is set, deduce the other pointers.
5313a8e1175bSopenharmony_ci *
5314a8e1175bSopenharmony_ci * Note: For TLS, we save the implicit record sequence number
5315a8e1175bSopenharmony_ci *       (entering MAC computation) in the 8 bytes before ssl->in_hdr,
5316a8e1175bSopenharmony_ci *       and the caller has to make sure there's space for this.
5317a8e1175bSopenharmony_ci */
5318a8e1175bSopenharmony_ci
5319a8e1175bSopenharmony_civoid mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
5320a8e1175bSopenharmony_ci{
5321a8e1175bSopenharmony_ci    /* This function sets the pointers to match the case
5322a8e1175bSopenharmony_ci     * of unprotected TLS/DTLS records, with both  ssl->in_iv
5323a8e1175bSopenharmony_ci     * and ssl->in_msg pointing to the beginning of the record
5324a8e1175bSopenharmony_ci     * content.
5325a8e1175bSopenharmony_ci     *
5326a8e1175bSopenharmony_ci     * When decrypting a protected record, ssl->in_msg
5327a8e1175bSopenharmony_ci     * will be shifted to point to the beginning of the
5328a8e1175bSopenharmony_ci     * record plaintext.
5329a8e1175bSopenharmony_ci     */
5330a8e1175bSopenharmony_ci
5331a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5332a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5333a8e1175bSopenharmony_ci        /* This sets the header pointers to match records
5334a8e1175bSopenharmony_ci         * without CID. When we receive a record containing
5335a8e1175bSopenharmony_ci         * a CID, the fields are shifted accordingly in
5336a8e1175bSopenharmony_ci         * ssl_parse_record_header(). */
5337a8e1175bSopenharmony_ci        ssl->in_ctr = ssl->in_hdr +  3;
5338a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5339a8e1175bSopenharmony_ci        ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5340a8e1175bSopenharmony_ci        ssl->in_len = ssl->in_cid; /* Default: no CID */
5341a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5342a8e1175bSopenharmony_ci        ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5343a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5344a8e1175bSopenharmony_ci        ssl->in_iv  = ssl->in_len + 2;
5345a8e1175bSopenharmony_ci    } else
5346a8e1175bSopenharmony_ci#endif
5347a8e1175bSopenharmony_ci    {
5348a8e1175bSopenharmony_ci        ssl->in_ctr = ssl->in_hdr - MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5349a8e1175bSopenharmony_ci        ssl->in_len = ssl->in_hdr + 3;
5350a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5351a8e1175bSopenharmony_ci        ssl->in_cid = ssl->in_len;
5352a8e1175bSopenharmony_ci#endif
5353a8e1175bSopenharmony_ci        ssl->in_iv  = ssl->in_hdr + 5;
5354a8e1175bSopenharmony_ci    }
5355a8e1175bSopenharmony_ci
5356a8e1175bSopenharmony_ci    /* This will be adjusted at record decryption time. */
5357a8e1175bSopenharmony_ci    ssl->in_msg = ssl->in_iv;
5358a8e1175bSopenharmony_ci}
5359a8e1175bSopenharmony_ci
5360a8e1175bSopenharmony_ci/*
5361a8e1175bSopenharmony_ci * Setup an SSL context
5362a8e1175bSopenharmony_ci */
5363a8e1175bSopenharmony_ci
5364a8e1175bSopenharmony_civoid mbedtls_ssl_reset_in_out_pointers(mbedtls_ssl_context *ssl)
5365a8e1175bSopenharmony_ci{
5366a8e1175bSopenharmony_ci    /* Set the incoming and outgoing record pointers. */
5367a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5368a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5369a8e1175bSopenharmony_ci        ssl->out_hdr = ssl->out_buf;
5370a8e1175bSopenharmony_ci        ssl->in_hdr  = ssl->in_buf;
5371a8e1175bSopenharmony_ci    } else
5372a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
5373a8e1175bSopenharmony_ci    {
5374a8e1175bSopenharmony_ci        ssl->out_ctr = ssl->out_buf;
5375a8e1175bSopenharmony_ci        ssl->out_hdr = ssl->out_buf + 8;
5376a8e1175bSopenharmony_ci        ssl->in_hdr  = ssl->in_buf  + 8;
5377a8e1175bSopenharmony_ci    }
5378a8e1175bSopenharmony_ci
5379a8e1175bSopenharmony_ci    /* Derive other internal pointers. */
5380a8e1175bSopenharmony_ci    mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
5381a8e1175bSopenharmony_ci    mbedtls_ssl_update_in_pointers(ssl);
5382a8e1175bSopenharmony_ci}
5383a8e1175bSopenharmony_ci
5384a8e1175bSopenharmony_ci/*
5385a8e1175bSopenharmony_ci * SSL get accessors
5386a8e1175bSopenharmony_ci */
5387a8e1175bSopenharmony_cisize_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl)
5388a8e1175bSopenharmony_ci{
5389a8e1175bSopenharmony_ci    return ssl->in_offt == NULL ? 0 : ssl->in_msglen;
5390a8e1175bSopenharmony_ci}
5391a8e1175bSopenharmony_ci
5392a8e1175bSopenharmony_ciint mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl)
5393a8e1175bSopenharmony_ci{
5394a8e1175bSopenharmony_ci    /*
5395a8e1175bSopenharmony_ci     * Case A: We're currently holding back
5396a8e1175bSopenharmony_ci     * a message for further processing.
5397a8e1175bSopenharmony_ci     */
5398a8e1175bSopenharmony_ci
5399a8e1175bSopenharmony_ci    if (ssl->keep_current_message == 1) {
5400a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: record held back for processing"));
5401a8e1175bSopenharmony_ci        return 1;
5402a8e1175bSopenharmony_ci    }
5403a8e1175bSopenharmony_ci
5404a8e1175bSopenharmony_ci    /*
5405a8e1175bSopenharmony_ci     * Case B: Further records are pending in the current datagram.
5406a8e1175bSopenharmony_ci     */
5407a8e1175bSopenharmony_ci
5408a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5409a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5410a8e1175bSopenharmony_ci        ssl->in_left > ssl->next_record_offset) {
5411a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: more records within current datagram"));
5412a8e1175bSopenharmony_ci        return 1;
5413a8e1175bSopenharmony_ci    }
5414a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
5415a8e1175bSopenharmony_ci
5416a8e1175bSopenharmony_ci    /*
5417a8e1175bSopenharmony_ci     * Case C: A handshake message is being processed.
5418a8e1175bSopenharmony_ci     */
5419a8e1175bSopenharmony_ci
5420a8e1175bSopenharmony_ci    if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) {
5421a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3,
5422a8e1175bSopenharmony_ci                              ("ssl_check_pending: more handshake messages within current record"));
5423a8e1175bSopenharmony_ci        return 1;
5424a8e1175bSopenharmony_ci    }
5425a8e1175bSopenharmony_ci
5426a8e1175bSopenharmony_ci    /*
5427a8e1175bSopenharmony_ci     * Case D: An application data message is being processed
5428a8e1175bSopenharmony_ci     */
5429a8e1175bSopenharmony_ci    if (ssl->in_offt != NULL) {
5430a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: application data record is being processed"));
5431a8e1175bSopenharmony_ci        return 1;
5432a8e1175bSopenharmony_ci    }
5433a8e1175bSopenharmony_ci
5434a8e1175bSopenharmony_ci    /*
5435a8e1175bSopenharmony_ci     * In all other cases, the rest of the message can be dropped.
5436a8e1175bSopenharmony_ci     * As in ssl_get_next_record, this needs to be adapted if
5437a8e1175bSopenharmony_ci     * we implement support for multiple alerts in single records.
5438a8e1175bSopenharmony_ci     */
5439a8e1175bSopenharmony_ci
5440a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending"));
5441a8e1175bSopenharmony_ci    return 0;
5442a8e1175bSopenharmony_ci}
5443a8e1175bSopenharmony_ci
5444a8e1175bSopenharmony_ci
5445a8e1175bSopenharmony_ciint mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl)
5446a8e1175bSopenharmony_ci{
5447a8e1175bSopenharmony_ci    size_t transform_expansion = 0;
5448a8e1175bSopenharmony_ci    const mbedtls_ssl_transform *transform = ssl->transform_out;
5449a8e1175bSopenharmony_ci    unsigned block_size;
5450a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
5451a8e1175bSopenharmony_ci    psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
5452a8e1175bSopenharmony_ci    psa_key_type_t key_type;
5453a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
5454a8e1175bSopenharmony_ci
5455a8e1175bSopenharmony_ci    size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl);
5456a8e1175bSopenharmony_ci
5457a8e1175bSopenharmony_ci    if (transform == NULL) {
5458a8e1175bSopenharmony_ci        return (int) out_hdr_len;
5459a8e1175bSopenharmony_ci    }
5460a8e1175bSopenharmony_ci
5461a8e1175bSopenharmony_ci
5462a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
5463a8e1175bSopenharmony_ci    if (transform->psa_alg == PSA_ALG_GCM ||
5464a8e1175bSopenharmony_ci        transform->psa_alg == PSA_ALG_CCM ||
5465a8e1175bSopenharmony_ci        transform->psa_alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 8) ||
5466a8e1175bSopenharmony_ci        transform->psa_alg == PSA_ALG_CHACHA20_POLY1305 ||
5467a8e1175bSopenharmony_ci        transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) {
5468a8e1175bSopenharmony_ci        transform_expansion = transform->minlen;
5469a8e1175bSopenharmony_ci    } else if (transform->psa_alg == PSA_ALG_CBC_NO_PADDING) {
5470a8e1175bSopenharmony_ci        (void) psa_get_key_attributes(transform->psa_key_enc, &attr);
5471a8e1175bSopenharmony_ci        key_type = psa_get_key_type(&attr);
5472a8e1175bSopenharmony_ci
5473a8e1175bSopenharmony_ci        block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
5474a8e1175bSopenharmony_ci
5475a8e1175bSopenharmony_ci        /* Expansion due to the addition of the MAC. */
5476a8e1175bSopenharmony_ci        transform_expansion += transform->maclen;
5477a8e1175bSopenharmony_ci
5478a8e1175bSopenharmony_ci        /* Expansion due to the addition of CBC padding;
5479a8e1175bSopenharmony_ci         * Theoretically up to 256 bytes, but we never use
5480a8e1175bSopenharmony_ci         * more than the block size of the underlying cipher. */
5481a8e1175bSopenharmony_ci        transform_expansion += block_size;
5482a8e1175bSopenharmony_ci
5483a8e1175bSopenharmony_ci        /* For TLS 1.2 or higher, an explicit IV is added
5484a8e1175bSopenharmony_ci         * after the record header. */
5485a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5486a8e1175bSopenharmony_ci        transform_expansion += block_size;
5487a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
5488a8e1175bSopenharmony_ci    } else {
5489a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1,
5490a8e1175bSopenharmony_ci                              ("Unsupported psa_alg spotted in mbedtls_ssl_get_record_expansion()"));
5491a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
5492a8e1175bSopenharmony_ci    }
5493a8e1175bSopenharmony_ci#else
5494a8e1175bSopenharmony_ci    switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) {
5495a8e1175bSopenharmony_ci        case MBEDTLS_MODE_GCM:
5496a8e1175bSopenharmony_ci        case MBEDTLS_MODE_CCM:
5497a8e1175bSopenharmony_ci        case MBEDTLS_MODE_CHACHAPOLY:
5498a8e1175bSopenharmony_ci        case MBEDTLS_MODE_STREAM:
5499a8e1175bSopenharmony_ci            transform_expansion = transform->minlen;
5500a8e1175bSopenharmony_ci            break;
5501a8e1175bSopenharmony_ci
5502a8e1175bSopenharmony_ci        case MBEDTLS_MODE_CBC:
5503a8e1175bSopenharmony_ci
5504a8e1175bSopenharmony_ci            block_size = mbedtls_cipher_get_block_size(
5505a8e1175bSopenharmony_ci                &transform->cipher_ctx_enc);
5506a8e1175bSopenharmony_ci
5507a8e1175bSopenharmony_ci            /* Expansion due to the addition of the MAC. */
5508a8e1175bSopenharmony_ci            transform_expansion += transform->maclen;
5509a8e1175bSopenharmony_ci
5510a8e1175bSopenharmony_ci            /* Expansion due to the addition of CBC padding;
5511a8e1175bSopenharmony_ci             * Theoretically up to 256 bytes, but we never use
5512a8e1175bSopenharmony_ci             * more than the block size of the underlying cipher. */
5513a8e1175bSopenharmony_ci            transform_expansion += block_size;
5514a8e1175bSopenharmony_ci
5515a8e1175bSopenharmony_ci            /* For TLS 1.2 or higher, an explicit IV is added
5516a8e1175bSopenharmony_ci             * after the record header. */
5517a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5518a8e1175bSopenharmony_ci            transform_expansion += block_size;
5519a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
5520a8e1175bSopenharmony_ci
5521a8e1175bSopenharmony_ci            break;
5522a8e1175bSopenharmony_ci
5523a8e1175bSopenharmony_ci        default:
5524a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
5525a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
5526a8e1175bSopenharmony_ci    }
5527a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
5528a8e1175bSopenharmony_ci
5529a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
5530a8e1175bSopenharmony_ci    if (transform->out_cid_len != 0) {
5531a8e1175bSopenharmony_ci        transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
5532a8e1175bSopenharmony_ci    }
5533a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
5534a8e1175bSopenharmony_ci
5535a8e1175bSopenharmony_ci    return (int) (out_hdr_len + transform_expansion);
5536a8e1175bSopenharmony_ci}
5537a8e1175bSopenharmony_ci
5538a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
5539a8e1175bSopenharmony_ci/*
5540a8e1175bSopenharmony_ci * Check record counters and renegotiate if they're above the limit.
5541a8e1175bSopenharmony_ci */
5542a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5543a8e1175bSopenharmony_cistatic int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
5544a8e1175bSopenharmony_ci{
5545a8e1175bSopenharmony_ci    size_t ep_len = mbedtls_ssl_ep_len(ssl);
5546a8e1175bSopenharmony_ci    int in_ctr_cmp;
5547a8e1175bSopenharmony_ci    int out_ctr_cmp;
5548a8e1175bSopenharmony_ci
5549a8e1175bSopenharmony_ci    if (mbedtls_ssl_is_handshake_over(ssl) == 0 ||
5550a8e1175bSopenharmony_ci        ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
5551a8e1175bSopenharmony_ci        ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
5552a8e1175bSopenharmony_ci        return 0;
5553a8e1175bSopenharmony_ci    }
5554a8e1175bSopenharmony_ci
5555a8e1175bSopenharmony_ci    in_ctr_cmp = memcmp(ssl->in_ctr + ep_len,
5556a8e1175bSopenharmony_ci                        &ssl->conf->renego_period[ep_len],
5557a8e1175bSopenharmony_ci                        MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len);
5558a8e1175bSopenharmony_ci    out_ctr_cmp = memcmp(&ssl->cur_out_ctr[ep_len],
5559a8e1175bSopenharmony_ci                         &ssl->conf->renego_period[ep_len],
5560a8e1175bSopenharmony_ci                         sizeof(ssl->cur_out_ctr) - ep_len);
5561a8e1175bSopenharmony_ci
5562a8e1175bSopenharmony_ci    if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) {
5563a8e1175bSopenharmony_ci        return 0;
5564a8e1175bSopenharmony_ci    }
5565a8e1175bSopenharmony_ci
5566a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate"));
5567a8e1175bSopenharmony_ci    return mbedtls_ssl_renegotiate(ssl);
5568a8e1175bSopenharmony_ci}
5569a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */
5570a8e1175bSopenharmony_ci
5571a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
5572a8e1175bSopenharmony_ci
5573a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
5574a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5575a8e1175bSopenharmony_cistatic int ssl_tls13_check_new_session_ticket(mbedtls_ssl_context *ssl)
5576a8e1175bSopenharmony_ci{
5577a8e1175bSopenharmony_ci
5578a8e1175bSopenharmony_ci    if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) ||
5579a8e1175bSopenharmony_ci        (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET)) {
5580a8e1175bSopenharmony_ci        return 0;
5581a8e1175bSopenharmony_ci    }
5582a8e1175bSopenharmony_ci
5583a8e1175bSopenharmony_ci    ssl->keep_current_message = 1;
5584a8e1175bSopenharmony_ci
5585a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
5586a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl,
5587a8e1175bSopenharmony_ci                                    MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
5588a8e1175bSopenharmony_ci
5589a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_WANT_READ;
5590a8e1175bSopenharmony_ci}
5591a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5592a8e1175bSopenharmony_ci
5593a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5594a8e1175bSopenharmony_cistatic int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
5595a8e1175bSopenharmony_ci{
5596a8e1175bSopenharmony_ci
5597a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message"));
5598a8e1175bSopenharmony_ci
5599a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
5600a8e1175bSopenharmony_ci    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5601a8e1175bSopenharmony_ci        int ret = ssl_tls13_check_new_session_ticket(ssl);
5602a8e1175bSopenharmony_ci        if (ret != 0) {
5603a8e1175bSopenharmony_ci            return ret;
5604a8e1175bSopenharmony_ci        }
5605a8e1175bSopenharmony_ci    }
5606a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
5607a8e1175bSopenharmony_ci
5608a8e1175bSopenharmony_ci    /* Fail in all other cases. */
5609a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5610a8e1175bSopenharmony_ci}
5611a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
5612a8e1175bSopenharmony_ci
5613a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5614a8e1175bSopenharmony_ci/* This function is called from mbedtls_ssl_read() when a handshake message is
5615a8e1175bSopenharmony_ci * received after the initial handshake. In this context, handshake messages
5616a8e1175bSopenharmony_ci * may only be sent for the purpose of initiating renegotiations.
5617a8e1175bSopenharmony_ci *
5618a8e1175bSopenharmony_ci * This function is introduced as a separate helper since the handling
5619a8e1175bSopenharmony_ci * of post-handshake handshake messages changes significantly in TLS 1.3,
5620a8e1175bSopenharmony_ci * and having a helper function allows to distinguish between TLS <= 1.2 and
5621a8e1175bSopenharmony_ci * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read().
5622a8e1175bSopenharmony_ci */
5623a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5624a8e1175bSopenharmony_cistatic int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
5625a8e1175bSopenharmony_ci{
5626a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5627a8e1175bSopenharmony_ci
5628a8e1175bSopenharmony_ci    /*
5629a8e1175bSopenharmony_ci     * - For client-side, expect SERVER_HELLO_REQUEST.
5630a8e1175bSopenharmony_ci     * - For server-side, expect CLIENT_HELLO.
5631a8e1175bSopenharmony_ci     * - Fail (TLS) or silently drop record (DTLS) in other cases.
5632a8e1175bSopenharmony_ci     */
5633a8e1175bSopenharmony_ci
5634a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CLI_C)
5635a8e1175bSopenharmony_ci    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
5636a8e1175bSopenharmony_ci        (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
5637a8e1175bSopenharmony_ci         ssl->in_hslen  != mbedtls_ssl_hs_hdr_len(ssl))) {
5638a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)"));
5639a8e1175bSopenharmony_ci
5640a8e1175bSopenharmony_ci        /* With DTLS, drop the packet (probably from last handshake) */
5641a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5642a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5643a8e1175bSopenharmony_ci            return 0;
5644a8e1175bSopenharmony_ci        }
5645a8e1175bSopenharmony_ci#endif
5646a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5647a8e1175bSopenharmony_ci    }
5648a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CLI_C */
5649a8e1175bSopenharmony_ci
5650a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C)
5651a8e1175bSopenharmony_ci    if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
5652a8e1175bSopenharmony_ci        ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
5653a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)"));
5654a8e1175bSopenharmony_ci
5655a8e1175bSopenharmony_ci        /* With DTLS, drop the packet (probably from last handshake) */
5656a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5657a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5658a8e1175bSopenharmony_ci            return 0;
5659a8e1175bSopenharmony_ci        }
5660a8e1175bSopenharmony_ci#endif
5661a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5662a8e1175bSopenharmony_ci    }
5663a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C */
5664a8e1175bSopenharmony_ci
5665a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
5666a8e1175bSopenharmony_ci    /* Determine whether renegotiation attempt should be accepted */
5667a8e1175bSopenharmony_ci    if (!(ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
5668a8e1175bSopenharmony_ci          (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
5669a8e1175bSopenharmony_ci           ssl->conf->allow_legacy_renegotiation ==
5670a8e1175bSopenharmony_ci           MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) {
5671a8e1175bSopenharmony_ci        /*
5672a8e1175bSopenharmony_ci         * Accept renegotiation request
5673a8e1175bSopenharmony_ci         */
5674a8e1175bSopenharmony_ci
5675a8e1175bSopenharmony_ci        /* DTLS clients need to know renego is server-initiated */
5676a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5677a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
5678a8e1175bSopenharmony_ci            ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5679a8e1175bSopenharmony_ci            ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
5680a8e1175bSopenharmony_ci        }
5681a8e1175bSopenharmony_ci#endif
5682a8e1175bSopenharmony_ci        ret = mbedtls_ssl_start_renegotiation(ssl);
5683a8e1175bSopenharmony_ci        if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5684a8e1175bSopenharmony_ci            ret != 0) {
5685a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation",
5686a8e1175bSopenharmony_ci                                  ret);
5687a8e1175bSopenharmony_ci            return ret;
5688a8e1175bSopenharmony_ci        }
5689a8e1175bSopenharmony_ci    } else
5690a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */
5691a8e1175bSopenharmony_ci    {
5692a8e1175bSopenharmony_ci        /*
5693a8e1175bSopenharmony_ci         * Refuse renegotiation
5694a8e1175bSopenharmony_ci         */
5695a8e1175bSopenharmony_ci
5696a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert"));
5697a8e1175bSopenharmony_ci
5698a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_send_alert_message(ssl,
5699a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_ALERT_LEVEL_WARNING,
5700a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) {
5701a8e1175bSopenharmony_ci            return ret;
5702a8e1175bSopenharmony_ci        }
5703a8e1175bSopenharmony_ci    }
5704a8e1175bSopenharmony_ci
5705a8e1175bSopenharmony_ci    return 0;
5706a8e1175bSopenharmony_ci}
5707a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
5708a8e1175bSopenharmony_ci
5709a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5710a8e1175bSopenharmony_cistatic int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
5711a8e1175bSopenharmony_ci{
5712a8e1175bSopenharmony_ci    /* Check protocol version and dispatch accordingly. */
5713a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
5714a8e1175bSopenharmony_ci    if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
5715a8e1175bSopenharmony_ci        return ssl_tls13_handle_hs_message_post_handshake(ssl);
5716a8e1175bSopenharmony_ci    }
5717a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
5718a8e1175bSopenharmony_ci
5719a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
5720a8e1175bSopenharmony_ci    if (ssl->tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) {
5721a8e1175bSopenharmony_ci        return ssl_tls12_handle_hs_message_post_handshake(ssl);
5722a8e1175bSopenharmony_ci    }
5723a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
5724a8e1175bSopenharmony_ci
5725a8e1175bSopenharmony_ci    /* Should never happen */
5726a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
5727a8e1175bSopenharmony_ci}
5728a8e1175bSopenharmony_ci
5729a8e1175bSopenharmony_ci/*
5730a8e1175bSopenharmony_ci * brief          Read at most 'len' application data bytes from the input
5731a8e1175bSopenharmony_ci *                buffer.
5732a8e1175bSopenharmony_ci *
5733a8e1175bSopenharmony_ci * param ssl      SSL context:
5734a8e1175bSopenharmony_ci *                - First byte of application data not read yet in the input
5735a8e1175bSopenharmony_ci *                  buffer located at address `in_offt`.
5736a8e1175bSopenharmony_ci *                - The number of bytes of data not read yet is `in_msglen`.
5737a8e1175bSopenharmony_ci * param buf      buffer that will hold the data
5738a8e1175bSopenharmony_ci * param len      maximum number of bytes to read
5739a8e1175bSopenharmony_ci *
5740a8e1175bSopenharmony_ci * note           The function updates the fields `in_offt` and `in_msglen`
5741a8e1175bSopenharmony_ci *                according to the number of bytes read.
5742a8e1175bSopenharmony_ci *
5743a8e1175bSopenharmony_ci * return         The number of bytes read.
5744a8e1175bSopenharmony_ci */
5745a8e1175bSopenharmony_cistatic int ssl_read_application_data(
5746a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
5747a8e1175bSopenharmony_ci{
5748a8e1175bSopenharmony_ci    size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
5749a8e1175bSopenharmony_ci
5750a8e1175bSopenharmony_ci    if (len != 0) {
5751a8e1175bSopenharmony_ci        memcpy(buf, ssl->in_offt, n);
5752a8e1175bSopenharmony_ci        ssl->in_msglen -= n;
5753a8e1175bSopenharmony_ci    }
5754a8e1175bSopenharmony_ci
5755a8e1175bSopenharmony_ci    /* Zeroising the plaintext buffer to erase unused application data
5756a8e1175bSopenharmony_ci       from the memory. */
5757a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(ssl->in_offt, n);
5758a8e1175bSopenharmony_ci
5759a8e1175bSopenharmony_ci    if (ssl->in_msglen == 0) {
5760a8e1175bSopenharmony_ci        /* all bytes consumed */
5761a8e1175bSopenharmony_ci        ssl->in_offt = NULL;
5762a8e1175bSopenharmony_ci        ssl->keep_current_message = 0;
5763a8e1175bSopenharmony_ci    } else {
5764a8e1175bSopenharmony_ci        /* more data available */
5765a8e1175bSopenharmony_ci        ssl->in_offt += n;
5766a8e1175bSopenharmony_ci    }
5767a8e1175bSopenharmony_ci
5768a8e1175bSopenharmony_ci    return (int) n;
5769a8e1175bSopenharmony_ci}
5770a8e1175bSopenharmony_ci
5771a8e1175bSopenharmony_ci/*
5772a8e1175bSopenharmony_ci * Receive application data decrypted from the SSL layer
5773a8e1175bSopenharmony_ci */
5774a8e1175bSopenharmony_ciint mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
5775a8e1175bSopenharmony_ci{
5776a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
5777a8e1175bSopenharmony_ci
5778a8e1175bSopenharmony_ci    if (ssl == NULL || ssl->conf == NULL) {
5779a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5780a8e1175bSopenharmony_ci    }
5781a8e1175bSopenharmony_ci
5782a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> read"));
5783a8e1175bSopenharmony_ci
5784a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5785a8e1175bSopenharmony_ci    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5786a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
5787a8e1175bSopenharmony_ci            return ret;
5788a8e1175bSopenharmony_ci        }
5789a8e1175bSopenharmony_ci
5790a8e1175bSopenharmony_ci        if (ssl->handshake != NULL &&
5791a8e1175bSopenharmony_ci            ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
5792a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
5793a8e1175bSopenharmony_ci                return ret;
5794a8e1175bSopenharmony_ci            }
5795a8e1175bSopenharmony_ci        }
5796a8e1175bSopenharmony_ci    }
5797a8e1175bSopenharmony_ci#endif
5798a8e1175bSopenharmony_ci
5799a8e1175bSopenharmony_ci    /*
5800a8e1175bSopenharmony_ci     * Check if renegotiation is necessary and/or handshake is
5801a8e1175bSopenharmony_ci     * in process. If yes, perform/continue, and fall through
5802a8e1175bSopenharmony_ci     * if an unexpected packet is received while the client
5803a8e1175bSopenharmony_ci     * is waiting for the ServerHello.
5804a8e1175bSopenharmony_ci     *
5805a8e1175bSopenharmony_ci     * (There is no equivalent to the last condition on
5806a8e1175bSopenharmony_ci     *  the server-side as it is not treated as within
5807a8e1175bSopenharmony_ci     *  a handshake while waiting for the ClientHello
5808a8e1175bSopenharmony_ci     *  after a renegotiation request.)
5809a8e1175bSopenharmony_ci     */
5810a8e1175bSopenharmony_ci
5811a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
5812a8e1175bSopenharmony_ci    ret = ssl_check_ctr_renegotiate(ssl);
5813a8e1175bSopenharmony_ci    if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5814a8e1175bSopenharmony_ci        ret != 0) {
5815a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
5816a8e1175bSopenharmony_ci        return ret;
5817a8e1175bSopenharmony_ci    }
5818a8e1175bSopenharmony_ci#endif
5819a8e1175bSopenharmony_ci
5820a8e1175bSopenharmony_ci    if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
5821a8e1175bSopenharmony_ci        ret = mbedtls_ssl_handshake(ssl);
5822a8e1175bSopenharmony_ci        if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
5823a8e1175bSopenharmony_ci            ret != 0) {
5824a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
5825a8e1175bSopenharmony_ci            return ret;
5826a8e1175bSopenharmony_ci        }
5827a8e1175bSopenharmony_ci    }
5828a8e1175bSopenharmony_ci
5829a8e1175bSopenharmony_ci    /* Loop as long as no application data record is available */
5830a8e1175bSopenharmony_ci    while (ssl->in_offt == NULL) {
5831a8e1175bSopenharmony_ci        /* Start timer if not already running */
5832a8e1175bSopenharmony_ci        if (ssl->f_get_timer != NULL &&
5833a8e1175bSopenharmony_ci            ssl->f_get_timer(ssl->p_timer) == -1) {
5834a8e1175bSopenharmony_ci            mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout);
5835a8e1175bSopenharmony_ci        }
5836a8e1175bSopenharmony_ci
5837a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
5838a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
5839a8e1175bSopenharmony_ci                return 0;
5840a8e1175bSopenharmony_ci            }
5841a8e1175bSopenharmony_ci
5842a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
5843a8e1175bSopenharmony_ci            return ret;
5844a8e1175bSopenharmony_ci        }
5845a8e1175bSopenharmony_ci
5846a8e1175bSopenharmony_ci        if (ssl->in_msglen  == 0 &&
5847a8e1175bSopenharmony_ci            ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
5848a8e1175bSopenharmony_ci            /*
5849a8e1175bSopenharmony_ci             * OpenSSL sends empty messages to randomize the IV
5850a8e1175bSopenharmony_ci             */
5851a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
5852a8e1175bSopenharmony_ci                if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
5853a8e1175bSopenharmony_ci                    return 0;
5854a8e1175bSopenharmony_ci                }
5855a8e1175bSopenharmony_ci
5856a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
5857a8e1175bSopenharmony_ci                return ret;
5858a8e1175bSopenharmony_ci            }
5859a8e1175bSopenharmony_ci        }
5860a8e1175bSopenharmony_ci
5861a8e1175bSopenharmony_ci        if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
5862a8e1175bSopenharmony_ci            ret = ssl_handle_hs_message_post_handshake(ssl);
5863a8e1175bSopenharmony_ci            if (ret != 0) {
5864a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake",
5865a8e1175bSopenharmony_ci                                      ret);
5866a8e1175bSopenharmony_ci                return ret;
5867a8e1175bSopenharmony_ci            }
5868a8e1175bSopenharmony_ci
5869a8e1175bSopenharmony_ci            /* At this point, we don't know whether the renegotiation triggered
5870a8e1175bSopenharmony_ci             * by the post-handshake message has been completed or not. The cases
5871a8e1175bSopenharmony_ci             * to consider are the following:
5872a8e1175bSopenharmony_ci             * 1) The renegotiation is complete. In this case, no new record
5873a8e1175bSopenharmony_ci             *    has been read yet.
5874a8e1175bSopenharmony_ci             * 2) The renegotiation is incomplete because the client received
5875a8e1175bSopenharmony_ci             *    an application data record while awaiting the ServerHello.
5876a8e1175bSopenharmony_ci             * 3) The renegotiation is incomplete because the client received
5877a8e1175bSopenharmony_ci             *    a non-handshake, non-application data message while awaiting
5878a8e1175bSopenharmony_ci             *    the ServerHello.
5879a8e1175bSopenharmony_ci             *
5880a8e1175bSopenharmony_ci             * In each of these cases, looping will be the proper action:
5881a8e1175bSopenharmony_ci             * - For 1), the next iteration will read a new record and check
5882a8e1175bSopenharmony_ci             *   if it's application data.
5883a8e1175bSopenharmony_ci             * - For 2), the loop condition isn't satisfied as application data
5884a8e1175bSopenharmony_ci             *   is present, hence continue is the same as break
5885a8e1175bSopenharmony_ci             * - For 3), the loop condition is satisfied and read_record
5886a8e1175bSopenharmony_ci             *   will re-deliver the message that was held back by the client
5887a8e1175bSopenharmony_ci             *   when expecting the ServerHello.
5888a8e1175bSopenharmony_ci             */
5889a8e1175bSopenharmony_ci
5890a8e1175bSopenharmony_ci            continue;
5891a8e1175bSopenharmony_ci        }
5892a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
5893a8e1175bSopenharmony_ci        else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
5894a8e1175bSopenharmony_ci            if (ssl->conf->renego_max_records >= 0) {
5895a8e1175bSopenharmony_ci                if (++ssl->renego_records_seen > ssl->conf->renego_max_records) {
5896a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, "
5897a8e1175bSopenharmony_ci                                              "but not honored by client"));
5898a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5899a8e1175bSopenharmony_ci                }
5900a8e1175bSopenharmony_ci            }
5901a8e1175bSopenharmony_ci        }
5902a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */
5903a8e1175bSopenharmony_ci
5904a8e1175bSopenharmony_ci        /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
5905a8e1175bSopenharmony_ci        if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
5906a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert"));
5907a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_WANT_READ;
5908a8e1175bSopenharmony_ci        }
5909a8e1175bSopenharmony_ci
5910a8e1175bSopenharmony_ci        if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
5911a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message"));
5912a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5913a8e1175bSopenharmony_ci        }
5914a8e1175bSopenharmony_ci
5915a8e1175bSopenharmony_ci        ssl->in_offt = ssl->in_msg;
5916a8e1175bSopenharmony_ci
5917a8e1175bSopenharmony_ci        /* We're going to return something now, cancel timer,
5918a8e1175bSopenharmony_ci         * except if handshake (renegotiation) is in progress */
5919a8e1175bSopenharmony_ci        if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
5920a8e1175bSopenharmony_ci            mbedtls_ssl_set_timer(ssl, 0);
5921a8e1175bSopenharmony_ci        }
5922a8e1175bSopenharmony_ci
5923a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5924a8e1175bSopenharmony_ci        /* If we requested renego but received AppData, resend HelloRequest.
5925a8e1175bSopenharmony_ci         * Do it now, after setting in_offt, to avoid taking this branch
5926a8e1175bSopenharmony_ci         * again if ssl_write_hello_request() returns WANT_WRITE */
5927a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
5928a8e1175bSopenharmony_ci        if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
5929a8e1175bSopenharmony_ci            ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
5930a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
5931a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
5932a8e1175bSopenharmony_ci                                      ret);
5933a8e1175bSopenharmony_ci                return ret;
5934a8e1175bSopenharmony_ci            }
5935a8e1175bSopenharmony_ci        }
5936a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
5937a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
5938a8e1175bSopenharmony_ci    }
5939a8e1175bSopenharmony_ci
5940a8e1175bSopenharmony_ci    ret = ssl_read_application_data(ssl, buf, len);
5941a8e1175bSopenharmony_ci
5942a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
5943a8e1175bSopenharmony_ci
5944a8e1175bSopenharmony_ci    return ret;
5945a8e1175bSopenharmony_ci}
5946a8e1175bSopenharmony_ci
5947a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
5948a8e1175bSopenharmony_ciint mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
5949a8e1175bSopenharmony_ci                                unsigned char *buf, size_t len)
5950a8e1175bSopenharmony_ci{
5951a8e1175bSopenharmony_ci    if (ssl == NULL || (ssl->conf == NULL)) {
5952a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5953a8e1175bSopenharmony_ci    }
5954a8e1175bSopenharmony_ci
5955a8e1175bSopenharmony_ci    /*
5956a8e1175bSopenharmony_ci     * The server may receive early data only while waiting for the End of
5957a8e1175bSopenharmony_ci     * Early Data handshake message.
5958a8e1175bSopenharmony_ci     */
5959a8e1175bSopenharmony_ci    if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
5960a8e1175bSopenharmony_ci        (ssl->in_offt == NULL)) {
5961a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
5962a8e1175bSopenharmony_ci    }
5963a8e1175bSopenharmony_ci
5964a8e1175bSopenharmony_ci    return ssl_read_application_data(ssl, buf, len);
5965a8e1175bSopenharmony_ci}
5966a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
5967a8e1175bSopenharmony_ci
5968a8e1175bSopenharmony_ci/*
5969a8e1175bSopenharmony_ci * Send application data to be encrypted by the SSL layer, taking care of max
5970a8e1175bSopenharmony_ci * fragment length and buffer size.
5971a8e1175bSopenharmony_ci *
5972a8e1175bSopenharmony_ci * According to RFC 5246 Section 6.2.1:
5973a8e1175bSopenharmony_ci *
5974a8e1175bSopenharmony_ci *      Zero-length fragments of Application data MAY be sent as they are
5975a8e1175bSopenharmony_ci *      potentially useful as a traffic analysis countermeasure.
5976a8e1175bSopenharmony_ci *
5977a8e1175bSopenharmony_ci * Therefore, it is possible that the input message length is 0 and the
5978a8e1175bSopenharmony_ci * corresponding return code is 0 on success.
5979a8e1175bSopenharmony_ci */
5980a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
5981a8e1175bSopenharmony_cistatic int ssl_write_real(mbedtls_ssl_context *ssl,
5982a8e1175bSopenharmony_ci                          const unsigned char *buf, size_t len)
5983a8e1175bSopenharmony_ci{
5984a8e1175bSopenharmony_ci    int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
5985a8e1175bSopenharmony_ci    const size_t max_len = (size_t) ret;
5986a8e1175bSopenharmony_ci
5987a8e1175bSopenharmony_ci    if (ret < 0) {
5988a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret);
5989a8e1175bSopenharmony_ci        return ret;
5990a8e1175bSopenharmony_ci    }
5991a8e1175bSopenharmony_ci
5992a8e1175bSopenharmony_ci    if (len > max_len) {
5993a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
5994a8e1175bSopenharmony_ci        if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5995a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("fragment larger than the (negotiated) "
5996a8e1175bSopenharmony_ci                                      "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
5997a8e1175bSopenharmony_ci                                      " > %" MBEDTLS_PRINTF_SIZET,
5998a8e1175bSopenharmony_ci                                      len, max_len));
5999a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6000a8e1175bSopenharmony_ci        } else
6001a8e1175bSopenharmony_ci#endif
6002a8e1175bSopenharmony_ci        len = max_len;
6003a8e1175bSopenharmony_ci    }
6004a8e1175bSopenharmony_ci
6005a8e1175bSopenharmony_ci    if (ssl->out_left != 0) {
6006a8e1175bSopenharmony_ci        /*
6007a8e1175bSopenharmony_ci         * The user has previously tried to send the data and
6008a8e1175bSopenharmony_ci         * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
6009a8e1175bSopenharmony_ci         * written. In this case, we expect the high-level write function
6010a8e1175bSopenharmony_ci         * (e.g. mbedtls_ssl_write()) to be called with the same parameters
6011a8e1175bSopenharmony_ci         */
6012a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
6013a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
6014a8e1175bSopenharmony_ci            return ret;
6015a8e1175bSopenharmony_ci        }
6016a8e1175bSopenharmony_ci    } else {
6017a8e1175bSopenharmony_ci        /*
6018a8e1175bSopenharmony_ci         * The user is trying to send a message the first time, so we need to
6019a8e1175bSopenharmony_ci         * copy the data into the internal buffers and setup the data structure
6020a8e1175bSopenharmony_ci         * to keep track of partial writes
6021a8e1175bSopenharmony_ci         */
6022a8e1175bSopenharmony_ci        ssl->out_msglen  = len;
6023a8e1175bSopenharmony_ci        ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
6024a8e1175bSopenharmony_ci        if (len > 0) {
6025a8e1175bSopenharmony_ci            memcpy(ssl->out_msg, buf, len);
6026a8e1175bSopenharmony_ci        }
6027a8e1175bSopenharmony_ci
6028a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
6029a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
6030a8e1175bSopenharmony_ci            return ret;
6031a8e1175bSopenharmony_ci        }
6032a8e1175bSopenharmony_ci    }
6033a8e1175bSopenharmony_ci
6034a8e1175bSopenharmony_ci    return (int) len;
6035a8e1175bSopenharmony_ci}
6036a8e1175bSopenharmony_ci
6037a8e1175bSopenharmony_ci/*
6038a8e1175bSopenharmony_ci * Write application data (public-facing wrapper)
6039a8e1175bSopenharmony_ci */
6040a8e1175bSopenharmony_ciint mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
6041a8e1175bSopenharmony_ci{
6042a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6043a8e1175bSopenharmony_ci
6044a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write"));
6045a8e1175bSopenharmony_ci
6046a8e1175bSopenharmony_ci    if (ssl == NULL || ssl->conf == NULL) {
6047a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6048a8e1175bSopenharmony_ci    }
6049a8e1175bSopenharmony_ci
6050a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
6051a8e1175bSopenharmony_ci    if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) {
6052a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
6053a8e1175bSopenharmony_ci        return ret;
6054a8e1175bSopenharmony_ci    }
6055a8e1175bSopenharmony_ci#endif
6056a8e1175bSopenharmony_ci
6057a8e1175bSopenharmony_ci    if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
6058a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
6059a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6060a8e1175bSopenharmony_ci            return ret;
6061a8e1175bSopenharmony_ci        }
6062a8e1175bSopenharmony_ci    }
6063a8e1175bSopenharmony_ci
6064a8e1175bSopenharmony_ci    ret = ssl_write_real(ssl, buf, len);
6065a8e1175bSopenharmony_ci
6066a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write"));
6067a8e1175bSopenharmony_ci
6068a8e1175bSopenharmony_ci    return ret;
6069a8e1175bSopenharmony_ci}
6070a8e1175bSopenharmony_ci
6071a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
6072a8e1175bSopenharmony_ciint mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
6073a8e1175bSopenharmony_ci                                 const unsigned char *buf, size_t len)
6074a8e1175bSopenharmony_ci{
6075a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6076a8e1175bSopenharmony_ci    const struct mbedtls_ssl_config *conf;
6077a8e1175bSopenharmony_ci    uint32_t remaining;
6078a8e1175bSopenharmony_ci
6079a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
6080a8e1175bSopenharmony_ci
6081a8e1175bSopenharmony_ci    if (ssl == NULL || (conf = ssl->conf) == NULL) {
6082a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6083a8e1175bSopenharmony_ci    }
6084a8e1175bSopenharmony_ci
6085a8e1175bSopenharmony_ci    if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
6086a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6087a8e1175bSopenharmony_ci    }
6088a8e1175bSopenharmony_ci
6089a8e1175bSopenharmony_ci    if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
6090a8e1175bSopenharmony_ci        (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
6091a8e1175bSopenharmony_ci        (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
6092a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6093a8e1175bSopenharmony_ci    }
6094a8e1175bSopenharmony_ci
6095a8e1175bSopenharmony_ci    if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
6096a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6097a8e1175bSopenharmony_ci    }
6098a8e1175bSopenharmony_ci
6099a8e1175bSopenharmony_ci    /*
6100a8e1175bSopenharmony_ci     * If we are at the beginning of the handshake, the early data state being
6101a8e1175bSopenharmony_ci     * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or
6102a8e1175bSopenharmony_ci     * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just
6103a8e1175bSopenharmony_ci     * enough to be able to send early data if possible. That way, we can
6104a8e1175bSopenharmony_ci     * guarantee that when starting the handshake with this function we will
6105a8e1175bSopenharmony_ci     * send at least one record of early data. Note that when the state is
6106a8e1175bSopenharmony_ci     * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet
6107a8e1175bSopenharmony_ci     * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data
6108a8e1175bSopenharmony_ci     * as the early data outbound transform has not been set as we may have to
6109a8e1175bSopenharmony_ci     * first send a dummy CCS in clear.
6110a8e1175bSopenharmony_ci     */
6111a8e1175bSopenharmony_ci    if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6112a8e1175bSopenharmony_ci        (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6113a8e1175bSopenharmony_ci        while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6114a8e1175bSopenharmony_ci               (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6115a8e1175bSopenharmony_ci            ret = mbedtls_ssl_handshake_step(ssl);
6116a8e1175bSopenharmony_ci            if (ret != 0) {
6117a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
6118a8e1175bSopenharmony_ci                return ret;
6119a8e1175bSopenharmony_ci            }
6120a8e1175bSopenharmony_ci
6121a8e1175bSopenharmony_ci            ret = mbedtls_ssl_flush_output(ssl);
6122a8e1175bSopenharmony_ci            if (ret != 0) {
6123a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
6124a8e1175bSopenharmony_ci                return ret;
6125a8e1175bSopenharmony_ci            }
6126a8e1175bSopenharmony_ci        }
6127a8e1175bSopenharmony_ci        remaining = ssl->session_negotiate->max_early_data_size;
6128a8e1175bSopenharmony_ci    } else {
6129a8e1175bSopenharmony_ci        /*
6130a8e1175bSopenharmony_ci         * If we are past the point where we can send early data or we have
6131a8e1175bSopenharmony_ci         * already reached the maximum early data size, return immediatly.
6132a8e1175bSopenharmony_ci         * Otherwise, progress the handshake as much as possible to not delay
6133a8e1175bSopenharmony_ci         * it too much. If we reach a point where we can still send early data,
6134a8e1175bSopenharmony_ci         * then we will send some.
6135a8e1175bSopenharmony_ci         */
6136a8e1175bSopenharmony_ci        if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6137a8e1175bSopenharmony_ci            (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
6138a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6139a8e1175bSopenharmony_ci        }
6140a8e1175bSopenharmony_ci
6141a8e1175bSopenharmony_ci        remaining = ssl->session_negotiate->max_early_data_size -
6142a8e1175bSopenharmony_ci                    ssl->total_early_data_size;
6143a8e1175bSopenharmony_ci
6144a8e1175bSopenharmony_ci        if (remaining == 0) {
6145a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6146a8e1175bSopenharmony_ci        }
6147a8e1175bSopenharmony_ci
6148a8e1175bSopenharmony_ci        ret = mbedtls_ssl_handshake(ssl);
6149a8e1175bSopenharmony_ci        if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
6150a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6151a8e1175bSopenharmony_ci            return ret;
6152a8e1175bSopenharmony_ci        }
6153a8e1175bSopenharmony_ci    }
6154a8e1175bSopenharmony_ci
6155a8e1175bSopenharmony_ci    if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6156a8e1175bSopenharmony_ci         (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
6157a8e1175bSopenharmony_ci        || (remaining == 0)) {
6158a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6159a8e1175bSopenharmony_ci    }
6160a8e1175bSopenharmony_ci
6161a8e1175bSopenharmony_ci    if (len > remaining) {
6162a8e1175bSopenharmony_ci        len = remaining;
6163a8e1175bSopenharmony_ci    }
6164a8e1175bSopenharmony_ci
6165a8e1175bSopenharmony_ci    ret = ssl_write_real(ssl, buf, len);
6166a8e1175bSopenharmony_ci    if (ret >= 0) {
6167a8e1175bSopenharmony_ci        ssl->total_early_data_size += ret;
6168a8e1175bSopenharmony_ci    }
6169a8e1175bSopenharmony_ci
6170a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
6171a8e1175bSopenharmony_ci
6172a8e1175bSopenharmony_ci    return ret;
6173a8e1175bSopenharmony_ci}
6174a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
6175a8e1175bSopenharmony_ci
6176a8e1175bSopenharmony_ci/*
6177a8e1175bSopenharmony_ci * Notify the peer that the connection is being closed
6178a8e1175bSopenharmony_ci */
6179a8e1175bSopenharmony_ciint mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
6180a8e1175bSopenharmony_ci{
6181a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6182a8e1175bSopenharmony_ci
6183a8e1175bSopenharmony_ci    if (ssl == NULL || ssl->conf == NULL) {
6184a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6185a8e1175bSopenharmony_ci    }
6186a8e1175bSopenharmony_ci
6187a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify"));
6188a8e1175bSopenharmony_ci
6189a8e1175bSopenharmony_ci    if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
6190a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_send_alert_message(ssl,
6191a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_ALERT_LEVEL_WARNING,
6192a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) {
6193a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret);
6194a8e1175bSopenharmony_ci            return ret;
6195a8e1175bSopenharmony_ci        }
6196a8e1175bSopenharmony_ci    }
6197a8e1175bSopenharmony_ci
6198a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify"));
6199a8e1175bSopenharmony_ci
6200a8e1175bSopenharmony_ci    return 0;
6201a8e1175bSopenharmony_ci}
6202a8e1175bSopenharmony_ci
6203a8e1175bSopenharmony_civoid mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform)
6204a8e1175bSopenharmony_ci{
6205a8e1175bSopenharmony_ci    if (transform == NULL) {
6206a8e1175bSopenharmony_ci        return;
6207a8e1175bSopenharmony_ci    }
6208a8e1175bSopenharmony_ci
6209a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
6210a8e1175bSopenharmony_ci    psa_destroy_key(transform->psa_key_enc);
6211a8e1175bSopenharmony_ci    psa_destroy_key(transform->psa_key_dec);
6212a8e1175bSopenharmony_ci#else
6213a8e1175bSopenharmony_ci    mbedtls_cipher_free(&transform->cipher_ctx_enc);
6214a8e1175bSopenharmony_ci    mbedtls_cipher_free(&transform->cipher_ctx_dec);
6215a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
6216a8e1175bSopenharmony_ci
6217a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
6218a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
6219a8e1175bSopenharmony_ci    psa_destroy_key(transform->psa_mac_enc);
6220a8e1175bSopenharmony_ci    psa_destroy_key(transform->psa_mac_dec);
6221a8e1175bSopenharmony_ci#else
6222a8e1175bSopenharmony_ci    mbedtls_md_free(&transform->md_ctx_enc);
6223a8e1175bSopenharmony_ci    mbedtls_md_free(&transform->md_ctx_dec);
6224a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
6225a8e1175bSopenharmony_ci#endif
6226a8e1175bSopenharmony_ci
6227a8e1175bSopenharmony_ci    mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform));
6228a8e1175bSopenharmony_ci}
6229a8e1175bSopenharmony_ci
6230a8e1175bSopenharmony_civoid mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl,
6231a8e1175bSopenharmony_ci                                       mbedtls_ssl_transform *transform)
6232a8e1175bSopenharmony_ci{
6233a8e1175bSopenharmony_ci    ssl->transform_in = transform;
6234a8e1175bSopenharmony_ci    memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
6235a8e1175bSopenharmony_ci}
6236a8e1175bSopenharmony_ci
6237a8e1175bSopenharmony_civoid mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl,
6238a8e1175bSopenharmony_ci                                        mbedtls_ssl_transform *transform)
6239a8e1175bSopenharmony_ci{
6240a8e1175bSopenharmony_ci    ssl->transform_out = transform;
6241a8e1175bSopenharmony_ci    memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr));
6242a8e1175bSopenharmony_ci}
6243a8e1175bSopenharmony_ci
6244a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
6245a8e1175bSopenharmony_ci
6246a8e1175bSopenharmony_civoid mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl)
6247a8e1175bSopenharmony_ci{
6248a8e1175bSopenharmony_ci    unsigned offset;
6249a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
6250a8e1175bSopenharmony_ci
6251a8e1175bSopenharmony_ci    if (hs == NULL) {
6252a8e1175bSopenharmony_ci        return;
6253a8e1175bSopenharmony_ci    }
6254a8e1175bSopenharmony_ci
6255a8e1175bSopenharmony_ci    ssl_free_buffered_record(ssl);
6256a8e1175bSopenharmony_ci
6257a8e1175bSopenharmony_ci    for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
6258a8e1175bSopenharmony_ci        ssl_buffering_free_slot(ssl, offset);
6259a8e1175bSopenharmony_ci    }
6260a8e1175bSopenharmony_ci}
6261a8e1175bSopenharmony_ci
6262a8e1175bSopenharmony_cistatic void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
6263a8e1175bSopenharmony_ci                                    uint8_t slot)
6264a8e1175bSopenharmony_ci{
6265a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params * const hs = ssl->handshake;
6266a8e1175bSopenharmony_ci    mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
6267a8e1175bSopenharmony_ci
6268a8e1175bSopenharmony_ci    if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
6269a8e1175bSopenharmony_ci        return;
6270a8e1175bSopenharmony_ci    }
6271a8e1175bSopenharmony_ci
6272a8e1175bSopenharmony_ci    if (hs_buf->is_valid == 1) {
6273a8e1175bSopenharmony_ci        hs->buffering.total_bytes_buffered -= hs_buf->data_len;
6274a8e1175bSopenharmony_ci        mbedtls_zeroize_and_free(hs_buf->data, hs_buf->data_len);
6275a8e1175bSopenharmony_ci        memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
6276a8e1175bSopenharmony_ci    }
6277a8e1175bSopenharmony_ci}
6278a8e1175bSopenharmony_ci
6279a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
6280a8e1175bSopenharmony_ci
6281a8e1175bSopenharmony_ci/*
6282a8e1175bSopenharmony_ci * Convert version numbers to/from wire format
6283a8e1175bSopenharmony_ci * and, for DTLS, to/from TLS equivalent.
6284a8e1175bSopenharmony_ci *
6285a8e1175bSopenharmony_ci * For TLS this is the identity.
6286a8e1175bSopenharmony_ci * For DTLS, map as follows, then use 1's complement (v -> ~v):
6287a8e1175bSopenharmony_ci * 1.x <-> 3.x+1    for x != 0 (DTLS 1.2 based on TLS 1.2)
6288a8e1175bSopenharmony_ci *                  DTLS 1.0 is stored as TLS 1.1 internally
6289a8e1175bSopenharmony_ci */
6290a8e1175bSopenharmony_civoid mbedtls_ssl_write_version(unsigned char version[2], int transport,
6291a8e1175bSopenharmony_ci                               mbedtls_ssl_protocol_version tls_version)
6292a8e1175bSopenharmony_ci{
6293a8e1175bSopenharmony_ci    uint16_t tls_version_formatted;
6294a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
6295a8e1175bSopenharmony_ci    if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6296a8e1175bSopenharmony_ci        tls_version_formatted =
6297a8e1175bSopenharmony_ci            ~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201));
6298a8e1175bSopenharmony_ci    } else
6299a8e1175bSopenharmony_ci#else
6300a8e1175bSopenharmony_ci    ((void) transport);
6301a8e1175bSopenharmony_ci#endif
6302a8e1175bSopenharmony_ci    {
6303a8e1175bSopenharmony_ci        tls_version_formatted = (uint16_t) tls_version;
6304a8e1175bSopenharmony_ci    }
6305a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(tls_version_formatted, version, 0);
6306a8e1175bSopenharmony_ci}
6307a8e1175bSopenharmony_ci
6308a8e1175bSopenharmony_ciuint16_t mbedtls_ssl_read_version(const unsigned char version[2],
6309a8e1175bSopenharmony_ci                                  int transport)
6310a8e1175bSopenharmony_ci{
6311a8e1175bSopenharmony_ci    uint16_t tls_version = MBEDTLS_GET_UINT16_BE(version, 0);
6312a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
6313a8e1175bSopenharmony_ci    if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6314a8e1175bSopenharmony_ci        tls_version =
6315a8e1175bSopenharmony_ci            ~(tls_version - (tls_version == 0xfeff ? 0x0202 : 0x0201));
6316a8e1175bSopenharmony_ci    }
6317a8e1175bSopenharmony_ci#else
6318a8e1175bSopenharmony_ci    ((void) transport);
6319a8e1175bSopenharmony_ci#endif
6320a8e1175bSopenharmony_ci    return tls_version;
6321a8e1175bSopenharmony_ci}
6322a8e1175bSopenharmony_ci
6323a8e1175bSopenharmony_ci/*
6324a8e1175bSopenharmony_ci * Send pending fatal alert.
6325a8e1175bSopenharmony_ci * 0,   No alert message.
6326a8e1175bSopenharmony_ci * !0,  if mbedtls_ssl_send_alert_message() returned in error, the error code it
6327a8e1175bSopenharmony_ci *      returned, ssl->alert_reason otherwise.
6328a8e1175bSopenharmony_ci */
6329a8e1175bSopenharmony_ciint mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl)
6330a8e1175bSopenharmony_ci{
6331a8e1175bSopenharmony_ci    int ret;
6332a8e1175bSopenharmony_ci
6333a8e1175bSopenharmony_ci    /* No pending alert, return success*/
6334a8e1175bSopenharmony_ci    if (ssl->send_alert == 0) {
6335a8e1175bSopenharmony_ci        return 0;
6336a8e1175bSopenharmony_ci    }
6337a8e1175bSopenharmony_ci
6338a8e1175bSopenharmony_ci    ret = mbedtls_ssl_send_alert_message(ssl,
6339a8e1175bSopenharmony_ci                                         MBEDTLS_SSL_ALERT_LEVEL_FATAL,
6340a8e1175bSopenharmony_ci                                         ssl->alert_type);
6341a8e1175bSopenharmony_ci
6342a8e1175bSopenharmony_ci    /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE,
6343a8e1175bSopenharmony_ci     * do not clear the alert to be able to send it later.
6344a8e1175bSopenharmony_ci     */
6345a8e1175bSopenharmony_ci    if (ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
6346a8e1175bSopenharmony_ci        ssl->send_alert = 0;
6347a8e1175bSopenharmony_ci    }
6348a8e1175bSopenharmony_ci
6349a8e1175bSopenharmony_ci    if (ret != 0) {
6350a8e1175bSopenharmony_ci        return ret;
6351a8e1175bSopenharmony_ci    }
6352a8e1175bSopenharmony_ci
6353a8e1175bSopenharmony_ci    return ssl->alert_reason;
6354a8e1175bSopenharmony_ci}
6355a8e1175bSopenharmony_ci
6356a8e1175bSopenharmony_ci/*
6357a8e1175bSopenharmony_ci * Set pending fatal alert flag.
6358a8e1175bSopenharmony_ci */
6359a8e1175bSopenharmony_civoid mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl,
6360a8e1175bSopenharmony_ci                                  unsigned char alert_type,
6361a8e1175bSopenharmony_ci                                  int alert_reason)
6362a8e1175bSopenharmony_ci{
6363a8e1175bSopenharmony_ci    ssl->send_alert = 1;
6364a8e1175bSopenharmony_ci    ssl->alert_type = alert_type;
6365a8e1175bSopenharmony_ci    ssl->alert_reason = alert_reason;
6366a8e1175bSopenharmony_ci}
6367a8e1175bSopenharmony_ci
6368a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS_C */
6369