111fa71b9SJerome Forissier /*
211fa71b9SJerome Forissier * Generic SSL/TLS messaging layer functions
311fa71b9SJerome Forissier * (record layer + retransmission state machine)
411fa71b9SJerome Forissier *
57901324dSJerome Forissier * Copyright The Mbed TLS Contributors
6b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
711fa71b9SJerome Forissier */
811fa71b9SJerome Forissier /*
911fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc2246.txt
1011fa71b9SJerome Forissier * http://www.ietf.org/rfc/rfc4346.txt
1111fa71b9SJerome Forissier */
1211fa71b9SJerome Forissier
137901324dSJerome Forissier #include "common.h"
1411fa71b9SJerome Forissier
1511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_TLS_C)
1611fa71b9SJerome Forissier
1711fa71b9SJerome Forissier #include "mbedtls/platform.h"
1811fa71b9SJerome Forissier
1911fa71b9SJerome Forissier #include "mbedtls/ssl.h"
2032b31808SJens Wiklander #include "ssl_misc.h"
21b0563631STom Van Eyck #include "debug_internal.h"
2211fa71b9SJerome Forissier #include "mbedtls/error.h"
2311fa71b9SJerome Forissier #include "mbedtls/platform_util.h"
2411fa71b9SJerome Forissier #include "mbedtls/version.h"
25039e02dfSJerome Forissier #include "constant_time_internal.h"
26039e02dfSJerome Forissier #include "mbedtls/constant_time.h"
277901324dSJerome Forissier
28c3deb3d6SEtienne Carriere #include <limits.h>
2911fa71b9SJerome Forissier #include <string.h>
3011fa71b9SJerome Forissier
3111fa71b9SJerome Forissier #if defined(MBEDTLS_USE_PSA_CRYPTO)
32b0563631STom Van Eyck #include "psa_util_internal.h"
3311fa71b9SJerome Forissier #include "psa/crypto.h"
3411fa71b9SJerome Forissier #endif
3511fa71b9SJerome Forissier
3611fa71b9SJerome Forissier #if defined(MBEDTLS_X509_CRT_PARSE_C)
3711fa71b9SJerome Forissier #include "mbedtls/oid.h"
3811fa71b9SJerome Forissier #endif
3911fa71b9SJerome Forissier
4032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
41b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many
42b0563631STom Van Eyck * arguments in each translating place. */
local_err_translation(psa_status_t status)43b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
44b0563631STom Van Eyck {
45b0563631STom Van Eyck return psa_status_to_mbedtls(status, psa_to_ssl_errors,
46b0563631STom Van Eyck ARRAY_LENGTH(psa_to_ssl_errors),
47b0563631STom Van Eyck psa_generic_status_to_mbedtls);
48b0563631STom Van Eyck }
49b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
5032b31808SJens Wiklander #endif
5132b31808SJens Wiklander
52b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
53b0563631STom Van Eyck
54b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
55b0563631STom Van Eyck
56b0563631STom Van Eyck #if defined(PSA_WANT_ALG_SHA_384)
57b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384)
58b0563631STom Van Eyck #elif defined(PSA_WANT_ALG_SHA_256)
59b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)
60b0563631STom Van Eyck #else /* See check_config.h */
61b0563631STom Van Eyck #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1)
62b0563631STom Van Eyck #endif
63b0563631STom Van Eyck
64b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE
mbedtls_ct_hmac(mbedtls_svc_key_id_t key,psa_algorithm_t mac_alg,const unsigned char * add_data,size_t add_data_len,const unsigned char * data,size_t data_len_secret,size_t min_data_len,size_t max_data_len,unsigned char * output)65b0563631STom Van Eyck int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
66b0563631STom Van Eyck psa_algorithm_t mac_alg,
67b0563631STom Van Eyck const unsigned char *add_data,
68b0563631STom Van Eyck size_t add_data_len,
69b0563631STom Van Eyck const unsigned char *data,
70b0563631STom Van Eyck size_t data_len_secret,
71b0563631STom Van Eyck size_t min_data_len,
72b0563631STom Van Eyck size_t max_data_len,
73b0563631STom Van Eyck unsigned char *output)
74b0563631STom Van Eyck {
75b0563631STom Van Eyck /*
76b0563631STom Van Eyck * This function breaks the HMAC abstraction and uses psa_hash_clone()
77b0563631STom Van Eyck * extension in order to get constant-flow behaviour.
78b0563631STom Van Eyck *
79b0563631STom Van Eyck * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
80b0563631STom Van Eyck * concatenation, and okey/ikey are the XOR of the key with some fixed bit
81b0563631STom Van Eyck * patterns (see RFC 2104, sec. 2).
82b0563631STom Van Eyck *
83b0563631STom Van Eyck * We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
84b0563631STom Van Eyck * hashing up to minlen, then cloning the context, and for each byte up
85b0563631STom Van Eyck * to maxlen finishing up the hash computation, keeping only the
86b0563631STom Van Eyck * correct result.
87b0563631STom Van Eyck *
88b0563631STom Van Eyck * Then we only need to compute HASH(okey + inner_hash) and we're done.
89b0563631STom Van Eyck */
90b0563631STom Van Eyck psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
91b0563631STom Van Eyck const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
92b0563631STom Van Eyck unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
93b0563631STom Van Eyck const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
94b0563631STom Van Eyck psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
95b0563631STom Van Eyck size_t hash_length;
96b0563631STom Van Eyck
97b0563631STom Van Eyck unsigned char aux_out[PSA_HASH_MAX_SIZE];
98b0563631STom Van Eyck psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
99b0563631STom Van Eyck size_t offset;
100b0563631STom Van Eyck psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
101b0563631STom Van Eyck
102b0563631STom Van Eyck size_t mac_key_length;
103b0563631STom Van Eyck size_t i;
104b0563631STom Van Eyck
105b0563631STom Van Eyck #define PSA_CHK(func_call) \
106b0563631STom Van Eyck do { \
107b0563631STom Van Eyck status = (func_call); \
108b0563631STom Van Eyck if (status != PSA_SUCCESS) \
109b0563631STom Van Eyck goto cleanup; \
110b0563631STom Van Eyck } while (0)
111b0563631STom Van Eyck
112b0563631STom Van Eyck /* Export MAC key
113b0563631STom Van Eyck * We assume key length is always exactly the output size
114b0563631STom Van Eyck * which is never more than the block size, thus we use block_size
115b0563631STom Van Eyck * as the key buffer size.
116b0563631STom Van Eyck */
117b0563631STom Van Eyck PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
118b0563631STom Van Eyck
119b0563631STom Van Eyck /* Calculate ikey */
120b0563631STom Van Eyck for (i = 0; i < mac_key_length; i++) {
121b0563631STom Van Eyck key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
122b0563631STom Van Eyck }
123b0563631STom Van Eyck for (; i < block_size; ++i) {
124b0563631STom Van Eyck key_buf[i] = 0x36;
125b0563631STom Van Eyck }
126b0563631STom Van Eyck
127b0563631STom Van Eyck PSA_CHK(psa_hash_setup(&operation, hash_alg));
128b0563631STom Van Eyck
129b0563631STom Van Eyck /* Now compute inner_hash = HASH(ikey + msg) */
130b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
131b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
132b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, data, min_data_len));
133b0563631STom Van Eyck
134b0563631STom Van Eyck /* Fill the hash buffer in advance with something that is
135b0563631STom Van Eyck * not a valid hash (barring an attack on the hash and
136b0563631STom Van Eyck * deliberately-crafted input), in case the caller doesn't
137b0563631STom Van Eyck * check the return status properly. */
138b0563631STom Van Eyck memset(output, '!', hash_size);
139b0563631STom Van Eyck
140b0563631STom Van Eyck /* For each possible length, compute the hash up to that point */
141b0563631STom Van Eyck for (offset = min_data_len; offset <= max_data_len; offset++) {
142b0563631STom Van Eyck PSA_CHK(psa_hash_clone(&operation, &aux_operation));
143b0563631STom Van Eyck PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
144b0563631STom Van Eyck PSA_HASH_MAX_SIZE, &hash_length));
145b0563631STom Van Eyck /* Keep only the correct inner_hash in the output buffer */
146b0563631STom Van Eyck mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
147b0563631STom Van Eyck output, aux_out, NULL, hash_size);
148b0563631STom Van Eyck
149b0563631STom Van Eyck if (offset < max_data_len) {
150b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, data + offset, 1));
151b0563631STom Van Eyck }
152b0563631STom Van Eyck }
153b0563631STom Van Eyck
154b0563631STom Van Eyck /* Abort current operation to prepare for final operation */
155b0563631STom Van Eyck PSA_CHK(psa_hash_abort(&operation));
156b0563631STom Van Eyck
157b0563631STom Van Eyck /* Calculate okey */
158b0563631STom Van Eyck for (i = 0; i < mac_key_length; i++) {
159b0563631STom Van Eyck key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
160b0563631STom Van Eyck }
161b0563631STom Van Eyck for (; i < block_size; ++i) {
162b0563631STom Van Eyck key_buf[i] = 0x5C;
163b0563631STom Van Eyck }
164b0563631STom Van Eyck
165b0563631STom Van Eyck /* Now compute HASH(okey + inner_hash) */
166b0563631STom Van Eyck PSA_CHK(psa_hash_setup(&operation, hash_alg));
167b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
168b0563631STom Van Eyck PSA_CHK(psa_hash_update(&operation, output, hash_size));
169b0563631STom Van Eyck PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
170b0563631STom Van Eyck
171b0563631STom Van Eyck #undef PSA_CHK
172b0563631STom Van Eyck
173b0563631STom Van Eyck cleanup:
174b0563631STom Van Eyck mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
175b0563631STom Van Eyck mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
176b0563631STom Van Eyck
177b0563631STom Van Eyck psa_hash_abort(&operation);
178b0563631STom Van Eyck psa_hash_abort(&aux_operation);
179b0563631STom Van Eyck return PSA_TO_MBEDTLS_ERR(status);
180b0563631STom Van Eyck }
181b0563631STom Van Eyck
182b0563631STom Van Eyck #undef MAX_HASH_BLOCK_LENGTH
183b0563631STom Van Eyck
184b0563631STom Van Eyck #else
185b0563631STom Van Eyck MBEDTLS_STATIC_TESTABLE
mbedtls_ct_hmac(mbedtls_md_context_t * ctx,const unsigned char * add_data,size_t add_data_len,const unsigned char * data,size_t data_len_secret,size_t min_data_len,size_t max_data_len,unsigned char * output)186b0563631STom Van Eyck int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
187b0563631STom Van Eyck const unsigned char *add_data,
188b0563631STom Van Eyck size_t add_data_len,
189b0563631STom Van Eyck const unsigned char *data,
190b0563631STom Van Eyck size_t data_len_secret,
191b0563631STom Van Eyck size_t min_data_len,
192b0563631STom Van Eyck size_t max_data_len,
193b0563631STom Van Eyck unsigned char *output)
194b0563631STom Van Eyck {
195b0563631STom Van Eyck /*
196b0563631STom Van Eyck * This function breaks the HMAC abstraction and uses the md_clone()
197b0563631STom Van Eyck * extension to the MD API in order to get constant-flow behaviour.
198b0563631STom Van Eyck *
199b0563631STom Van Eyck * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
200b0563631STom Van Eyck * concatenation, and okey/ikey are the XOR of the key with some fixed bit
201b0563631STom Van Eyck * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
202b0563631STom Van Eyck *
203b0563631STom Van Eyck * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
204b0563631STom Van Eyck * minlen, then cloning the context, and for each byte up to maxlen
205b0563631STom Van Eyck * finishing up the hash computation, keeping only the correct result.
206b0563631STom Van Eyck *
207b0563631STom Van Eyck * Then we only need to compute HASH(okey + inner_hash) and we're done.
208b0563631STom Van Eyck */
209b0563631STom Van Eyck const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
210b0563631STom Van Eyck /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
211b0563631STom Van Eyck * all of which have the same block size except SHA-384. */
212b0563631STom Van Eyck const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
213b0563631STom Van Eyck const unsigned char * const ikey = ctx->hmac_ctx;
214b0563631STom Van Eyck const unsigned char * const okey = ikey + block_size;
215b0563631STom Van Eyck const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
216b0563631STom Van Eyck
217b0563631STom Van Eyck unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
218b0563631STom Van Eyck mbedtls_md_context_t aux;
219b0563631STom Van Eyck size_t offset;
220b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
221b0563631STom Van Eyck
222b0563631STom Van Eyck mbedtls_md_init(&aux);
223b0563631STom Van Eyck
224b0563631STom Van Eyck #define MD_CHK(func_call) \
225b0563631STom Van Eyck do { \
226b0563631STom Van Eyck ret = (func_call); \
227b0563631STom Van Eyck if (ret != 0) \
228b0563631STom Van Eyck goto cleanup; \
229b0563631STom Van Eyck } while (0)
230b0563631STom Van Eyck
231b0563631STom Van Eyck MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
232b0563631STom Van Eyck
233b0563631STom Van Eyck /* After hmac_start() of hmac_reset(), ikey has already been hashed,
234b0563631STom Van Eyck * so we can start directly with the message */
235b0563631STom Van Eyck MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
236b0563631STom Van Eyck MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
237b0563631STom Van Eyck
238b0563631STom Van Eyck /* Fill the hash buffer in advance with something that is
239b0563631STom Van Eyck * not a valid hash (barring an attack on the hash and
240b0563631STom Van Eyck * deliberately-crafted input), in case the caller doesn't
241b0563631STom Van Eyck * check the return status properly. */
242b0563631STom Van Eyck memset(output, '!', hash_size);
243b0563631STom Van Eyck
244b0563631STom Van Eyck /* For each possible length, compute the hash up to that point */
245b0563631STom Van Eyck for (offset = min_data_len; offset <= max_data_len; offset++) {
246b0563631STom Van Eyck MD_CHK(mbedtls_md_clone(&aux, ctx));
247b0563631STom Van Eyck MD_CHK(mbedtls_md_finish(&aux, aux_out));
248b0563631STom Van Eyck /* Keep only the correct inner_hash in the output buffer */
249b0563631STom Van Eyck mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offset, data_len_secret),
250b0563631STom Van Eyck output, aux_out, NULL, hash_size);
251b0563631STom Van Eyck
252b0563631STom Van Eyck if (offset < max_data_len) {
253b0563631STom Van Eyck MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
254b0563631STom Van Eyck }
255b0563631STom Van Eyck }
256b0563631STom Van Eyck
257b0563631STom Van Eyck /* The context needs to finish() before it starts() again */
258b0563631STom Van Eyck MD_CHK(mbedtls_md_finish(ctx, aux_out));
259b0563631STom Van Eyck
260b0563631STom Van Eyck /* Now compute HASH(okey + inner_hash) */
261b0563631STom Van Eyck MD_CHK(mbedtls_md_starts(ctx));
262b0563631STom Van Eyck MD_CHK(mbedtls_md_update(ctx, okey, block_size));
263b0563631STom Van Eyck MD_CHK(mbedtls_md_update(ctx, output, hash_size));
264b0563631STom Van Eyck MD_CHK(mbedtls_md_finish(ctx, output));
265b0563631STom Van Eyck
266b0563631STom Van Eyck /* Done, get ready for next time */
267b0563631STom Van Eyck MD_CHK(mbedtls_md_hmac_reset(ctx));
268b0563631STom Van Eyck
269b0563631STom Van Eyck #undef MD_CHK
270b0563631STom Van Eyck
271b0563631STom Van Eyck cleanup:
272b0563631STom Van Eyck mbedtls_md_free(&aux);
273b0563631STom Van Eyck return ret;
274b0563631STom Van Eyck }
275b0563631STom Van Eyck
276b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
277b0563631STom Van Eyck
278b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
279b0563631STom Van Eyck
28011fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl);
28111fa71b9SJerome Forissier
28211fa71b9SJerome Forissier /*
28311fa71b9SJerome Forissier * Start a timer.
28411fa71b9SJerome Forissier * Passing millisecs = 0 cancels a running timer.
28511fa71b9SJerome Forissier */
mbedtls_ssl_set_timer(mbedtls_ssl_context * ssl,uint32_t millisecs)28611fa71b9SJerome Forissier void mbedtls_ssl_set_timer(mbedtls_ssl_context *ssl, uint32_t millisecs)
28711fa71b9SJerome Forissier {
28832b31808SJens Wiklander if (ssl->f_set_timer == NULL) {
28911fa71b9SJerome Forissier return;
29032b31808SJens Wiklander }
29111fa71b9SJerome Forissier
29211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("set_timer to %d ms", (int) millisecs));
29311fa71b9SJerome Forissier ssl->f_set_timer(ssl->p_timer, millisecs / 4, millisecs);
29411fa71b9SJerome Forissier }
29511fa71b9SJerome Forissier
29611fa71b9SJerome Forissier /*
29711fa71b9SJerome Forissier * Return -1 is timer is expired, 0 if it isn't.
29811fa71b9SJerome Forissier */
mbedtls_ssl_check_timer(mbedtls_ssl_context * ssl)29911fa71b9SJerome Forissier int mbedtls_ssl_check_timer(mbedtls_ssl_context *ssl)
30011fa71b9SJerome Forissier {
30132b31808SJens Wiklander if (ssl->f_get_timer == NULL) {
30232b31808SJens Wiklander return 0;
30332b31808SJens Wiklander }
30411fa71b9SJerome Forissier
30532b31808SJens Wiklander if (ssl->f_get_timer(ssl->p_timer) == 2) {
30611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("timer expired"));
30732b31808SJens Wiklander return -1;
30811fa71b9SJerome Forissier }
30911fa71b9SJerome Forissier
31032b31808SJens Wiklander return 0;
31111fa71b9SJerome Forissier }
31211fa71b9SJerome Forissier
313039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
31411fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
31511fa71b9SJerome Forissier unsigned char *buf,
31611fa71b9SJerome Forissier size_t len,
31711fa71b9SJerome Forissier mbedtls_record *rec);
31811fa71b9SJerome Forissier
mbedtls_ssl_check_record(mbedtls_ssl_context const * ssl,unsigned char * buf,size_t buflen)31911fa71b9SJerome Forissier int mbedtls_ssl_check_record(mbedtls_ssl_context const *ssl,
32011fa71b9SJerome Forissier unsigned char *buf,
32111fa71b9SJerome Forissier size_t buflen)
32211fa71b9SJerome Forissier {
32311fa71b9SJerome Forissier int ret = 0;
32411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("=> mbedtls_ssl_check_record"));
32511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "record buffer", buf, buflen);
32611fa71b9SJerome Forissier
32711fa71b9SJerome Forissier /* We don't support record checking in TLS because
32832b31808SJens Wiklander * there doesn't seem to be a usecase for it.
32911fa71b9SJerome Forissier */
33032b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
33111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
33211fa71b9SJerome Forissier goto exit;
33311fa71b9SJerome Forissier }
33411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
33532b31808SJens Wiklander else {
33611fa71b9SJerome Forissier mbedtls_record rec;
33711fa71b9SJerome Forissier
33811fa71b9SJerome Forissier ret = ssl_parse_record_header(ssl, buf, buflen, &rec);
33932b31808SJens Wiklander if (ret != 0) {
34011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(3, "ssl_parse_record_header", ret);
34111fa71b9SJerome Forissier goto exit;
34211fa71b9SJerome Forissier }
34311fa71b9SJerome Forissier
34432b31808SJens Wiklander if (ssl->transform_in != NULL) {
34511fa71b9SJerome Forissier ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in, &rec);
34632b31808SJens Wiklander if (ret != 0) {
34711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(3, "mbedtls_ssl_decrypt_buf", ret);
34811fa71b9SJerome Forissier goto exit;
34911fa71b9SJerome Forissier }
35011fa71b9SJerome Forissier }
35111fa71b9SJerome Forissier }
35211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
35311fa71b9SJerome Forissier
35411fa71b9SJerome Forissier exit:
35511fa71b9SJerome Forissier /* On success, we have decrypted the buffer in-place, so make
35611fa71b9SJerome Forissier * sure we don't leak any plaintext data. */
35711fa71b9SJerome Forissier mbedtls_platform_zeroize(buf, buflen);
35811fa71b9SJerome Forissier
35911fa71b9SJerome Forissier /* For the purpose of this API, treat messages with unexpected CID
36011fa71b9SJerome Forissier * as well as such from future epochs as unexpected. */
36111fa71b9SJerome Forissier if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
36232b31808SJens Wiklander ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
36311fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
36411fa71b9SJerome Forissier }
36511fa71b9SJerome Forissier
36611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("<= mbedtls_ssl_check_record"));
36732b31808SJens Wiklander return ret;
36811fa71b9SJerome Forissier }
36911fa71b9SJerome Forissier
37011fa71b9SJerome Forissier #define SSL_DONT_FORCE_FLUSH 0
37111fa71b9SJerome Forissier #define SSL_FORCE_FLUSH 1
37211fa71b9SJerome Forissier
37311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
37411fa71b9SJerome Forissier
37511fa71b9SJerome Forissier /* Forward declarations for functions related to message buffering. */
37611fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
37711fa71b9SJerome Forissier uint8_t slot);
37811fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl);
379039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38011fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl);
381039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38211fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl);
383039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38411fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl);
385039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38611fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
38711fa71b9SJerome Forissier mbedtls_record const *rec);
388039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
38911fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl);
39011fa71b9SJerome Forissier
ssl_get_maximum_datagram_size(mbedtls_ssl_context const * ssl)39111fa71b9SJerome Forissier static size_t ssl_get_maximum_datagram_size(mbedtls_ssl_context const *ssl)
39211fa71b9SJerome Forissier {
39311fa71b9SJerome Forissier size_t mtu = mbedtls_ssl_get_current_mtu(ssl);
39411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
39511fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len;
39611fa71b9SJerome Forissier #else
39711fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
39811fa71b9SJerome Forissier #endif
39911fa71b9SJerome Forissier
40032b31808SJens Wiklander if (mtu != 0 && mtu < out_buf_len) {
40132b31808SJens Wiklander return mtu;
40232b31808SJens Wiklander }
40311fa71b9SJerome Forissier
40432b31808SJens Wiklander return out_buf_len;
40511fa71b9SJerome Forissier }
40611fa71b9SJerome Forissier
407039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const * ssl)40811fa71b9SJerome Forissier static int ssl_get_remaining_space_in_datagram(mbedtls_ssl_context const *ssl)
40911fa71b9SJerome Forissier {
41011fa71b9SJerome Forissier size_t const bytes_written = ssl->out_left;
41111fa71b9SJerome Forissier size_t const mtu = ssl_get_maximum_datagram_size(ssl);
41211fa71b9SJerome Forissier
41311fa71b9SJerome Forissier /* Double-check that the write-index hasn't gone
41411fa71b9SJerome Forissier * past what we can transmit in a single datagram. */
41532b31808SJens Wiklander if (bytes_written > mtu) {
41611fa71b9SJerome Forissier /* Should never happen... */
41732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
41811fa71b9SJerome Forissier }
41911fa71b9SJerome Forissier
42032b31808SJens Wiklander return (int) (mtu - bytes_written);
42111fa71b9SJerome Forissier }
42211fa71b9SJerome Forissier
423039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const * ssl)42411fa71b9SJerome Forissier static int ssl_get_remaining_payload_in_datagram(mbedtls_ssl_context const *ssl)
42511fa71b9SJerome Forissier {
42611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
42711fa71b9SJerome Forissier size_t remaining, expansion;
42811fa71b9SJerome Forissier size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
42911fa71b9SJerome Forissier
43011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
43111fa71b9SJerome Forissier const size_t mfl = mbedtls_ssl_get_output_max_frag_len(ssl);
43211fa71b9SJerome Forissier
43332b31808SJens Wiklander if (max_len > mfl) {
43411fa71b9SJerome Forissier max_len = mfl;
43532b31808SJens Wiklander }
43611fa71b9SJerome Forissier
43711fa71b9SJerome Forissier /* By the standard (RFC 6066 Sect. 4), the MFL extension
43811fa71b9SJerome Forissier * only limits the maximum record payload size, so in theory
43911fa71b9SJerome Forissier * we would be allowed to pack multiple records of payload size
44011fa71b9SJerome Forissier * MFL into a single datagram. However, this would mean that there's
44111fa71b9SJerome Forissier * no way to explicitly communicate MTU restrictions to the peer.
44211fa71b9SJerome Forissier *
44311fa71b9SJerome Forissier * The following reduction of max_len makes sure that we never
44411fa71b9SJerome Forissier * write datagrams larger than MFL + Record Expansion Overhead.
44511fa71b9SJerome Forissier */
44632b31808SJens Wiklander if (max_len <= ssl->out_left) {
44732b31808SJens Wiklander return 0;
44832b31808SJens Wiklander }
44911fa71b9SJerome Forissier
45011fa71b9SJerome Forissier max_len -= ssl->out_left;
45111fa71b9SJerome Forissier #endif
45211fa71b9SJerome Forissier
45311fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram(ssl);
45432b31808SJens Wiklander if (ret < 0) {
45532b31808SJens Wiklander return ret;
45632b31808SJens Wiklander }
45711fa71b9SJerome Forissier remaining = (size_t) ret;
45811fa71b9SJerome Forissier
45911fa71b9SJerome Forissier ret = mbedtls_ssl_get_record_expansion(ssl);
46032b31808SJens Wiklander if (ret < 0) {
46132b31808SJens Wiklander return ret;
46232b31808SJens Wiklander }
46311fa71b9SJerome Forissier expansion = (size_t) ret;
46411fa71b9SJerome Forissier
46532b31808SJens Wiklander if (remaining <= expansion) {
46632b31808SJens Wiklander return 0;
46732b31808SJens Wiklander }
46811fa71b9SJerome Forissier
46911fa71b9SJerome Forissier remaining -= expansion;
47032b31808SJens Wiklander if (remaining >= max_len) {
47111fa71b9SJerome Forissier remaining = max_len;
47232b31808SJens Wiklander }
47311fa71b9SJerome Forissier
47432b31808SJens Wiklander return (int) remaining;
47511fa71b9SJerome Forissier }
47611fa71b9SJerome Forissier
47711fa71b9SJerome Forissier /*
47811fa71b9SJerome Forissier * Double the retransmit timeout value, within the allowed range,
47911fa71b9SJerome Forissier * returning -1 if the maximum value has already been reached.
48011fa71b9SJerome Forissier */
481039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_double_retransmit_timeout(mbedtls_ssl_context * ssl)48211fa71b9SJerome Forissier static int ssl_double_retransmit_timeout(mbedtls_ssl_context *ssl)
48311fa71b9SJerome Forissier {
48411fa71b9SJerome Forissier uint32_t new_timeout;
48511fa71b9SJerome Forissier
48632b31808SJens Wiklander if (ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max) {
48732b31808SJens Wiklander return -1;
48832b31808SJens Wiklander }
48911fa71b9SJerome Forissier
49011fa71b9SJerome Forissier /* Implement the final paragraph of RFC 6347 section 4.1.1.1
49111fa71b9SJerome Forissier * in the following way: after the initial transmission and a first
49211fa71b9SJerome Forissier * retransmission, back off to a temporary estimated MTU of 508 bytes.
49311fa71b9SJerome Forissier * This value is guaranteed to be deliverable (if not guaranteed to be
49411fa71b9SJerome Forissier * delivered) of any compliant IPv4 (and IPv6) network, and should work
49511fa71b9SJerome Forissier * on most non-IP stacks too. */
49632b31808SJens Wiklander if (ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min) {
49711fa71b9SJerome Forissier ssl->handshake->mtu = 508;
49811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("mtu autoreduction to %d bytes", ssl->handshake->mtu));
49911fa71b9SJerome Forissier }
50011fa71b9SJerome Forissier
50111fa71b9SJerome Forissier new_timeout = 2 * ssl->handshake->retransmit_timeout;
50211fa71b9SJerome Forissier
50311fa71b9SJerome Forissier /* Avoid arithmetic overflow and range overflow */
50411fa71b9SJerome Forissier if (new_timeout < ssl->handshake->retransmit_timeout ||
50532b31808SJens Wiklander new_timeout > ssl->conf->hs_timeout_max) {
50611fa71b9SJerome Forissier new_timeout = ssl->conf->hs_timeout_max;
50711fa71b9SJerome Forissier }
50811fa71b9SJerome Forissier
50911fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = new_timeout;
5107901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
5117901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout));
51211fa71b9SJerome Forissier
51332b31808SJens Wiklander return 0;
51411fa71b9SJerome Forissier }
51511fa71b9SJerome Forissier
ssl_reset_retransmit_timeout(mbedtls_ssl_context * ssl)51611fa71b9SJerome Forissier static void ssl_reset_retransmit_timeout(mbedtls_ssl_context *ssl)
51711fa71b9SJerome Forissier {
51811fa71b9SJerome Forissier ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
5197901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("update timeout value to %lu millisecs",
5207901324dSJerome Forissier (unsigned long) ssl->handshake->retransmit_timeout));
52111fa71b9SJerome Forissier }
52211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
52311fa71b9SJerome Forissier
52411fa71b9SJerome Forissier /*
52511fa71b9SJerome Forissier * Encryption/decryption functions
52611fa71b9SJerome Forissier */
52711fa71b9SJerome Forissier
52832b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
5297901324dSJerome Forissier
ssl_compute_padding_length(size_t len,size_t granularity)5307901324dSJerome Forissier static size_t ssl_compute_padding_length(size_t len,
5317901324dSJerome Forissier size_t granularity)
5327901324dSJerome Forissier {
53332b31808SJens Wiklander return (granularity - (len + 1) % granularity) % granularity;
5347901324dSJerome Forissier }
5357901324dSJerome Forissier
5367901324dSJerome Forissier /* This functions transforms a (D)TLS plaintext fragment and a record content
5377901324dSJerome Forissier * type into an instance of the (D)TLSInnerPlaintext structure. This is used
5387901324dSJerome Forissier * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
5397901324dSJerome Forissier * a record's content type.
54011fa71b9SJerome Forissier *
54111fa71b9SJerome Forissier * struct {
54211fa71b9SJerome Forissier * opaque content[DTLSPlaintext.length];
54311fa71b9SJerome Forissier * ContentType real_type;
54411fa71b9SJerome Forissier * uint8 zeros[length_of_padding];
5457901324dSJerome Forissier * } (D)TLSInnerPlaintext;
54611fa71b9SJerome Forissier *
54711fa71b9SJerome Forissier * Input:
54811fa71b9SJerome Forissier * - `content`: The beginning of the buffer holding the
54911fa71b9SJerome Forissier * plaintext to be wrapped.
55011fa71b9SJerome Forissier * - `*content_size`: The length of the plaintext in Bytes.
55111fa71b9SJerome Forissier * - `max_len`: The number of Bytes available starting from
55211fa71b9SJerome Forissier * `content`. This must be `>= *content_size`.
55311fa71b9SJerome Forissier * - `rec_type`: The desired record content type.
55411fa71b9SJerome Forissier *
55511fa71b9SJerome Forissier * Output:
5567901324dSJerome Forissier * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
5577901324dSJerome Forissier * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
55811fa71b9SJerome Forissier *
55911fa71b9SJerome Forissier * Returns:
56011fa71b9SJerome Forissier * - `0` on success.
56111fa71b9SJerome Forissier * - A negative error code if `max_len` didn't offer enough space
56211fa71b9SJerome Forissier * for the expansion.
56311fa71b9SJerome Forissier */
564039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_build_inner_plaintext(unsigned char * content,size_t * content_size,size_t remaining,uint8_t rec_type,size_t pad)5657901324dSJerome Forissier static int ssl_build_inner_plaintext(unsigned char *content,
56611fa71b9SJerome Forissier size_t *content_size,
56711fa71b9SJerome Forissier size_t remaining,
5687901324dSJerome Forissier uint8_t rec_type,
5697901324dSJerome Forissier size_t pad)
57011fa71b9SJerome Forissier {
57111fa71b9SJerome Forissier size_t len = *content_size;
57211fa71b9SJerome Forissier
57311fa71b9SJerome Forissier /* Write real content type */
57432b31808SJens Wiklander if (remaining == 0) {
57532b31808SJens Wiklander return -1;
57632b31808SJens Wiklander }
57711fa71b9SJerome Forissier content[len] = rec_type;
57811fa71b9SJerome Forissier len++;
57911fa71b9SJerome Forissier remaining--;
58011fa71b9SJerome Forissier
58132b31808SJens Wiklander if (remaining < pad) {
58232b31808SJens Wiklander return -1;
58332b31808SJens Wiklander }
58411fa71b9SJerome Forissier memset(content + len, 0, pad);
58511fa71b9SJerome Forissier len += pad;
58611fa71b9SJerome Forissier remaining -= pad;
58711fa71b9SJerome Forissier
58811fa71b9SJerome Forissier *content_size = len;
58932b31808SJens Wiklander return 0;
59011fa71b9SJerome Forissier }
59111fa71b9SJerome Forissier
5927901324dSJerome Forissier /* This function parses a (D)TLSInnerPlaintext structure.
5937901324dSJerome Forissier * See ssl_build_inner_plaintext() for details. */
594039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_inner_plaintext(unsigned char const * content,size_t * content_size,uint8_t * rec_type)5957901324dSJerome Forissier static int ssl_parse_inner_plaintext(unsigned char const *content,
59611fa71b9SJerome Forissier size_t *content_size,
59711fa71b9SJerome Forissier uint8_t *rec_type)
59811fa71b9SJerome Forissier {
59911fa71b9SJerome Forissier size_t remaining = *content_size;
60011fa71b9SJerome Forissier
60111fa71b9SJerome Forissier /* Determine length of padding by skipping zeroes from the back. */
60232b31808SJens Wiklander do {
60332b31808SJens Wiklander if (remaining == 0) {
60432b31808SJens Wiklander return -1;
60532b31808SJens Wiklander }
60611fa71b9SJerome Forissier remaining--;
60711fa71b9SJerome Forissier } while (content[remaining] == 0);
60811fa71b9SJerome Forissier
60911fa71b9SJerome Forissier *content_size = remaining;
61011fa71b9SJerome Forissier *rec_type = content[remaining];
61111fa71b9SJerome Forissier
61232b31808SJens Wiklander return 0;
61311fa71b9SJerome Forissier }
61432b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID || MBEDTLS_SSL_PROTO_TLS1_3 */
61511fa71b9SJerome Forissier
61632b31808SJens Wiklander /* The size of the `add_data` structure depends on various
61732b31808SJens Wiklander * factors, namely
61832b31808SJens Wiklander *
61932b31808SJens Wiklander * 1) CID functionality disabled
62032b31808SJens Wiklander *
62132b31808SJens Wiklander * additional_data =
62232b31808SJens Wiklander * 8: seq_num +
62332b31808SJens Wiklander * 1: type +
62432b31808SJens Wiklander * 2: version +
62532b31808SJens Wiklander * 2: length of inner plaintext +
62632b31808SJens Wiklander *
62732b31808SJens Wiklander * size = 13 bytes
62832b31808SJens Wiklander *
62932b31808SJens Wiklander * 2) CID functionality based on RFC 9146 enabled
63032b31808SJens Wiklander *
63132b31808SJens Wiklander * size = 8 + 1 + 1 + 1 + 2 + 2 + 6 + 2 + CID-length
63232b31808SJens Wiklander * = 23 + CID-length
63332b31808SJens Wiklander *
63432b31808SJens Wiklander * 3) CID functionality based on legacy CID version
63532b31808SJens Wiklander according to draft-ietf-tls-dtls-connection-id-05
63632b31808SJens Wiklander * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
63732b31808SJens Wiklander *
63832b31808SJens Wiklander * size = 13 + 1 + CID-length
63932b31808SJens Wiklander *
64032b31808SJens Wiklander * More information about the CID usage:
64132b31808SJens Wiklander *
64232b31808SJens Wiklander * Per Section 5.3 of draft-ietf-tls-dtls-connection-id-05 the
64332b31808SJens Wiklander * size of the additional data structure is calculated as:
64432b31808SJens Wiklander *
64532b31808SJens Wiklander * additional_data =
64632b31808SJens Wiklander * 8: seq_num +
64732b31808SJens Wiklander * 1: tls12_cid +
64832b31808SJens Wiklander * 2: DTLSCipherText.version +
64932b31808SJens Wiklander * n: cid +
65032b31808SJens Wiklander * 1: cid_length +
65132b31808SJens Wiklander * 2: length_of_DTLSInnerPlaintext
65232b31808SJens Wiklander *
65332b31808SJens Wiklander * Per RFC 9146 the size of the add_data structure is calculated as:
65432b31808SJens Wiklander *
65532b31808SJens Wiklander * additional_data =
65632b31808SJens Wiklander * 8: seq_num_placeholder +
65732b31808SJens Wiklander * 1: tls12_cid +
65832b31808SJens Wiklander * 1: cid_length +
65932b31808SJens Wiklander * 1: tls12_cid +
66032b31808SJens Wiklander * 2: DTLSCiphertext.version +
66132b31808SJens Wiklander * 2: epoch +
66232b31808SJens Wiklander * 6: sequence_number +
66332b31808SJens Wiklander * n: cid +
66432b31808SJens Wiklander * 2: length_of_DTLSInnerPlaintext
66532b31808SJens Wiklander *
66632b31808SJens Wiklander */
ssl_extract_add_data_from_record(unsigned char * add_data,size_t * add_data_len,mbedtls_record * rec,mbedtls_ssl_protocol_version tls_version,size_t taglen)66711fa71b9SJerome Forissier static void ssl_extract_add_data_from_record(unsigned char *add_data,
66811fa71b9SJerome Forissier size_t *add_data_len,
6697901324dSJerome Forissier mbedtls_record *rec,
67032b31808SJens Wiklander mbedtls_ssl_protocol_version
67132b31808SJens Wiklander tls_version,
67232b31808SJens Wiklander size_t taglen)
67311fa71b9SJerome Forissier {
67432b31808SJens Wiklander /* Several types of ciphers have been defined for use with TLS and DTLS,
67532b31808SJens Wiklander * and the MAC calculations for those ciphers differ slightly. Further
67632b31808SJens Wiklander * variants were added when the CID functionality was added with RFC 9146.
67732b31808SJens Wiklander * This implementations also considers the use of a legacy version of the
67832b31808SJens Wiklander * CID specification published in draft-ietf-tls-dtls-connection-id-05,
67932b31808SJens Wiklander * which is used in deployments.
68032b31808SJens Wiklander *
68132b31808SJens Wiklander * We will distinguish between the non-CID and the CID cases below.
68232b31808SJens Wiklander *
68332b31808SJens Wiklander * --- Non-CID cases ---
68432b31808SJens Wiklander *
68532b31808SJens Wiklander * Quoting RFC 5246 (TLS 1.2):
68611fa71b9SJerome Forissier *
68711fa71b9SJerome Forissier * additional_data = seq_num + TLSCompressed.type +
68811fa71b9SJerome Forissier * TLSCompressed.version + TLSCompressed.length;
68911fa71b9SJerome Forissier *
6907901324dSJerome Forissier * For TLS 1.3, the record sequence number is dropped from the AAD
6917901324dSJerome Forissier * and encoded within the nonce of the AEAD operation instead.
69232b31808SJens Wiklander * Moreover, the additional data involves the length of the TLS
69332b31808SJens Wiklander * ciphertext, not the TLS plaintext as in earlier versions.
69432b31808SJens Wiklander * Quoting RFC 8446 (TLS 1.3):
69532b31808SJens Wiklander *
69632b31808SJens Wiklander * additional_data = TLSCiphertext.opaque_type ||
69732b31808SJens Wiklander * TLSCiphertext.legacy_record_version ||
69832b31808SJens Wiklander * TLSCiphertext.length
69932b31808SJens Wiklander *
70032b31808SJens Wiklander * We pass the tag length to this function in order to compute the
70132b31808SJens Wiklander * ciphertext length from the inner plaintext length rec->data_len via
70232b31808SJens Wiklander *
70332b31808SJens Wiklander * TLSCiphertext.length = TLSInnerPlaintext.length + taglen.
70432b31808SJens Wiklander *
70532b31808SJens Wiklander * --- CID cases ---
70632b31808SJens Wiklander *
70732b31808SJens Wiklander * RFC 9146 uses a common pattern when constructing the data
70832b31808SJens Wiklander * passed into a MAC / AEAD cipher.
70932b31808SJens Wiklander *
71032b31808SJens Wiklander * Data concatenation for MACs used with block ciphers with
71132b31808SJens Wiklander * Encrypt-then-MAC Processing (with CID):
71232b31808SJens Wiklander *
71332b31808SJens Wiklander * data = seq_num_placeholder +
71432b31808SJens Wiklander * tls12_cid +
71532b31808SJens Wiklander * cid_length +
71632b31808SJens Wiklander * tls12_cid +
71732b31808SJens Wiklander * DTLSCiphertext.version +
71832b31808SJens Wiklander * epoch +
71932b31808SJens Wiklander * sequence_number +
72032b31808SJens Wiklander * cid +
72132b31808SJens Wiklander * DTLSCiphertext.length +
72232b31808SJens Wiklander * IV +
72332b31808SJens Wiklander * ENC(content + padding + padding_length)
72432b31808SJens Wiklander *
72532b31808SJens Wiklander * Data concatenation for MACs used with block ciphers (with CID):
72632b31808SJens Wiklander *
72732b31808SJens Wiklander * data = seq_num_placeholder +
72832b31808SJens Wiklander * tls12_cid +
72932b31808SJens Wiklander * cid_length +
73032b31808SJens Wiklander * tls12_cid +
73132b31808SJens Wiklander * DTLSCiphertext.version +
73232b31808SJens Wiklander * epoch +
73332b31808SJens Wiklander * sequence_number +
73432b31808SJens Wiklander * cid +
73532b31808SJens Wiklander * length_of_DTLSInnerPlaintext +
73632b31808SJens Wiklander * DTLSInnerPlaintext.content +
73732b31808SJens Wiklander * DTLSInnerPlaintext.real_type +
73832b31808SJens Wiklander * DTLSInnerPlaintext.zeros
73932b31808SJens Wiklander *
74032b31808SJens Wiklander * AEAD ciphers use the following additional data calculation (with CIDs):
74132b31808SJens Wiklander *
74232b31808SJens Wiklander * additional_data = seq_num_placeholder +
74332b31808SJens Wiklander * tls12_cid +
74432b31808SJens Wiklander * cid_length +
74532b31808SJens Wiklander * tls12_cid +
74632b31808SJens Wiklander * DTLSCiphertext.version +
74732b31808SJens Wiklander * epoch +
74832b31808SJens Wiklander * sequence_number +
74932b31808SJens Wiklander * cid +
75032b31808SJens Wiklander * length_of_DTLSInnerPlaintext
75132b31808SJens Wiklander *
75232b31808SJens Wiklander * Section 5.3 of draft-ietf-tls-dtls-connection-id-05 (for legacy CID use)
75332b31808SJens Wiklander * defines the additional data calculation as follows:
75432b31808SJens Wiklander *
75532b31808SJens Wiklander * additional_data = seq_num +
75632b31808SJens Wiklander * tls12_cid +
75732b31808SJens Wiklander * DTLSCipherText.version +
75832b31808SJens Wiklander * cid +
75932b31808SJens Wiklander * cid_length +
76032b31808SJens Wiklander * length_of_DTLSInnerPlaintext
76111fa71b9SJerome Forissier */
76211fa71b9SJerome Forissier
7637901324dSJerome Forissier unsigned char *cur = add_data;
76432b31808SJens Wiklander size_t ad_len_field = rec->data_len;
7657901324dSJerome Forissier
76632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
76732b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
76832b31808SJens Wiklander const unsigned char seq_num_placeholder[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
76932b31808SJens Wiklander #endif
77032b31808SJens Wiklander
77132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
77232b31808SJens Wiklander if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
77332b31808SJens Wiklander /* In TLS 1.3, the AAD contains the length of the TLSCiphertext,
77432b31808SJens Wiklander * which differs from the length of the TLSInnerPlaintext
77532b31808SJens Wiklander * by the length of the authentication tag. */
77632b31808SJens Wiklander ad_len_field += taglen;
77732b31808SJens Wiklander } else
77832b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
7797901324dSJerome Forissier {
78032b31808SJens Wiklander ((void) tls_version);
78132b31808SJens Wiklander ((void) taglen);
7827901324dSJerome Forissier
78332b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
78432b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
78532b31808SJens Wiklander if (rec->cid_len != 0) {
78632b31808SJens Wiklander // seq_num_placeholder
78732b31808SJens Wiklander memcpy(cur, seq_num_placeholder, sizeof(seq_num_placeholder));
78832b31808SJens Wiklander cur += sizeof(seq_num_placeholder);
78932b31808SJens Wiklander
79032b31808SJens Wiklander // tls12_cid type
7917901324dSJerome Forissier *cur = rec->type;
7927901324dSJerome Forissier cur++;
7937901324dSJerome Forissier
79432b31808SJens Wiklander // cid_length
79532b31808SJens Wiklander *cur = rec->cid_len;
79632b31808SJens Wiklander cur++;
79732b31808SJens Wiklander } else
79832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
79932b31808SJens Wiklander {
80032b31808SJens Wiklander // epoch + sequence number
80132b31808SJens Wiklander memcpy(cur, rec->ctr, sizeof(rec->ctr));
80232b31808SJens Wiklander cur += sizeof(rec->ctr);
80332b31808SJens Wiklander }
80432b31808SJens Wiklander }
80532b31808SJens Wiklander
80632b31808SJens Wiklander // type
80732b31808SJens Wiklander *cur = rec->type;
80832b31808SJens Wiklander cur++;
80932b31808SJens Wiklander
81032b31808SJens Wiklander // version
8117901324dSJerome Forissier memcpy(cur, rec->ver, sizeof(rec->ver));
8127901324dSJerome Forissier cur += sizeof(rec->ver);
81311fa71b9SJerome Forissier
81432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
81532b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 1
81632b31808SJens Wiklander
81732b31808SJens Wiklander if (rec->cid_len != 0) {
81832b31808SJens Wiklander // CID
8197901324dSJerome Forissier memcpy(cur, rec->cid, rec->cid_len);
8207901324dSJerome Forissier cur += rec->cid_len;
8217901324dSJerome Forissier
82232b31808SJens Wiklander // cid_length
8237901324dSJerome Forissier *cur = rec->cid_len;
8247901324dSJerome Forissier cur++;
8257901324dSJerome Forissier
82632b31808SJens Wiklander // length of inner plaintext
82732b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
8287901324dSJerome Forissier cur += 2;
82932b31808SJens Wiklander } else
83032b31808SJens Wiklander #elif defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
83132b31808SJens Wiklander MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT == 0
83232b31808SJens Wiklander
83332b31808SJens Wiklander if (rec->cid_len != 0) {
83432b31808SJens Wiklander // epoch + sequence number
83532b31808SJens Wiklander memcpy(cur, rec->ctr, sizeof(rec->ctr));
83632b31808SJens Wiklander cur += sizeof(rec->ctr);
83732b31808SJens Wiklander
83832b31808SJens Wiklander // CID
83932b31808SJens Wiklander memcpy(cur, rec->cid, rec->cid_len);
84032b31808SJens Wiklander cur += rec->cid_len;
84132b31808SJens Wiklander
84232b31808SJens Wiklander // length of inner plaintext
84332b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
84432b31808SJens Wiklander cur += 2;
84532b31808SJens Wiklander } else
84611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
84711fa71b9SJerome Forissier {
84832b31808SJens Wiklander MBEDTLS_PUT_UINT16_BE(ad_len_field, cur, 0);
8497901324dSJerome Forissier cur += 2;
85011fa71b9SJerome Forissier }
8517901324dSJerome Forissier
852b0563631STom Van Eyck *add_data_len = (size_t) (cur - add_data);
85311fa71b9SJerome Forissier }
85411fa71b9SJerome Forissier
855b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
856039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_transform_aead_dynamic_iv_is_explicit(mbedtls_ssl_transform const * transform)8577901324dSJerome Forissier static int ssl_transform_aead_dynamic_iv_is_explicit(
8587901324dSJerome Forissier mbedtls_ssl_transform const *transform)
8597901324dSJerome Forissier {
86032b31808SJens Wiklander return transform->ivlen != transform->fixed_ivlen;
8617901324dSJerome Forissier }
8627901324dSJerome Forissier
8637901324dSJerome Forissier /* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
8647901324dSJerome Forissier *
8657901324dSJerome Forissier * Concretely, this occurs in two variants:
8667901324dSJerome Forissier *
8677901324dSJerome Forissier * a) Fixed and dynamic IV lengths add up to total IV length, giving
8687901324dSJerome Forissier * IV = fixed_iv || dynamic_iv
8697901324dSJerome Forissier *
8707901324dSJerome Forissier * This variant is used in TLS 1.2 when used with GCM or CCM.
8717901324dSJerome Forissier *
8727901324dSJerome Forissier * b) Fixed IV lengths matches total IV length, giving
8737901324dSJerome Forissier * IV = fixed_iv XOR ( 0 || dynamic_iv )
8747901324dSJerome Forissier *
8757901324dSJerome Forissier * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
8767901324dSJerome Forissier *
8777901324dSJerome Forissier * See also the documentation of mbedtls_ssl_transform.
8787901324dSJerome Forissier *
8797901324dSJerome Forissier * This function has the precondition that
8807901324dSJerome Forissier *
8817901324dSJerome Forissier * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
8827901324dSJerome Forissier *
8837901324dSJerome Forissier * which has to be ensured by the caller. If this precondition
8847901324dSJerome Forissier * violated, the behavior of this function is undefined.
8857901324dSJerome Forissier */
ssl_build_record_nonce(unsigned char * dst_iv,size_t dst_iv_len,unsigned char const * fixed_iv,size_t fixed_iv_len,unsigned char const * dynamic_iv,size_t dynamic_iv_len)8867901324dSJerome Forissier static void ssl_build_record_nonce(unsigned char *dst_iv,
8877901324dSJerome Forissier size_t dst_iv_len,
8887901324dSJerome Forissier unsigned char const *fixed_iv,
8897901324dSJerome Forissier size_t fixed_iv_len,
8907901324dSJerome Forissier unsigned char const *dynamic_iv,
8917901324dSJerome Forissier size_t dynamic_iv_len)
8927901324dSJerome Forissier {
8937901324dSJerome Forissier /* Start with Fixed IV || 0 */
8947901324dSJerome Forissier memset(dst_iv, 0, dst_iv_len);
8957901324dSJerome Forissier memcpy(dst_iv, fixed_iv, fixed_iv_len);
8967901324dSJerome Forissier
8977901324dSJerome Forissier dst_iv += dst_iv_len - dynamic_iv_len;
89832b31808SJens Wiklander mbedtls_xor(dst_iv, dst_iv, dynamic_iv, dynamic_iv_len);
8997901324dSJerome Forissier }
900b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
9017901324dSJerome Forissier
mbedtls_ssl_encrypt_buf(mbedtls_ssl_context * ssl,mbedtls_ssl_transform * transform,mbedtls_record * rec,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)90211fa71b9SJerome Forissier int mbedtls_ssl_encrypt_buf(mbedtls_ssl_context *ssl,
90311fa71b9SJerome Forissier mbedtls_ssl_transform *transform,
90411fa71b9SJerome Forissier mbedtls_record *rec,
90511fa71b9SJerome Forissier int (*f_rng)(void *, unsigned char *, size_t),
90611fa71b9SJerome Forissier void *p_rng)
90711fa71b9SJerome Forissier {
90832b31808SJens Wiklander mbedtls_ssl_mode_t ssl_mode;
90911fa71b9SJerome Forissier int auth_done = 0;
91011fa71b9SJerome Forissier unsigned char *data;
91132b31808SJens Wiklander /* For an explanation of the additional data length see
91232b31808SJens Wiklander * the description of ssl_extract_add_data_from_record().
91332b31808SJens Wiklander */
91432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
91532b31808SJens Wiklander unsigned char add_data[23 + MBEDTLS_SSL_CID_OUT_LEN_MAX];
91632b31808SJens Wiklander #else
91732b31808SJens Wiklander unsigned char add_data[13];
91832b31808SJens Wiklander #endif
91911fa71b9SJerome Forissier size_t add_data_len;
92011fa71b9SJerome Forissier size_t post_avail;
92111fa71b9SJerome Forissier
92211fa71b9SJerome Forissier /* The SSL context is only used for debugging purposes! */
92311fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
92411fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */
92511fa71b9SJerome Forissier ((void) ssl);
92611fa71b9SJerome Forissier #endif
92711fa71b9SJerome Forissier
92811fa71b9SJerome Forissier /* The PRNG is used for dynamic IV generation that's used
92932b31808SJens Wiklander * for CBC transformations in TLS 1.2. */
9307901324dSJerome Forissier #if !(defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
93132b31808SJens Wiklander defined(MBEDTLS_SSL_PROTO_TLS1_2))
93211fa71b9SJerome Forissier ((void) f_rng);
93311fa71b9SJerome Forissier ((void) p_rng);
93411fa71b9SJerome Forissier #endif
93511fa71b9SJerome Forissier
93611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> encrypt buf"));
93711fa71b9SJerome Forissier
93832b31808SJens Wiklander if (transform == NULL) {
93911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("no transform provided to encrypt_buf"));
94032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
94111fa71b9SJerome Forissier }
94211fa71b9SJerome Forissier if (rec == NULL
94311fa71b9SJerome Forissier || rec->buf == NULL
94411fa71b9SJerome Forissier || rec->buf_len < rec->data_offset
94511fa71b9SJerome Forissier || rec->buf_len - rec->data_offset < rec->data_len
94611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
94711fa71b9SJerome Forissier || rec->cid_len != 0
94811fa71b9SJerome Forissier #endif
94932b31808SJens Wiklander ) {
95011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to encrypt_buf"));
95132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
95211fa71b9SJerome Forissier }
95311fa71b9SJerome Forissier
95432b31808SJens Wiklander ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
95532b31808SJens Wiklander
95611fa71b9SJerome Forissier data = rec->buf + rec->data_offset;
95711fa71b9SJerome Forissier post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
95811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "before encrypt: output payload",
95911fa71b9SJerome Forissier data, rec->data_len);
96011fa71b9SJerome Forissier
96132b31808SJens Wiklander if (rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
9627901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Record content %" MBEDTLS_PRINTF_SIZET
9637901324dSJerome Forissier " too large, maximum %" MBEDTLS_PRINTF_SIZET,
9647901324dSJerome Forissier rec->data_len,
9657901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
96632b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
96711fa71b9SJerome Forissier }
96811fa71b9SJerome Forissier
9697901324dSJerome Forissier /* The following two code paths implement the (D)TLSInnerPlaintext
9707901324dSJerome Forissier * structure present in TLS 1.3 and DTLS 1.2 + CID.
9717901324dSJerome Forissier *
9727901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information.
9737901324dSJerome Forissier *
9747901324dSJerome Forissier * Note that this changes `rec->data_len`, and hence
9757901324dSJerome Forissier * `post_avail` needs to be recalculated afterwards.
9767901324dSJerome Forissier *
9777901324dSJerome Forissier * Note also that the two code paths cannot occur simultaneously
9787901324dSJerome Forissier * since they apply to different versions of the protocol. There
9797901324dSJerome Forissier * is hence no risk of double-addition of the inner plaintext.
9807901324dSJerome Forissier */
98132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
98232b31808SJens Wiklander if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
9837901324dSJerome Forissier size_t padding =
9847901324dSJerome Forissier ssl_compute_padding_length(rec->data_len,
98532b31808SJens Wiklander MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
9867901324dSJerome Forissier if (ssl_build_inner_plaintext(data,
9877901324dSJerome Forissier &rec->data_len,
9887901324dSJerome Forissier post_avail,
9897901324dSJerome Forissier rec->type,
99032b31808SJens Wiklander padding) != 0) {
99132b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
9927901324dSJerome Forissier }
9937901324dSJerome Forissier
9947901324dSJerome Forissier rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
9957901324dSJerome Forissier }
99632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
9977901324dSJerome Forissier
99811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
99911fa71b9SJerome Forissier /*
100011fa71b9SJerome Forissier * Add CID information
100111fa71b9SJerome Forissier */
100211fa71b9SJerome Forissier rec->cid_len = transform->out_cid_len;
100311fa71b9SJerome Forissier memcpy(rec->cid, transform->out_cid, transform->out_cid_len);
100411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "CID", rec->cid, rec->cid_len);
100511fa71b9SJerome Forissier
100632b31808SJens Wiklander if (rec->cid_len != 0) {
10077901324dSJerome Forissier size_t padding =
10087901324dSJerome Forissier ssl_compute_padding_length(rec->data_len,
100932b31808SJens Wiklander MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY);
101011fa71b9SJerome Forissier /*
101111fa71b9SJerome Forissier * Wrap plaintext into DTLSInnerPlaintext structure.
10127901324dSJerome Forissier * See ssl_build_inner_plaintext() for more information.
101311fa71b9SJerome Forissier *
101411fa71b9SJerome Forissier * Note that this changes `rec->data_len`, and hence
101511fa71b9SJerome Forissier * `post_avail` needs to be recalculated afterwards.
101611fa71b9SJerome Forissier */
10177901324dSJerome Forissier if (ssl_build_inner_plaintext(data,
101811fa71b9SJerome Forissier &rec->data_len,
101911fa71b9SJerome Forissier post_avail,
10207901324dSJerome Forissier rec->type,
102132b31808SJens Wiklander padding) != 0) {
102232b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
102311fa71b9SJerome Forissier }
102411fa71b9SJerome Forissier
102511fa71b9SJerome Forissier rec->type = MBEDTLS_SSL_MSG_CID;
102611fa71b9SJerome Forissier }
102711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
102811fa71b9SJerome Forissier
102911fa71b9SJerome Forissier post_avail = rec->buf_len - (rec->data_len + rec->data_offset);
103011fa71b9SJerome Forissier
103111fa71b9SJerome Forissier /*
103211fa71b9SJerome Forissier * Add MAC before if needed
103311fa71b9SJerome Forissier */
103432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
103532b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM ||
103632b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC) {
103732b31808SJens Wiklander if (post_avail < transform->maclen) {
103811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
103932b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
104011fa71b9SJerome Forissier }
104132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
104211fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD];
1043039e02dfSJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
104432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
104532b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
104632b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
104732b31808SJens Wiklander size_t sign_mac_length = 0;
104832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
104911fa71b9SJerome Forissier
10507901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
105132b31808SJens Wiklander transform->tls_version,
105232b31808SJens Wiklander transform->taglen);
105311fa71b9SJerome Forissier
105432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
105532b31808SJens Wiklander status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
105632b31808SJens Wiklander transform->psa_mac_alg);
105732b31808SJens Wiklander if (status != PSA_SUCCESS) {
1058039e02dfSJerome Forissier goto hmac_failed_etm_disabled;
105932b31808SJens Wiklander }
106032b31808SJens Wiklander
106132b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len);
106232b31808SJens Wiklander if (status != PSA_SUCCESS) {
1063039e02dfSJerome Forissier goto hmac_failed_etm_disabled;
106432b31808SJens Wiklander }
106532b31808SJens Wiklander
106632b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len);
106732b31808SJens Wiklander if (status != PSA_SUCCESS) {
106832b31808SJens Wiklander goto hmac_failed_etm_disabled;
106932b31808SJens Wiklander }
107032b31808SJens Wiklander
107132b31808SJens Wiklander status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
107232b31808SJens Wiklander &sign_mac_length);
107332b31808SJens Wiklander if (status != PSA_SUCCESS) {
107432b31808SJens Wiklander goto hmac_failed_etm_disabled;
107532b31808SJens Wiklander }
107632b31808SJens Wiklander #else
107732b31808SJens Wiklander ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
107832b31808SJens Wiklander add_data_len);
107932b31808SJens Wiklander if (ret != 0) {
108032b31808SJens Wiklander goto hmac_failed_etm_disabled;
108132b31808SJens Wiklander }
108232b31808SJens Wiklander ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, data, rec->data_len);
108332b31808SJens Wiklander if (ret != 0) {
108432b31808SJens Wiklander goto hmac_failed_etm_disabled;
108532b31808SJens Wiklander }
1086039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
108732b31808SJens Wiklander if (ret != 0) {
1088039e02dfSJerome Forissier goto hmac_failed_etm_disabled;
108932b31808SJens Wiklander }
1090039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
109132b31808SJens Wiklander if (ret != 0) {
1092039e02dfSJerome Forissier goto hmac_failed_etm_disabled;
109332b31808SJens Wiklander }
109432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
109511fa71b9SJerome Forissier
109611fa71b9SJerome Forissier memcpy(data + rec->data_len, mac, transform->maclen);
109711fa71b9SJerome Forissier #endif
109811fa71b9SJerome Forissier
109911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "computed mac", data + rec->data_len,
110011fa71b9SJerome Forissier transform->maclen);
110111fa71b9SJerome Forissier
110211fa71b9SJerome Forissier rec->data_len += transform->maclen;
110311fa71b9SJerome Forissier post_avail -= transform->maclen;
110411fa71b9SJerome Forissier auth_done++;
110532b31808SJens Wiklander
110632b31808SJens Wiklander hmac_failed_etm_disabled:
110732b31808SJens Wiklander mbedtls_platform_zeroize(mac, transform->maclen);
110832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
110932b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
111032b31808SJens Wiklander status = psa_mac_abort(&operation);
111132b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) {
111232b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
111311fa71b9SJerome Forissier }
111432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
111532b31808SJens Wiklander if (ret != 0) {
111632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_md_hmac_xxx", ret);
111732b31808SJens Wiklander return ret;
111832b31808SJens Wiklander }
111932b31808SJens Wiklander }
112032b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
112111fa71b9SJerome Forissier
112211fa71b9SJerome Forissier /*
112311fa71b9SJerome Forissier * Encrypt
112411fa71b9SJerome Forissier */
112532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
112632b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
11277901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
112811fa71b9SJerome Forissier "including %d bytes of padding",
112911fa71b9SJerome Forissier rec->data_len, 0));
113011fa71b9SJerome Forissier
113132b31808SJens Wiklander /* The only supported stream cipher is "NULL",
113232b31808SJens Wiklander * so there's nothing to do here.*/
113332b31808SJens Wiklander } else
113432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
113511fa71b9SJerome Forissier
1136b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
113732b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
113811fa71b9SJerome Forissier unsigned char iv[12];
11397901324dSJerome Forissier unsigned char *dynamic_iv;
11407901324dSJerome Forissier size_t dynamic_iv_len;
11417901324dSJerome Forissier int dynamic_iv_is_explicit =
11427901324dSJerome Forissier ssl_transform_aead_dynamic_iv_is_explicit(transform);
114332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
114432b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
114532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
114632b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
114711fa71b9SJerome Forissier
11487901324dSJerome Forissier /* Check that there's space for the authentication tag. */
114932b31808SJens Wiklander if (post_avail < transform->taglen) {
115011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
115132b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
115211fa71b9SJerome Forissier }
115311fa71b9SJerome Forissier
115411fa71b9SJerome Forissier /*
11557901324dSJerome Forissier * Build nonce for AEAD encryption.
11567901324dSJerome Forissier *
11577901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
11587901324dSJerome Forissier * part of the IV is prepended to the ciphertext and
11597901324dSJerome Forissier * can be chosen freely - in particular, it need not
11607901324dSJerome Forissier * agree with the record sequence number.
11617901324dSJerome Forissier * However, since ChaChaPoly as well as all AEAD modes
11627901324dSJerome Forissier * in TLS 1.3 use the record sequence number as the
11637901324dSJerome Forissier * dynamic part of the nonce, we uniformly use the
11647901324dSJerome Forissier * record sequence number here in all cases.
116511fa71b9SJerome Forissier */
11667901324dSJerome Forissier dynamic_iv = rec->ctr;
11677901324dSJerome Forissier dynamic_iv_len = sizeof(rec->ctr);
116811fa71b9SJerome Forissier
11697901324dSJerome Forissier ssl_build_record_nonce(iv, sizeof(iv),
11707901324dSJerome Forissier transform->iv_enc,
11717901324dSJerome Forissier transform->fixed_ivlen,
11727901324dSJerome Forissier dynamic_iv,
11737901324dSJerome Forissier dynamic_iv_len);
117411fa71b9SJerome Forissier
11757901324dSJerome Forissier /*
11767901324dSJerome Forissier * Build additional data for AEAD encryption.
11777901324dSJerome Forissier * This depends on the TLS version.
11787901324dSJerome Forissier */
11797901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
118032b31808SJens Wiklander transform->tls_version,
118132b31808SJens Wiklander transform->taglen);
118211fa71b9SJerome Forissier
118311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used (internal)",
118411fa71b9SJerome Forissier iv, transform->ivlen);
118511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used (transmitted)",
11867901324dSJerome Forissier dynamic_iv,
11877901324dSJerome Forissier dynamic_iv_is_explicit ? dynamic_iv_len : 0);
118811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
118911fa71b9SJerome Forissier add_data, add_data_len);
11907901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
119111fa71b9SJerome Forissier "including 0 bytes of padding",
119211fa71b9SJerome Forissier rec->data_len));
119311fa71b9SJerome Forissier
119411fa71b9SJerome Forissier /*
119511fa71b9SJerome Forissier * Encrypt and authenticate
119611fa71b9SJerome Forissier */
119732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
119832b31808SJens Wiklander status = psa_aead_encrypt(transform->psa_key_enc,
119932b31808SJens Wiklander transform->psa_alg,
120032b31808SJens Wiklander iv, transform->ivlen,
120132b31808SJens Wiklander add_data, add_data_len,
120232b31808SJens Wiklander data, rec->data_len,
120332b31808SJens Wiklander data, rec->buf_len - (data - rec->buf),
120432b31808SJens Wiklander &rec->data_len);
120511fa71b9SJerome Forissier
120632b31808SJens Wiklander if (status != PSA_SUCCESS) {
120732b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
120832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_encrypt_buf", ret);
120932b31808SJens Wiklander return ret;
121032b31808SJens Wiklander }
121132b31808SJens Wiklander #else
12127901324dSJerome Forissier if ((ret = mbedtls_cipher_auth_encrypt_ext(&transform->cipher_ctx_enc,
121311fa71b9SJerome Forissier iv, transform->ivlen,
12147901324dSJerome Forissier add_data, add_data_len,
12157901324dSJerome Forissier data, rec->data_len, /* src */
1216b0563631STom Van Eyck data, rec->buf_len - (size_t) (data - rec->buf), /* dst */
12177901324dSJerome Forissier &rec->data_len,
121832b31808SJens Wiklander transform->taglen)) != 0) {
121932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_encrypt_ext", ret);
122032b31808SJens Wiklander return ret;
122111fa71b9SJerome Forissier }
122232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
122332b31808SJens Wiklander
122411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "after encrypt: tag",
12257901324dSJerome Forissier data + rec->data_len - transform->taglen,
12267901324dSJerome Forissier transform->taglen);
12277901324dSJerome Forissier /* Account for authentication tag. */
122811fa71b9SJerome Forissier post_avail -= transform->taglen;
12297901324dSJerome Forissier
12307901324dSJerome Forissier /*
12317901324dSJerome Forissier * Prefix record content with dynamic IV in case it is explicit.
12327901324dSJerome Forissier */
123332b31808SJens Wiklander if (dynamic_iv_is_explicit != 0) {
123432b31808SJens Wiklander if (rec->data_offset < dynamic_iv_len) {
12357901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
123632b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
12377901324dSJerome Forissier }
12387901324dSJerome Forissier
12397901324dSJerome Forissier memcpy(data - dynamic_iv_len, dynamic_iv, dynamic_iv_len);
12407901324dSJerome Forissier rec->data_offset -= dynamic_iv_len;
12417901324dSJerome Forissier rec->data_len += dynamic_iv_len;
12427901324dSJerome Forissier }
12437901324dSJerome Forissier
124411fa71b9SJerome Forissier auth_done++;
124532b31808SJens Wiklander } else
1246b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
12477901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
124832b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
124932b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
125011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
125111fa71b9SJerome Forissier size_t padlen, i;
125211fa71b9SJerome Forissier size_t olen;
125332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
125432b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
125532b31808SJens Wiklander size_t part_len;
125632b31808SJens Wiklander psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
125732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
125811fa71b9SJerome Forissier
125911fa71b9SJerome Forissier /* Currently we're always using minimal padding
126011fa71b9SJerome Forissier * (up to 255 bytes would be allowed). */
126111fa71b9SJerome Forissier padlen = transform->ivlen - (rec->data_len + 1) % transform->ivlen;
126232b31808SJens Wiklander if (padlen == transform->ivlen) {
126311fa71b9SJerome Forissier padlen = 0;
126411fa71b9SJerome Forissier }
126511fa71b9SJerome Forissier
126632b31808SJens Wiklander /* Check there's enough space in the buffer for the padding. */
126732b31808SJens Wiklander if (post_avail < padlen + 1) {
126832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
126932b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
127032b31808SJens Wiklander }
127132b31808SJens Wiklander
127232b31808SJens Wiklander for (i = 0; i <= padlen; i++) {
127311fa71b9SJerome Forissier data[rec->data_len + i] = (unsigned char) padlen;
127432b31808SJens Wiklander }
127511fa71b9SJerome Forissier
127611fa71b9SJerome Forissier rec->data_len += padlen + 1;
127711fa71b9SJerome Forissier post_avail -= padlen + 1;
127811fa71b9SJerome Forissier
127932b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
128011fa71b9SJerome Forissier /*
128132b31808SJens Wiklander * Prepend per-record IV for block cipher in TLS v1.2 as per
128211fa71b9SJerome Forissier * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
128311fa71b9SJerome Forissier */
128432b31808SJens Wiklander if (f_rng == NULL) {
128511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("No PRNG provided to encrypt_record routine"));
128632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
128711fa71b9SJerome Forissier }
128811fa71b9SJerome Forissier
128932b31808SJens Wiklander if (rec->data_offset < transform->ivlen) {
129011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
129132b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
129211fa71b9SJerome Forissier }
129311fa71b9SJerome Forissier
129411fa71b9SJerome Forissier /*
129511fa71b9SJerome Forissier * Generate IV
129611fa71b9SJerome Forissier */
129711fa71b9SJerome Forissier ret = f_rng(p_rng, transform->iv_enc, transform->ivlen);
129832b31808SJens Wiklander if (ret != 0) {
129932b31808SJens Wiklander return ret;
130011fa71b9SJerome Forissier }
130132b31808SJens Wiklander
130232b31808SJens Wiklander memcpy(data - transform->ivlen, transform->iv_enc, transform->ivlen);
130332b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
130411fa71b9SJerome Forissier
13057901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
130632b31808SJens Wiklander "including %"
130732b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
13087901324dSJerome Forissier " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
130911fa71b9SJerome Forissier rec->data_len, transform->ivlen,
131011fa71b9SJerome Forissier padlen + 1));
131111fa71b9SJerome Forissier
131232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
131332b31808SJens Wiklander status = psa_cipher_encrypt_setup(&cipher_op,
131432b31808SJens Wiklander transform->psa_key_enc, transform->psa_alg);
131532b31808SJens Wiklander
131632b31808SJens Wiklander if (status != PSA_SUCCESS) {
131732b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
131832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_encrypt_setup", ret);
131932b31808SJens Wiklander return ret;
132032b31808SJens Wiklander }
132132b31808SJens Wiklander
132232b31808SJens Wiklander status = psa_cipher_set_iv(&cipher_op, transform->iv_enc, transform->ivlen);
132332b31808SJens Wiklander
132432b31808SJens Wiklander if (status != PSA_SUCCESS) {
132532b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
132632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
132732b31808SJens Wiklander return ret;
132832b31808SJens Wiklander
132932b31808SJens Wiklander }
133032b31808SJens Wiklander
133132b31808SJens Wiklander status = psa_cipher_update(&cipher_op,
133232b31808SJens Wiklander data, rec->data_len,
133332b31808SJens Wiklander data, rec->data_len, &olen);
133432b31808SJens Wiklander
133532b31808SJens Wiklander if (status != PSA_SUCCESS) {
133632b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
133732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
133832b31808SJens Wiklander return ret;
133932b31808SJens Wiklander
134032b31808SJens Wiklander }
134132b31808SJens Wiklander
134232b31808SJens Wiklander status = psa_cipher_finish(&cipher_op,
134332b31808SJens Wiklander data + olen, rec->data_len - olen,
134432b31808SJens Wiklander &part_len);
134532b31808SJens Wiklander
134632b31808SJens Wiklander if (status != PSA_SUCCESS) {
134732b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
134832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
134932b31808SJens Wiklander return ret;
135032b31808SJens Wiklander
135132b31808SJens Wiklander }
135232b31808SJens Wiklander
135332b31808SJens Wiklander olen += part_len;
135432b31808SJens Wiklander #else
135511fa71b9SJerome Forissier if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_enc,
135611fa71b9SJerome Forissier transform->iv_enc,
135711fa71b9SJerome Forissier transform->ivlen,
135811fa71b9SJerome Forissier data, rec->data_len,
135932b31808SJens Wiklander data, &olen)) != 0) {
136011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
136132b31808SJens Wiklander return ret;
136211fa71b9SJerome Forissier }
136332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
136411fa71b9SJerome Forissier
136532b31808SJens Wiklander if (rec->data_len != olen) {
136611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
136732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
136811fa71b9SJerome Forissier }
136911fa71b9SJerome Forissier
137011fa71b9SJerome Forissier data -= transform->ivlen;
137111fa71b9SJerome Forissier rec->data_offset -= transform->ivlen;
137211fa71b9SJerome Forissier rec->data_len += transform->ivlen;
137311fa71b9SJerome Forissier
137411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
137532b31808SJens Wiklander if (auth_done == 0) {
137611fa71b9SJerome Forissier unsigned char mac[MBEDTLS_SSL_MAC_ADD];
137732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
137832b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
137932b31808SJens Wiklander size_t sign_mac_length = 0;
138032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
138111fa71b9SJerome Forissier
138232b31808SJens Wiklander /* MAC(MAC_write_key, add_data, IV, ENC(content + padding + padding_length))
138311fa71b9SJerome Forissier */
138411fa71b9SJerome Forissier
138532b31808SJens Wiklander if (post_avail < transform->maclen) {
138611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Buffer provided for encrypted record not large enough"));
138732b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
138811fa71b9SJerome Forissier }
138911fa71b9SJerome Forissier
13907901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len,
139132b31808SJens Wiklander rec, transform->tls_version,
139232b31808SJens Wiklander transform->taglen);
139311fa71b9SJerome Forissier
139411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
139511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
139611fa71b9SJerome Forissier add_data_len);
139732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
139832b31808SJens Wiklander status = psa_mac_sign_setup(&operation, transform->psa_mac_enc,
139932b31808SJens Wiklander transform->psa_mac_alg);
140032b31808SJens Wiklander if (status != PSA_SUCCESS) {
140132b31808SJens Wiklander goto hmac_failed_etm_enabled;
140232b31808SJens Wiklander }
140332b31808SJens Wiklander
140432b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len);
140532b31808SJens Wiklander if (status != PSA_SUCCESS) {
140632b31808SJens Wiklander goto hmac_failed_etm_enabled;
140732b31808SJens Wiklander }
140832b31808SJens Wiklander
140932b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len);
141032b31808SJens Wiklander if (status != PSA_SUCCESS) {
141132b31808SJens Wiklander goto hmac_failed_etm_enabled;
141232b31808SJens Wiklander }
141332b31808SJens Wiklander
141432b31808SJens Wiklander status = psa_mac_sign_finish(&operation, mac, MBEDTLS_SSL_MAC_ADD,
141532b31808SJens Wiklander &sign_mac_length);
141632b31808SJens Wiklander if (status != PSA_SUCCESS) {
141732b31808SJens Wiklander goto hmac_failed_etm_enabled;
141832b31808SJens Wiklander }
141932b31808SJens Wiklander #else
142011fa71b9SJerome Forissier
1421039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_enc, add_data,
142211fa71b9SJerome Forissier add_data_len);
142332b31808SJens Wiklander if (ret != 0) {
1424039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
142532b31808SJens Wiklander }
1426039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_enc,
142711fa71b9SJerome Forissier data, rec->data_len);
142832b31808SJens Wiklander if (ret != 0) {
1429039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
143032b31808SJens Wiklander }
1431039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_enc, mac);
143232b31808SJens Wiklander if (ret != 0) {
1433039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
143432b31808SJens Wiklander }
1435039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_enc);
143632b31808SJens Wiklander if (ret != 0) {
1437039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
143832b31808SJens Wiklander }
143932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
144011fa71b9SJerome Forissier
144111fa71b9SJerome Forissier memcpy(data + rec->data_len, mac, transform->maclen);
144211fa71b9SJerome Forissier
144311fa71b9SJerome Forissier rec->data_len += transform->maclen;
144411fa71b9SJerome Forissier post_avail -= transform->maclen;
144511fa71b9SJerome Forissier auth_done++;
1446039e02dfSJerome Forissier
1447039e02dfSJerome Forissier hmac_failed_etm_enabled:
1448039e02dfSJerome Forissier mbedtls_platform_zeroize(mac, transform->maclen);
144932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
145032b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
145132b31808SJens Wiklander status = psa_mac_abort(&operation);
145232b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) {
145332b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
145432b31808SJens Wiklander }
145532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
145632b31808SJens Wiklander if (ret != 0) {
1457039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "HMAC calculation failed", ret);
145832b31808SJens Wiklander return ret;
1459039e02dfSJerome Forissier }
146011fa71b9SJerome Forissier }
146111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
146232b31808SJens Wiklander } else
14637901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
146411fa71b9SJerome Forissier {
146511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
146632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
146711fa71b9SJerome Forissier }
146811fa71b9SJerome Forissier
146911fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */
147032b31808SJens Wiklander if (auth_done != 1) {
147111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
147232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
147311fa71b9SJerome Forissier }
147411fa71b9SJerome Forissier
147511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= encrypt buf"));
147611fa71b9SJerome Forissier
147732b31808SJens Wiklander return 0;
147811fa71b9SJerome Forissier }
147911fa71b9SJerome Forissier
mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const * ssl,mbedtls_ssl_transform * transform,mbedtls_record * rec)148011fa71b9SJerome Forissier int mbedtls_ssl_decrypt_buf(mbedtls_ssl_context const *ssl,
148111fa71b9SJerome Forissier mbedtls_ssl_transform *transform,
148211fa71b9SJerome Forissier mbedtls_record *rec)
148311fa71b9SJerome Forissier {
1484b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) || defined(MBEDTLS_SSL_HAVE_AEAD)
148511fa71b9SJerome Forissier size_t olen;
1486b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC || MBEDTLS_SSL_HAVE_AEAD */
148732b31808SJens Wiklander mbedtls_ssl_mode_t ssl_mode;
148832b31808SJens Wiklander int ret;
148932b31808SJens Wiklander
149032b31808SJens Wiklander int auth_done = 0;
149132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
1492b0563631STom Van Eyck size_t padlen = 0;
1493b0563631STom Van Eyck mbedtls_ct_condition_t correct = MBEDTLS_CT_TRUE;
149411fa71b9SJerome Forissier #endif
149511fa71b9SJerome Forissier unsigned char *data;
149632b31808SJens Wiklander /* For an explanation of the additional data length see
149732b31808SJens Wiklander * the description of ssl_extract_add_data_from_record().
149832b31808SJens Wiklander */
149932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
150032b31808SJens Wiklander unsigned char add_data[23 + MBEDTLS_SSL_CID_IN_LEN_MAX];
150132b31808SJens Wiklander #else
150232b31808SJens Wiklander unsigned char add_data[13];
150332b31808SJens Wiklander #endif
150411fa71b9SJerome Forissier size_t add_data_len;
150511fa71b9SJerome Forissier
150611fa71b9SJerome Forissier #if !defined(MBEDTLS_DEBUG_C)
150711fa71b9SJerome Forissier ssl = NULL; /* make sure we don't use it except for debug */
150811fa71b9SJerome Forissier ((void) ssl);
150911fa71b9SJerome Forissier #endif
151011fa71b9SJerome Forissier
151111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> decrypt buf"));
151211fa71b9SJerome Forissier if (rec == NULL ||
151311fa71b9SJerome Forissier rec->buf == NULL ||
151411fa71b9SJerome Forissier rec->buf_len < rec->data_offset ||
151532b31808SJens Wiklander rec->buf_len - rec->data_offset < rec->data_len) {
151611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad record structure provided to decrypt_buf"));
151732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
151811fa71b9SJerome Forissier }
151911fa71b9SJerome Forissier
152011fa71b9SJerome Forissier data = rec->buf + rec->data_offset;
152132b31808SJens Wiklander ssl_mode = mbedtls_ssl_get_mode_from_transform(transform);
152211fa71b9SJerome Forissier
152311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
152411fa71b9SJerome Forissier /*
152511fa71b9SJerome Forissier * Match record's CID with incoming CID.
152611fa71b9SJerome Forissier */
152711fa71b9SJerome Forissier if (rec->cid_len != transform->in_cid_len ||
152832b31808SJens Wiklander memcmp(rec->cid, transform->in_cid, rec->cid_len) != 0) {
152932b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_CID;
153011fa71b9SJerome Forissier }
153111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
153211fa71b9SJerome Forissier
153332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_STREAM)
153432b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_STREAM) {
1535b0563631STom Van Eyck if (rec->data_len < transform->maclen) {
1536b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(1,
1537b0563631STom Van Eyck ("Record too short for MAC:"
1538b0563631STom Van Eyck " %" MBEDTLS_PRINTF_SIZET " < %" MBEDTLS_PRINTF_SIZET,
1539b0563631STom Van Eyck rec->data_len, transform->maclen));
1540b0563631STom Van Eyck return MBEDTLS_ERR_SSL_INVALID_MAC;
1541b0563631STom Van Eyck }
1542b0563631STom Van Eyck
154332b31808SJens Wiklander /* The only supported stream cipher is "NULL",
1544b0563631STom Van Eyck * so there's no encryption to do here.*/
154532b31808SJens Wiklander } else
154632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_STREAM */
1547b0563631STom Van Eyck #if defined(MBEDTLS_SSL_HAVE_AEAD)
154832b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_AEAD) {
154911fa71b9SJerome Forissier unsigned char iv[12];
15507901324dSJerome Forissier unsigned char *dynamic_iv;
15517901324dSJerome Forissier size_t dynamic_iv_len;
155232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
155332b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
155432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
155511fa71b9SJerome Forissier
155611fa71b9SJerome Forissier /*
15577901324dSJerome Forissier * Extract dynamic part of nonce for AEAD decryption.
15587901324dSJerome Forissier *
15597901324dSJerome Forissier * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
15607901324dSJerome Forissier * part of the IV is prepended to the ciphertext and
15617901324dSJerome Forissier * can be chosen freely - in particular, it need not
15627901324dSJerome Forissier * agree with the record sequence number.
156311fa71b9SJerome Forissier */
15647901324dSJerome Forissier dynamic_iv_len = sizeof(rec->ctr);
156532b31808SJens Wiklander if (ssl_transform_aead_dynamic_iv_is_explicit(transform) == 1) {
156632b31808SJens Wiklander if (rec->data_len < dynamic_iv_len) {
15677901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
15687901324dSJerome Forissier " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
15697901324dSJerome Forissier rec->data_len,
15707901324dSJerome Forissier dynamic_iv_len));
157132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
157211fa71b9SJerome Forissier }
15737901324dSJerome Forissier dynamic_iv = data;
157411fa71b9SJerome Forissier
15757901324dSJerome Forissier data += dynamic_iv_len;
15767901324dSJerome Forissier rec->data_offset += dynamic_iv_len;
15777901324dSJerome Forissier rec->data_len -= dynamic_iv_len;
157832b31808SJens Wiklander } else {
15797901324dSJerome Forissier dynamic_iv = rec->ctr;
158011fa71b9SJerome Forissier }
158111fa71b9SJerome Forissier
15827901324dSJerome Forissier /* Check that there's space for the authentication tag. */
158332b31808SJens Wiklander if (rec->data_len < transform->taglen) {
15847901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
15857901324dSJerome Forissier ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
15867901324dSJerome Forissier rec->data_len,
15877901324dSJerome Forissier transform->taglen));
158832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
15897901324dSJerome Forissier }
15907901324dSJerome Forissier rec->data_len -= transform->taglen;
159111fa71b9SJerome Forissier
15927901324dSJerome Forissier /*
15937901324dSJerome Forissier * Prepare nonce from dynamic and static parts.
15947901324dSJerome Forissier */
15957901324dSJerome Forissier ssl_build_record_nonce(iv, sizeof(iv),
15967901324dSJerome Forissier transform->iv_dec,
15977901324dSJerome Forissier transform->fixed_ivlen,
15987901324dSJerome Forissier dynamic_iv,
15997901324dSJerome Forissier dynamic_iv_len);
16007901324dSJerome Forissier
16017901324dSJerome Forissier /*
16027901324dSJerome Forissier * Build additional data for AEAD encryption.
16037901324dSJerome Forissier * This depends on the TLS version.
16047901324dSJerome Forissier */
16057901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
160632b31808SJens Wiklander transform->tls_version,
160732b31808SJens Wiklander transform->taglen);
160811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "additional data used for AEAD",
160911fa71b9SJerome Forissier add_data, add_data_len);
161011fa71b9SJerome Forissier
161111fa71b9SJerome Forissier /* Because of the check above, we know that there are
1612039e02dfSJerome Forissier * explicit_iv_len Bytes preceding data, and taglen
161311fa71b9SJerome Forissier * bytes following data + data_len. This justifies
161411fa71b9SJerome Forissier * the debug message and the invocation of
161532b31808SJens Wiklander * mbedtls_cipher_auth_decrypt_ext() below. */
161611fa71b9SJerome Forissier
161711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "IV used", iv, transform->ivlen);
161811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "TAG used", data + rec->data_len,
161911fa71b9SJerome Forissier transform->taglen);
162011fa71b9SJerome Forissier
162111fa71b9SJerome Forissier /*
162211fa71b9SJerome Forissier * Decrypt and authenticate
162311fa71b9SJerome Forissier */
162432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
162532b31808SJens Wiklander status = psa_aead_decrypt(transform->psa_key_dec,
162632b31808SJens Wiklander transform->psa_alg,
162732b31808SJens Wiklander iv, transform->ivlen,
162832b31808SJens Wiklander add_data, add_data_len,
162932b31808SJens Wiklander data, rec->data_len + transform->taglen,
163032b31808SJens Wiklander data, rec->buf_len - (data - rec->buf),
163132b31808SJens Wiklander &olen);
163232b31808SJens Wiklander
163332b31808SJens Wiklander if (status != PSA_SUCCESS) {
163432b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
163532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_aead_decrypt", ret);
163632b31808SJens Wiklander return ret;
163732b31808SJens Wiklander }
163832b31808SJens Wiklander #else
1639b0563631STom Van Eyck if ((ret = mbedtls_cipher_auth_decrypt_ext
1640b0563631STom Van Eyck (&transform->cipher_ctx_dec,
164111fa71b9SJerome Forissier iv, transform->ivlen,
164211fa71b9SJerome Forissier add_data, add_data_len,
16437901324dSJerome Forissier data, rec->data_len + transform->taglen, /* src */
1644b0563631STom Van Eyck data, rec->buf_len - (size_t) (data - rec->buf), &olen, /* dst */
164532b31808SJens Wiklander transform->taglen)) != 0) {
164632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_auth_decrypt_ext", ret);
164711fa71b9SJerome Forissier
164832b31808SJens Wiklander if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
164932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
165011fa71b9SJerome Forissier }
165132b31808SJens Wiklander
165232b31808SJens Wiklander return ret;
165332b31808SJens Wiklander }
165432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
165532b31808SJens Wiklander
165611fa71b9SJerome Forissier auth_done++;
165711fa71b9SJerome Forissier
165811fa71b9SJerome Forissier /* Double-check that AEAD decryption doesn't change content length. */
165932b31808SJens Wiklander if (olen != rec->data_len) {
166011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
166132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
166211fa71b9SJerome Forissier }
166332b31808SJens Wiklander } else
1664b0563631STom Van Eyck #endif /* MBEDTLS_SSL_HAVE_AEAD */
16657901324dSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
166632b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC ||
166732b31808SJens Wiklander ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
166811fa71b9SJerome Forissier size_t minlen = 0;
166932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
167032b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
167132b31808SJens Wiklander size_t part_len;
167232b31808SJens Wiklander psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
167332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
167411fa71b9SJerome Forissier
167511fa71b9SJerome Forissier /*
167611fa71b9SJerome Forissier * Check immediate ciphertext sanity
167711fa71b9SJerome Forissier */
167832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
167911fa71b9SJerome Forissier /* The ciphertext is prefixed with the CBC IV. */
168011fa71b9SJerome Forissier minlen += transform->ivlen;
168111fa71b9SJerome Forissier #endif
168211fa71b9SJerome Forissier
168311fa71b9SJerome Forissier /* Size considerations:
168411fa71b9SJerome Forissier *
168511fa71b9SJerome Forissier * - The CBC cipher text must not be empty and hence
168611fa71b9SJerome Forissier * at least of size transform->ivlen.
168711fa71b9SJerome Forissier *
168811fa71b9SJerome Forissier * Together with the potential IV-prefix, this explains
168911fa71b9SJerome Forissier * the first of the two checks below.
169011fa71b9SJerome Forissier *
169111fa71b9SJerome Forissier * - The record must contain a MAC, either in plain or
169211fa71b9SJerome Forissier * encrypted, depending on whether Encrypt-then-MAC
169311fa71b9SJerome Forissier * is used or not.
169411fa71b9SJerome Forissier * - If it is, the message contains the IV-prefix,
169511fa71b9SJerome Forissier * the CBC ciphertext, and the MAC.
169611fa71b9SJerome Forissier * - If it is not, the padded plaintext, and hence
169711fa71b9SJerome Forissier * the CBC ciphertext, has at least length maclen + 1
169811fa71b9SJerome Forissier * because there is at least the padding length byte.
169911fa71b9SJerome Forissier *
170011fa71b9SJerome Forissier * As the CBC ciphertext is not empty, both cases give the
170111fa71b9SJerome Forissier * lower bound minlen + maclen + 1 on the record size, which
170211fa71b9SJerome Forissier * we test for in the second check below.
170311fa71b9SJerome Forissier */
170411fa71b9SJerome Forissier if (rec->data_len < minlen + transform->ivlen ||
170532b31808SJens Wiklander rec->data_len < minlen + transform->maclen + 1) {
17067901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
17077901324dSJerome Forissier ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
17087901324dSJerome Forissier "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
170932b31808SJens Wiklander "+ 1 ) ( + expl IV )",
171032b31808SJens Wiklander rec->data_len,
171111fa71b9SJerome Forissier transform->ivlen,
171211fa71b9SJerome Forissier transform->maclen));
171332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
171411fa71b9SJerome Forissier }
171511fa71b9SJerome Forissier
171611fa71b9SJerome Forissier /*
171711fa71b9SJerome Forissier * Authenticate before decrypt if enabled
171811fa71b9SJerome Forissier */
171911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
172032b31808SJens Wiklander if (ssl_mode == MBEDTLS_SSL_MODE_CBC_ETM) {
172132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
172232b31808SJens Wiklander psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
172332b31808SJens Wiklander #else
172411fa71b9SJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
172532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
172611fa71b9SJerome Forissier
172711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("using encrypt then mac"));
172811fa71b9SJerome Forissier
172911fa71b9SJerome Forissier /* Update data_len in tandem with add_data.
173011fa71b9SJerome Forissier *
173111fa71b9SJerome Forissier * The subtraction is safe because of the previous check
173211fa71b9SJerome Forissier * data_len >= minlen + maclen + 1.
173311fa71b9SJerome Forissier *
173411fa71b9SJerome Forissier * Afterwards, we know that data + data_len is followed by at
173511fa71b9SJerome Forissier * least maclen Bytes, which justifies the call to
1736039e02dfSJerome Forissier * mbedtls_ct_memcmp() below.
173711fa71b9SJerome Forissier *
173811fa71b9SJerome Forissier * Further, we still know that data_len > minlen */
173911fa71b9SJerome Forissier rec->data_len -= transform->maclen;
17407901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
174132b31808SJens Wiklander transform->tls_version,
174232b31808SJens Wiklander transform->taglen);
174311fa71b9SJerome Forissier
174411fa71b9SJerome Forissier /* Calculate expected MAC. */
174511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "MAC'd meta-data", add_data,
174611fa71b9SJerome Forissier add_data_len);
174732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
174832b31808SJens Wiklander status = psa_mac_verify_setup(&operation, transform->psa_mac_dec,
174932b31808SJens Wiklander transform->psa_mac_alg);
175032b31808SJens Wiklander if (status != PSA_SUCCESS) {
175132b31808SJens Wiklander goto hmac_failed_etm_enabled;
175232b31808SJens Wiklander }
175332b31808SJens Wiklander
175432b31808SJens Wiklander status = psa_mac_update(&operation, add_data, add_data_len);
175532b31808SJens Wiklander if (status != PSA_SUCCESS) {
175632b31808SJens Wiklander goto hmac_failed_etm_enabled;
175732b31808SJens Wiklander }
175832b31808SJens Wiklander
175932b31808SJens Wiklander status = psa_mac_update(&operation, data, rec->data_len);
176032b31808SJens Wiklander if (status != PSA_SUCCESS) {
176132b31808SJens Wiklander goto hmac_failed_etm_enabled;
176232b31808SJens Wiklander }
176332b31808SJens Wiklander
176432b31808SJens Wiklander /* Compare expected MAC with MAC at the end of the record. */
176532b31808SJens Wiklander status = psa_mac_verify_finish(&operation, data + rec->data_len,
176632b31808SJens Wiklander transform->maclen);
176732b31808SJens Wiklander if (status != PSA_SUCCESS) {
176832b31808SJens Wiklander goto hmac_failed_etm_enabled;
176932b31808SJens Wiklander }
177032b31808SJens Wiklander #else
1771039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_dec, add_data,
177211fa71b9SJerome Forissier add_data_len);
177332b31808SJens Wiklander if (ret != 0) {
1774039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
177532b31808SJens Wiklander }
1776039e02dfSJerome Forissier ret = mbedtls_md_hmac_update(&transform->md_ctx_dec,
177711fa71b9SJerome Forissier data, rec->data_len);
177832b31808SJens Wiklander if (ret != 0) {
1779039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
178032b31808SJens Wiklander }
1781039e02dfSJerome Forissier ret = mbedtls_md_hmac_finish(&transform->md_ctx_dec, mac_expect);
178232b31808SJens Wiklander if (ret != 0) {
1783039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
178432b31808SJens Wiklander }
1785039e02dfSJerome Forissier ret = mbedtls_md_hmac_reset(&transform->md_ctx_dec);
178632b31808SJens Wiklander if (ret != 0) {
1787039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
178832b31808SJens Wiklander }
178911fa71b9SJerome Forissier
179011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message mac", data + rec->data_len,
179111fa71b9SJerome Forissier transform->maclen);
179211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect,
179311fa71b9SJerome Forissier transform->maclen);
179411fa71b9SJerome Forissier
179511fa71b9SJerome Forissier /* Compare expected MAC with MAC at the end of the record. */
1796039e02dfSJerome Forissier if (mbedtls_ct_memcmp(data + rec->data_len, mac_expect,
179732b31808SJens Wiklander transform->maclen) != 0) {
179811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
1799039e02dfSJerome Forissier ret = MBEDTLS_ERR_SSL_INVALID_MAC;
1800039e02dfSJerome Forissier goto hmac_failed_etm_enabled;
180111fa71b9SJerome Forissier }
180232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
180311fa71b9SJerome Forissier auth_done++;
1804039e02dfSJerome Forissier
1805039e02dfSJerome Forissier hmac_failed_etm_enabled:
180632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
180732b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
180832b31808SJens Wiklander status = psa_mac_abort(&operation);
180932b31808SJens Wiklander if (ret == 0 && status != PSA_SUCCESS) {
181032b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
181132b31808SJens Wiklander }
181232b31808SJens Wiklander #else
1813039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_expect, transform->maclen);
181432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
181532b31808SJens Wiklander if (ret != 0) {
181632b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_INVALID_MAC) {
1817039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_hmac_xxx", ret);
181832b31808SJens Wiklander }
181932b31808SJens Wiklander return ret;
1820039e02dfSJerome Forissier }
182111fa71b9SJerome Forissier }
182211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
182311fa71b9SJerome Forissier
182411fa71b9SJerome Forissier /*
182511fa71b9SJerome Forissier * Check length sanity
182611fa71b9SJerome Forissier */
182711fa71b9SJerome Forissier
182811fa71b9SJerome Forissier /* We know from above that data_len > minlen >= 0,
182911fa71b9SJerome Forissier * so the following check in particular implies that
183011fa71b9SJerome Forissier * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
183132b31808SJens Wiklander if (rec->data_len % transform->ivlen != 0) {
18327901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
18337901324dSJerome Forissier ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
183411fa71b9SJerome Forissier rec->data_len, transform->ivlen));
183532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
183611fa71b9SJerome Forissier }
183711fa71b9SJerome Forissier
183832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
183911fa71b9SJerome Forissier /*
184032b31808SJens Wiklander * Initialize for prepended IV for block cipher in TLS v1.2
184111fa71b9SJerome Forissier */
184211fa71b9SJerome Forissier /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
184311fa71b9SJerome Forissier memcpy(transform->iv_dec, data, transform->ivlen);
184411fa71b9SJerome Forissier
184511fa71b9SJerome Forissier data += transform->ivlen;
184611fa71b9SJerome Forissier rec->data_offset += transform->ivlen;
184711fa71b9SJerome Forissier rec->data_len -= transform->ivlen;
184832b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
184911fa71b9SJerome Forissier
185011fa71b9SJerome Forissier /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
185111fa71b9SJerome Forissier
185232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
185332b31808SJens Wiklander status = psa_cipher_decrypt_setup(&cipher_op,
185432b31808SJens Wiklander transform->psa_key_dec, transform->psa_alg);
185532b31808SJens Wiklander
185632b31808SJens Wiklander if (status != PSA_SUCCESS) {
185732b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
185832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_decrypt_setup", ret);
185932b31808SJens Wiklander return ret;
186032b31808SJens Wiklander }
186132b31808SJens Wiklander
186232b31808SJens Wiklander status = psa_cipher_set_iv(&cipher_op, transform->iv_dec, transform->ivlen);
186332b31808SJens Wiklander
186432b31808SJens Wiklander if (status != PSA_SUCCESS) {
186532b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
186632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_set_iv", ret);
186732b31808SJens Wiklander return ret;
186832b31808SJens Wiklander }
186932b31808SJens Wiklander
187032b31808SJens Wiklander status = psa_cipher_update(&cipher_op,
187132b31808SJens Wiklander data, rec->data_len,
187232b31808SJens Wiklander data, rec->data_len, &olen);
187332b31808SJens Wiklander
187432b31808SJens Wiklander if (status != PSA_SUCCESS) {
187532b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
187632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_update", ret);
187732b31808SJens Wiklander return ret;
187832b31808SJens Wiklander }
187932b31808SJens Wiklander
188032b31808SJens Wiklander status = psa_cipher_finish(&cipher_op,
188132b31808SJens Wiklander data + olen, rec->data_len - olen,
188232b31808SJens Wiklander &part_len);
188332b31808SJens Wiklander
188432b31808SJens Wiklander if (status != PSA_SUCCESS) {
188532b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
188632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_cipher_finish", ret);
188732b31808SJens Wiklander return ret;
188832b31808SJens Wiklander }
188932b31808SJens Wiklander
189032b31808SJens Wiklander olen += part_len;
189132b31808SJens Wiklander #else
189232b31808SJens Wiklander
189311fa71b9SJerome Forissier if ((ret = mbedtls_cipher_crypt(&transform->cipher_ctx_dec,
189411fa71b9SJerome Forissier transform->iv_dec, transform->ivlen,
189532b31808SJens Wiklander data, rec->data_len, data, &olen)) != 0) {
189611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_crypt", ret);
189732b31808SJens Wiklander return ret;
189811fa71b9SJerome Forissier }
189932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
190011fa71b9SJerome Forissier
190111fa71b9SJerome Forissier /* Double-check that length hasn't changed during decryption. */
190232b31808SJens Wiklander if (rec->data_len != olen) {
190311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
190432b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
190511fa71b9SJerome Forissier }
190611fa71b9SJerome Forissier
190711fa71b9SJerome Forissier /* Safe since data_len >= minlen + maclen + 1, so after having
190811fa71b9SJerome Forissier * subtracted at most minlen and maclen up to this point,
190911fa71b9SJerome Forissier * data_len > 0 (because of data_len % ivlen == 0, it's actually
191011fa71b9SJerome Forissier * >= ivlen ). */
191111fa71b9SJerome Forissier padlen = data[rec->data_len - 1];
191211fa71b9SJerome Forissier
191332b31808SJens Wiklander if (auth_done == 1) {
1914b0563631STom Van Eyck const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
19157901324dSJerome Forissier rec->data_len,
19167901324dSJerome Forissier padlen + 1);
1917b0563631STom Van Eyck correct = mbedtls_ct_bool_and(ge, correct);
1918b0563631STom Van Eyck padlen = mbedtls_ct_size_if_else_0(ge, padlen);
191932b31808SJens Wiklander } else {
192011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
192132b31808SJens Wiklander if (rec->data_len < transform->maclen + padlen + 1) {
19227901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("msglen (%" MBEDTLS_PRINTF_SIZET
19237901324dSJerome Forissier ") < maclen (%" MBEDTLS_PRINTF_SIZET
19247901324dSJerome Forissier ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
192511fa71b9SJerome Forissier rec->data_len,
192611fa71b9SJerome Forissier transform->maclen,
192711fa71b9SJerome Forissier padlen + 1));
192811fa71b9SJerome Forissier }
192911fa71b9SJerome Forissier #endif
1930b0563631STom Van Eyck const mbedtls_ct_condition_t ge = mbedtls_ct_uint_ge(
19317901324dSJerome Forissier rec->data_len,
19327901324dSJerome Forissier transform->maclen + padlen + 1);
1933b0563631STom Van Eyck correct = mbedtls_ct_bool_and(ge, correct);
1934b0563631STom Van Eyck padlen = mbedtls_ct_size_if_else_0(ge, padlen);
193511fa71b9SJerome Forissier }
193611fa71b9SJerome Forissier
193711fa71b9SJerome Forissier padlen++;
193811fa71b9SJerome Forissier
193911fa71b9SJerome Forissier /* Regardless of the validity of the padding,
194011fa71b9SJerome Forissier * we have data_len >= padlen here. */
194111fa71b9SJerome Forissier
194232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
194311fa71b9SJerome Forissier /* The padding check involves a series of up to 256
194411fa71b9SJerome Forissier * consecutive memory reads at the end of the record
194511fa71b9SJerome Forissier * plaintext buffer. In order to hide the length and
194611fa71b9SJerome Forissier * validity of the padding, always perform exactly
194711fa71b9SJerome Forissier * `min(256,plaintext_len)` reads (but take into account
194811fa71b9SJerome Forissier * only the last `padlen` bytes for the padding check). */
194911fa71b9SJerome Forissier size_t pad_count = 0;
195011fa71b9SJerome Forissier volatile unsigned char * const check = data;
195111fa71b9SJerome Forissier
195211fa71b9SJerome Forissier /* Index of first padding byte; it has been ensured above
195311fa71b9SJerome Forissier * that the subtraction is safe. */
195411fa71b9SJerome Forissier size_t const padding_idx = rec->data_len - padlen;
195511fa71b9SJerome Forissier size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
195611fa71b9SJerome Forissier size_t const start_idx = rec->data_len - num_checks;
195711fa71b9SJerome Forissier size_t idx;
195811fa71b9SJerome Forissier
195932b31808SJens Wiklander for (idx = start_idx; idx < rec->data_len; idx++) {
19607901324dSJerome Forissier /* pad_count += (idx >= padding_idx) &&
19617901324dSJerome Forissier * (check[idx] == padlen - 1);
19627901324dSJerome Forissier */
1963b0563631STom Van Eyck const mbedtls_ct_condition_t a = mbedtls_ct_uint_ge(idx, padding_idx);
1964b0563631STom Van Eyck size_t increment = mbedtls_ct_size_if_else_0(a, 1);
1965b0563631STom Van Eyck const mbedtls_ct_condition_t b = mbedtls_ct_uint_eq(check[idx], padlen - 1);
1966b0563631STom Van Eyck increment = mbedtls_ct_size_if_else_0(b, increment);
1967b0563631STom Van Eyck pad_count += increment;
196811fa71b9SJerome Forissier }
1969b0563631STom Van Eyck correct = mbedtls_ct_bool_and(mbedtls_ct_uint_eq(pad_count, padlen), correct);
197011fa71b9SJerome Forissier
197111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
1972b0563631STom Van Eyck if (padlen > 0 && correct == MBEDTLS_CT_FALSE) {
197311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad padding byte detected"));
197432b31808SJens Wiklander }
197511fa71b9SJerome Forissier #endif
1976b0563631STom Van Eyck padlen = mbedtls_ct_size_if_else_0(correct, padlen);
197732b31808SJens Wiklander
197832b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
197911fa71b9SJerome Forissier
198011fa71b9SJerome Forissier /* If the padding was found to be invalid, padlen == 0
198111fa71b9SJerome Forissier * and the subtraction is safe. If the padding was found valid,
198211fa71b9SJerome Forissier * padlen hasn't been changed and the previous assertion
198311fa71b9SJerome Forissier * data_len >= padlen still holds. */
198411fa71b9SJerome Forissier rec->data_len -= padlen;
198532b31808SJens Wiklander } else
19867901324dSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
198711fa71b9SJerome Forissier {
198811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
198932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
199011fa71b9SJerome Forissier }
199111fa71b9SJerome Forissier
199211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
199311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "raw buffer after decryption",
199411fa71b9SJerome Forissier data, rec->data_len);
199511fa71b9SJerome Forissier #endif
199611fa71b9SJerome Forissier
199711fa71b9SJerome Forissier /*
199811fa71b9SJerome Forissier * Authenticate if not done yet.
199911fa71b9SJerome Forissier * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
200011fa71b9SJerome Forissier */
200132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
200232b31808SJens Wiklander if (auth_done == 0) {
2003039e02dfSJerome Forissier unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD] = { 0 };
2004039e02dfSJerome Forissier unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD] = { 0 };
200511fa71b9SJerome Forissier
2006b0563631STom Van Eyck /* For CBC+MAC, If the initial value of padlen was such that
200711fa71b9SJerome Forissier * data_len < maclen + padlen + 1, then padlen
200811fa71b9SJerome Forissier * got reset to 1, and the initial check
200911fa71b9SJerome Forissier * data_len >= minlen + maclen + 1
201011fa71b9SJerome Forissier * guarantees that at this point we still
201111fa71b9SJerome Forissier * have at least data_len >= maclen.
201211fa71b9SJerome Forissier *
201311fa71b9SJerome Forissier * If the initial value of padlen was such that
201411fa71b9SJerome Forissier * data_len >= maclen + padlen + 1, then we have
201511fa71b9SJerome Forissier * subtracted either padlen + 1 (if the padding was correct)
201611fa71b9SJerome Forissier * or 0 (if the padding was incorrect) since then,
201711fa71b9SJerome Forissier * hence data_len >= maclen in any case.
2018b0563631STom Van Eyck *
2019b0563631STom Van Eyck * For stream ciphers, we checked above that
2020b0563631STom Van Eyck * data_len >= maclen.
202111fa71b9SJerome Forissier */
202211fa71b9SJerome Forissier rec->data_len -= transform->maclen;
20237901324dSJerome Forissier ssl_extract_add_data_from_record(add_data, &add_data_len, rec,
202432b31808SJens Wiklander transform->tls_version,
202532b31808SJens Wiklander transform->taglen);
202611fa71b9SJerome Forissier
202732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
202811fa71b9SJerome Forissier /*
202911fa71b9SJerome Forissier * The next two sizes are the minimum and maximum values of
20307901324dSJerome Forissier * data_len over all padlen values.
203111fa71b9SJerome Forissier *
203211fa71b9SJerome Forissier * They're independent of padlen, since we previously did
203311fa71b9SJerome Forissier * data_len -= padlen.
203411fa71b9SJerome Forissier *
203511fa71b9SJerome Forissier * Note that max_len + maclen is never more than the buffer
203611fa71b9SJerome Forissier * length, as we previously did in_msglen -= maclen too.
203711fa71b9SJerome Forissier */
203811fa71b9SJerome Forissier const size_t max_len = rec->data_len + padlen;
203911fa71b9SJerome Forissier const size_t min_len = (max_len > 256) ? max_len - 256 : 0;
204011fa71b9SJerome Forissier
204132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
204232b31808SJens Wiklander ret = mbedtls_ct_hmac(transform->psa_mac_dec,
204332b31808SJens Wiklander transform->psa_mac_alg,
204432b31808SJens Wiklander add_data, add_data_len,
204532b31808SJens Wiklander data, rec->data_len, min_len, max_len,
204632b31808SJens Wiklander mac_expect);
204732b31808SJens Wiklander #else
2048039e02dfSJerome Forissier ret = mbedtls_ct_hmac(&transform->md_ctx_dec,
20497901324dSJerome Forissier add_data, add_data_len,
20507901324dSJerome Forissier data, rec->data_len, min_len, max_len,
20517901324dSJerome Forissier mac_expect);
205232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
205332b31808SJens Wiklander if (ret != 0) {
2054039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ct_hmac", ret);
2055039e02dfSJerome Forissier goto hmac_failed_etm_disabled;
205611fa71b9SJerome Forissier }
205711fa71b9SJerome Forissier
2058039e02dfSJerome Forissier mbedtls_ct_memcpy_offset(mac_peer, data,
20597901324dSJerome Forissier rec->data_len,
20607901324dSJerome Forissier min_len, max_len,
20617901324dSJerome Forissier transform->maclen);
206232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
206311fa71b9SJerome Forissier
206411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
206511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "expected mac", mac_expect, transform->maclen);
20667901324dSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message mac", mac_peer, transform->maclen);
206711fa71b9SJerome Forissier #endif
206811fa71b9SJerome Forissier
2069039e02dfSJerome Forissier if (mbedtls_ct_memcmp(mac_peer, mac_expect,
207032b31808SJens Wiklander transform->maclen) != 0) {
207111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DEBUG_ALL)
207211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("message mac does not match"));
207311fa71b9SJerome Forissier #endif
2074b0563631STom Van Eyck correct = MBEDTLS_CT_FALSE;
207511fa71b9SJerome Forissier }
207611fa71b9SJerome Forissier auth_done++;
2077039e02dfSJerome Forissier
2078039e02dfSJerome Forissier hmac_failed_etm_disabled:
2079039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_peer, transform->maclen);
2080039e02dfSJerome Forissier mbedtls_platform_zeroize(mac_expect, transform->maclen);
208132b31808SJens Wiklander if (ret != 0) {
208232b31808SJens Wiklander return ret;
208332b31808SJens Wiklander }
208411fa71b9SJerome Forissier }
208511fa71b9SJerome Forissier
208611fa71b9SJerome Forissier /*
208711fa71b9SJerome Forissier * Finally check the correct flag
208811fa71b9SJerome Forissier */
2089b0563631STom Van Eyck if (correct == MBEDTLS_CT_FALSE) {
209032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
209132b31808SJens Wiklander }
209232b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
209311fa71b9SJerome Forissier
209411fa71b9SJerome Forissier /* Make extra sure authentication was performed, exactly once */
209532b31808SJens Wiklander if (auth_done != 1) {
209611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
209732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
209811fa71b9SJerome Forissier }
209911fa71b9SJerome Forissier
210032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
210132b31808SJens Wiklander if (transform->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
21027901324dSJerome Forissier /* Remove inner padding and infer true content type. */
21037901324dSJerome Forissier ret = ssl_parse_inner_plaintext(data, &rec->data_len,
21047901324dSJerome Forissier &rec->type);
21057901324dSJerome Forissier
210632b31808SJens Wiklander if (ret != 0) {
210732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
21087901324dSJerome Forissier }
210932b31808SJens Wiklander }
211032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
21117901324dSJerome Forissier
211211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
211332b31808SJens Wiklander if (rec->cid_len != 0) {
21147901324dSJerome Forissier ret = ssl_parse_inner_plaintext(data, &rec->data_len,
211511fa71b9SJerome Forissier &rec->type);
211632b31808SJens Wiklander if (ret != 0) {
211732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
211832b31808SJens Wiklander }
211911fa71b9SJerome Forissier }
212011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
212111fa71b9SJerome Forissier
212211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= decrypt buf"));
212311fa71b9SJerome Forissier
212432b31808SJens Wiklander return 0;
212511fa71b9SJerome Forissier }
212611fa71b9SJerome Forissier
212711fa71b9SJerome Forissier #undef MAC_NONE
212811fa71b9SJerome Forissier #undef MAC_PLAINTEXT
212911fa71b9SJerome Forissier #undef MAC_CIPHERTEXT
213011fa71b9SJerome Forissier
213111fa71b9SJerome Forissier /*
213211fa71b9SJerome Forissier * Fill the input message buffer by appending data to it.
213311fa71b9SJerome Forissier * The amount of data already fetched is in ssl->in_left.
213411fa71b9SJerome Forissier *
213511fa71b9SJerome Forissier * If we return 0, is it guaranteed that (at least) nb_want bytes are
213611fa71b9SJerome Forissier * available (from this read and/or a previous one). Otherwise, an error code
213711fa71b9SJerome Forissier * is returned (possibly EOF or WANT_READ).
213811fa71b9SJerome Forissier *
213911fa71b9SJerome Forissier * With stream transport (TLS) on success ssl->in_left == nb_want, but
214011fa71b9SJerome Forissier * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
214111fa71b9SJerome Forissier * since we always read a whole datagram at once.
214211fa71b9SJerome Forissier *
214311fa71b9SJerome Forissier * For DTLS, it is up to the caller to set ssl->next_record_offset when
214411fa71b9SJerome Forissier * they're done reading a record.
214511fa71b9SJerome Forissier */
mbedtls_ssl_fetch_input(mbedtls_ssl_context * ssl,size_t nb_want)214611fa71b9SJerome Forissier int mbedtls_ssl_fetch_input(mbedtls_ssl_context *ssl, size_t nb_want)
214711fa71b9SJerome Forissier {
214811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
214911fa71b9SJerome Forissier size_t len;
215011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
215111fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len;
215211fa71b9SJerome Forissier #else
215311fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
215411fa71b9SJerome Forissier #endif
215511fa71b9SJerome Forissier
215611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> fetch input"));
215711fa71b9SJerome Forissier
215832b31808SJens Wiklander if (ssl->f_recv == NULL && ssl->f_recv_timeout == NULL) {
215932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
216032b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
216111fa71b9SJerome Forissier }
216211fa71b9SJerome Forissier
216332b31808SJens Wiklander if (nb_want > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
216411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("requesting more data than fits"));
216532b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
216611fa71b9SJerome Forissier }
216711fa71b9SJerome Forissier
216811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
216932b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
217011fa71b9SJerome Forissier uint32_t timeout;
217111fa71b9SJerome Forissier
217211fa71b9SJerome Forissier /*
217311fa71b9SJerome Forissier * The point is, we need to always read a full datagram at once, so we
217411fa71b9SJerome Forissier * sometimes read more then requested, and handle the additional data.
217511fa71b9SJerome Forissier * It could be the rest of the current record (while fetching the
217611fa71b9SJerome Forissier * header) and/or some other records in the same datagram.
217711fa71b9SJerome Forissier */
217811fa71b9SJerome Forissier
217911fa71b9SJerome Forissier /*
218011fa71b9SJerome Forissier * Move to the next record in the already read datagram if applicable
218111fa71b9SJerome Forissier */
218232b31808SJens Wiklander if (ssl->next_record_offset != 0) {
218332b31808SJens Wiklander if (ssl->in_left < ssl->next_record_offset) {
218411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
218532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
218611fa71b9SJerome Forissier }
218711fa71b9SJerome Forissier
218811fa71b9SJerome Forissier ssl->in_left -= ssl->next_record_offset;
218911fa71b9SJerome Forissier
219032b31808SJens Wiklander if (ssl->in_left != 0) {
21917901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("next record in same datagram, offset: %"
21927901324dSJerome Forissier MBEDTLS_PRINTF_SIZET,
219311fa71b9SJerome Forissier ssl->next_record_offset));
219411fa71b9SJerome Forissier memmove(ssl->in_hdr,
219511fa71b9SJerome Forissier ssl->in_hdr + ssl->next_record_offset,
219611fa71b9SJerome Forissier ssl->in_left);
219711fa71b9SJerome Forissier }
219811fa71b9SJerome Forissier
219911fa71b9SJerome Forissier ssl->next_record_offset = 0;
220011fa71b9SJerome Forissier }
220111fa71b9SJerome Forissier
22027901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
22037901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET,
220411fa71b9SJerome Forissier ssl->in_left, nb_want));
220511fa71b9SJerome Forissier
220611fa71b9SJerome Forissier /*
220711fa71b9SJerome Forissier * Done if we already have enough data.
220811fa71b9SJerome Forissier */
220932b31808SJens Wiklander if (nb_want <= ssl->in_left) {
221011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
221132b31808SJens Wiklander return 0;
221211fa71b9SJerome Forissier }
221311fa71b9SJerome Forissier
221411fa71b9SJerome Forissier /*
221511fa71b9SJerome Forissier * A record can't be split across datagrams. If we need to read but
221611fa71b9SJerome Forissier * are not at the beginning of a new record, the caller did something
221711fa71b9SJerome Forissier * wrong.
221811fa71b9SJerome Forissier */
221932b31808SJens Wiklander if (ssl->in_left != 0) {
222011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
222132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
222211fa71b9SJerome Forissier }
222311fa71b9SJerome Forissier
222411fa71b9SJerome Forissier /*
222511fa71b9SJerome Forissier * Don't even try to read if time's out already.
222611fa71b9SJerome Forissier * This avoids by-passing the timer when repeatedly receiving messages
222711fa71b9SJerome Forissier * that will end up being dropped.
222811fa71b9SJerome Forissier */
222932b31808SJens Wiklander if (mbedtls_ssl_check_timer(ssl) != 0) {
223011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("timer has expired"));
223111fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT;
223232b31808SJens Wiklander } else {
2233b0563631STom Van Eyck len = in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf);
223411fa71b9SJerome Forissier
223532b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0) {
223611fa71b9SJerome Forissier timeout = ssl->handshake->retransmit_timeout;
223732b31808SJens Wiklander } else {
223811fa71b9SJerome Forissier timeout = ssl->conf->read_timeout;
223932b31808SJens Wiklander }
224011fa71b9SJerome Forissier
22417901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("f_recv_timeout: %lu ms", (unsigned long) timeout));
224211fa71b9SJerome Forissier
224332b31808SJens Wiklander if (ssl->f_recv_timeout != NULL) {
224411fa71b9SJerome Forissier ret = ssl->f_recv_timeout(ssl->p_bio, ssl->in_hdr, len,
224511fa71b9SJerome Forissier timeout);
224632b31808SJens Wiklander } else {
224711fa71b9SJerome Forissier ret = ssl->f_recv(ssl->p_bio, ssl->in_hdr, len);
224832b31808SJens Wiklander }
224911fa71b9SJerome Forissier
225011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
225111fa71b9SJerome Forissier
225232b31808SJens Wiklander if (ret == 0) {
225332b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONN_EOF;
225432b31808SJens Wiklander }
225511fa71b9SJerome Forissier }
225611fa71b9SJerome Forissier
225732b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_TIMEOUT) {
225811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("timeout"));
225911fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0);
226011fa71b9SJerome Forissier
226132b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
226232b31808SJens Wiklander if (ssl_double_retransmit_timeout(ssl) != 0) {
226311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("handshake timeout"));
226432b31808SJens Wiklander return MBEDTLS_ERR_SSL_TIMEOUT;
226511fa71b9SJerome Forissier }
226611fa71b9SJerome Forissier
226732b31808SJens Wiklander if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
226811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
226932b31808SJens Wiklander return ret;
227011fa71b9SJerome Forissier }
227111fa71b9SJerome Forissier
227232b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ;
227311fa71b9SJerome Forissier }
227411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
227511fa71b9SJerome Forissier else if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
227632b31808SJens Wiklander ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
227732b31808SJens Wiklander if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
227811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
227911fa71b9SJerome Forissier ret);
228032b31808SJens Wiklander return ret;
228111fa71b9SJerome Forissier }
228211fa71b9SJerome Forissier
228332b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ;
228411fa71b9SJerome Forissier }
228511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
228611fa71b9SJerome Forissier }
228711fa71b9SJerome Forissier
228832b31808SJens Wiklander if (ret < 0) {
228932b31808SJens Wiklander return ret;
229032b31808SJens Wiklander }
229111fa71b9SJerome Forissier
229211fa71b9SJerome Forissier ssl->in_left = ret;
229332b31808SJens Wiklander } else
229411fa71b9SJerome Forissier #endif
229511fa71b9SJerome Forissier {
22967901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
22977901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET,
229811fa71b9SJerome Forissier ssl->in_left, nb_want));
229911fa71b9SJerome Forissier
230032b31808SJens Wiklander while (ssl->in_left < nb_want) {
230111fa71b9SJerome Forissier len = nb_want - ssl->in_left;
230211fa71b9SJerome Forissier
230332b31808SJens Wiklander if (mbedtls_ssl_check_timer(ssl) != 0) {
230411fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_TIMEOUT;
230532b31808SJens Wiklander } else {
230632b31808SJens Wiklander if (ssl->f_recv_timeout != NULL) {
230711fa71b9SJerome Forissier ret = ssl->f_recv_timeout(ssl->p_bio,
230811fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len,
230911fa71b9SJerome Forissier ssl->conf->read_timeout);
231032b31808SJens Wiklander } else {
231111fa71b9SJerome Forissier ret = ssl->f_recv(ssl->p_bio,
231211fa71b9SJerome Forissier ssl->in_hdr + ssl->in_left, len);
231311fa71b9SJerome Forissier }
231411fa71b9SJerome Forissier }
231511fa71b9SJerome Forissier
23167901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("in_left: %" MBEDTLS_PRINTF_SIZET
23177901324dSJerome Forissier ", nb_want: %" MBEDTLS_PRINTF_SIZET,
231811fa71b9SJerome Forissier ssl->in_left, nb_want));
231911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_recv(_timeout)", ret);
232011fa71b9SJerome Forissier
232132b31808SJens Wiklander if (ret == 0) {
232232b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONN_EOF;
232332b31808SJens Wiklander }
232411fa71b9SJerome Forissier
232532b31808SJens Wiklander if (ret < 0) {
232632b31808SJens Wiklander return ret;
232732b31808SJens Wiklander }
232811fa71b9SJerome Forissier
232932b31808SJens Wiklander if ((size_t) ret > len) {
233011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1,
233132b31808SJens Wiklander ("f_recv returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
233232b31808SJens Wiklander " were requested",
23337901324dSJerome Forissier ret, len));
233432b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
233511fa71b9SJerome Forissier }
233611fa71b9SJerome Forissier
233711fa71b9SJerome Forissier ssl->in_left += ret;
233811fa71b9SJerome Forissier }
233911fa71b9SJerome Forissier }
234011fa71b9SJerome Forissier
234111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= fetch input"));
234211fa71b9SJerome Forissier
234332b31808SJens Wiklander return 0;
234411fa71b9SJerome Forissier }
234511fa71b9SJerome Forissier
234611fa71b9SJerome Forissier /*
234711fa71b9SJerome Forissier * Flush any data not yet written
234811fa71b9SJerome Forissier */
mbedtls_ssl_flush_output(mbedtls_ssl_context * ssl)234911fa71b9SJerome Forissier int mbedtls_ssl_flush_output(mbedtls_ssl_context *ssl)
235011fa71b9SJerome Forissier {
235111fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
235211fa71b9SJerome Forissier unsigned char *buf;
235311fa71b9SJerome Forissier
235411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> flush output"));
235511fa71b9SJerome Forissier
235632b31808SJens Wiklander if (ssl->f_send == NULL) {
235732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Bad usage of mbedtls_ssl_set_bio() "));
235832b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
235911fa71b9SJerome Forissier }
236011fa71b9SJerome Forissier
236111fa71b9SJerome Forissier /* Avoid incrementing counter if data is flushed */
236232b31808SJens Wiklander if (ssl->out_left == 0) {
236311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
236432b31808SJens Wiklander return 0;
236511fa71b9SJerome Forissier }
236611fa71b9SJerome Forissier
236732b31808SJens Wiklander while (ssl->out_left > 0) {
23687901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("message length: %" MBEDTLS_PRINTF_SIZET
23697901324dSJerome Forissier ", out_left: %" MBEDTLS_PRINTF_SIZET,
237011fa71b9SJerome Forissier mbedtls_ssl_out_hdr_len(ssl) + ssl->out_msglen, ssl->out_left));
237111fa71b9SJerome Forissier
237211fa71b9SJerome Forissier buf = ssl->out_hdr - ssl->out_left;
237311fa71b9SJerome Forissier ret = ssl->f_send(ssl->p_bio, buf, ssl->out_left);
237411fa71b9SJerome Forissier
237511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", ret);
237611fa71b9SJerome Forissier
237732b31808SJens Wiklander if (ret <= 0) {
237832b31808SJens Wiklander return ret;
237932b31808SJens Wiklander }
238011fa71b9SJerome Forissier
238132b31808SJens Wiklander if ((size_t) ret > ssl->out_left) {
238211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1,
238332b31808SJens Wiklander ("f_send returned %d bytes but only %" MBEDTLS_PRINTF_SIZET
238432b31808SJens Wiklander " bytes were sent",
23857901324dSJerome Forissier ret, ssl->out_left));
238632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
238711fa71b9SJerome Forissier }
238811fa71b9SJerome Forissier
238911fa71b9SJerome Forissier ssl->out_left -= ret;
239011fa71b9SJerome Forissier }
239111fa71b9SJerome Forissier
239211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
239332b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
239411fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf;
239532b31808SJens Wiklander } else
239611fa71b9SJerome Forissier #endif
239711fa71b9SJerome Forissier {
239811fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf + 8;
239911fa71b9SJerome Forissier }
240011fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
240111fa71b9SJerome Forissier
240211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= flush output"));
240311fa71b9SJerome Forissier
240432b31808SJens Wiklander return 0;
240511fa71b9SJerome Forissier }
240611fa71b9SJerome Forissier
240711fa71b9SJerome Forissier /*
240811fa71b9SJerome Forissier * Functions to handle the DTLS retransmission state machine
240911fa71b9SJerome Forissier */
241011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
241111fa71b9SJerome Forissier /*
241211fa71b9SJerome Forissier * Append current handshake message to current outgoing flight
241311fa71b9SJerome Forissier */
2414039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_flight_append(mbedtls_ssl_context * ssl)241511fa71b9SJerome Forissier static int ssl_flight_append(mbedtls_ssl_context *ssl)
241611fa71b9SJerome Forissier {
241711fa71b9SJerome Forissier mbedtls_ssl_flight_item *msg;
241811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_flight_append"));
241911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "message appended to flight",
242011fa71b9SJerome Forissier ssl->out_msg, ssl->out_msglen);
242111fa71b9SJerome Forissier
242211fa71b9SJerome Forissier /* Allocate space for current message */
242332b31808SJens Wiklander if ((msg = mbedtls_calloc(1, sizeof(mbedtls_ssl_flight_item))) == NULL) {
24247901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
242511fa71b9SJerome Forissier sizeof(mbedtls_ssl_flight_item)));
242632b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED;
242711fa71b9SJerome Forissier }
242811fa71b9SJerome Forissier
242932b31808SJens Wiklander if ((msg->p = mbedtls_calloc(1, ssl->out_msglen)) == NULL) {
24307901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
24317901324dSJerome Forissier ssl->out_msglen));
243211fa71b9SJerome Forissier mbedtls_free(msg);
243332b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED;
243411fa71b9SJerome Forissier }
243511fa71b9SJerome Forissier
243611fa71b9SJerome Forissier /* Copy current handshake message with headers */
243711fa71b9SJerome Forissier memcpy(msg->p, ssl->out_msg, ssl->out_msglen);
243811fa71b9SJerome Forissier msg->len = ssl->out_msglen;
243911fa71b9SJerome Forissier msg->type = ssl->out_msgtype;
244011fa71b9SJerome Forissier msg->next = NULL;
244111fa71b9SJerome Forissier
244211fa71b9SJerome Forissier /* Append to the current flight */
244332b31808SJens Wiklander if (ssl->handshake->flight == NULL) {
244411fa71b9SJerome Forissier ssl->handshake->flight = msg;
244532b31808SJens Wiklander } else {
244611fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
244732b31808SJens Wiklander while (cur->next != NULL) {
244811fa71b9SJerome Forissier cur = cur->next;
244932b31808SJens Wiklander }
245011fa71b9SJerome Forissier cur->next = msg;
245111fa71b9SJerome Forissier }
245211fa71b9SJerome Forissier
245311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_flight_append"));
245432b31808SJens Wiklander return 0;
245511fa71b9SJerome Forissier }
245611fa71b9SJerome Forissier
245711fa71b9SJerome Forissier /*
245811fa71b9SJerome Forissier * Free the current flight of handshake messages
245911fa71b9SJerome Forissier */
mbedtls_ssl_flight_free(mbedtls_ssl_flight_item * flight)246011fa71b9SJerome Forissier void mbedtls_ssl_flight_free(mbedtls_ssl_flight_item *flight)
246111fa71b9SJerome Forissier {
246211fa71b9SJerome Forissier mbedtls_ssl_flight_item *cur = flight;
246311fa71b9SJerome Forissier mbedtls_ssl_flight_item *next;
246411fa71b9SJerome Forissier
246532b31808SJens Wiklander while (cur != NULL) {
246611fa71b9SJerome Forissier next = cur->next;
246711fa71b9SJerome Forissier
246811fa71b9SJerome Forissier mbedtls_free(cur->p);
246911fa71b9SJerome Forissier mbedtls_free(cur);
247011fa71b9SJerome Forissier
247111fa71b9SJerome Forissier cur = next;
247211fa71b9SJerome Forissier }
247311fa71b9SJerome Forissier }
247411fa71b9SJerome Forissier
247511fa71b9SJerome Forissier /*
247611fa71b9SJerome Forissier * Swap transform_out and out_ctr with the alternative ones
247711fa71b9SJerome Forissier */
2478039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_swap_epochs(mbedtls_ssl_context * ssl)247911fa71b9SJerome Forissier static int ssl_swap_epochs(mbedtls_ssl_context *ssl)
248011fa71b9SJerome Forissier {
248111fa71b9SJerome Forissier mbedtls_ssl_transform *tmp_transform;
248232b31808SJens Wiklander unsigned char tmp_out_ctr[MBEDTLS_SSL_SEQUENCE_NUMBER_LEN];
248311fa71b9SJerome Forissier
248432b31808SJens Wiklander if (ssl->transform_out == ssl->handshake->alt_transform_out) {
248511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("skip swap epochs"));
248632b31808SJens Wiklander return 0;
248711fa71b9SJerome Forissier }
248811fa71b9SJerome Forissier
248911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("swap epochs"));
249011fa71b9SJerome Forissier
249111fa71b9SJerome Forissier /* Swap transforms */
249211fa71b9SJerome Forissier tmp_transform = ssl->transform_out;
249311fa71b9SJerome Forissier ssl->transform_out = ssl->handshake->alt_transform_out;
249411fa71b9SJerome Forissier ssl->handshake->alt_transform_out = tmp_transform;
249511fa71b9SJerome Forissier
249611fa71b9SJerome Forissier /* Swap epoch + sequence_number */
249732b31808SJens Wiklander memcpy(tmp_out_ctr, ssl->cur_out_ctr, sizeof(tmp_out_ctr));
249832b31808SJens Wiklander memcpy(ssl->cur_out_ctr, ssl->handshake->alt_out_ctr,
249932b31808SJens Wiklander sizeof(ssl->cur_out_ctr));
250032b31808SJens Wiklander memcpy(ssl->handshake->alt_out_ctr, tmp_out_ctr,
250132b31808SJens Wiklander sizeof(ssl->handshake->alt_out_ctr));
250211fa71b9SJerome Forissier
250311fa71b9SJerome Forissier /* Adjust to the newly activated transform */
250411fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
250511fa71b9SJerome Forissier
250632b31808SJens Wiklander return 0;
250711fa71b9SJerome Forissier }
250811fa71b9SJerome Forissier
250911fa71b9SJerome Forissier /*
251011fa71b9SJerome Forissier * Retransmit the current flight of messages.
251111fa71b9SJerome Forissier */
mbedtls_ssl_resend(mbedtls_ssl_context * ssl)251211fa71b9SJerome Forissier int mbedtls_ssl_resend(mbedtls_ssl_context *ssl)
251311fa71b9SJerome Forissier {
251411fa71b9SJerome Forissier int ret = 0;
251511fa71b9SJerome Forissier
251611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_resend"));
251711fa71b9SJerome Forissier
251811fa71b9SJerome Forissier ret = mbedtls_ssl_flight_transmit(ssl);
251911fa71b9SJerome Forissier
252011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_resend"));
252111fa71b9SJerome Forissier
252232b31808SJens Wiklander return ret;
252311fa71b9SJerome Forissier }
252411fa71b9SJerome Forissier
252511fa71b9SJerome Forissier /*
252611fa71b9SJerome Forissier * Transmit or retransmit the current flight of messages.
252711fa71b9SJerome Forissier *
252811fa71b9SJerome Forissier * Need to remember the current message in case flush_output returns
252911fa71b9SJerome Forissier * WANT_WRITE, causing us to exit this function and come back later.
253011fa71b9SJerome Forissier * This function must be called until state is no longer SENDING.
253111fa71b9SJerome Forissier */
mbedtls_ssl_flight_transmit(mbedtls_ssl_context * ssl)253211fa71b9SJerome Forissier int mbedtls_ssl_flight_transmit(mbedtls_ssl_context *ssl)
253311fa71b9SJerome Forissier {
253411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
253511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_flight_transmit"));
253611fa71b9SJerome Forissier
253732b31808SJens Wiklander if (ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING) {
253811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("initialise flight transmission"));
253911fa71b9SJerome Forissier
254011fa71b9SJerome Forissier ssl->handshake->cur_msg = ssl->handshake->flight;
254111fa71b9SJerome Forissier ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
254211fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl);
254332b31808SJens Wiklander if (ret != 0) {
254432b31808SJens Wiklander return ret;
254532b31808SJens Wiklander }
254611fa71b9SJerome Forissier
254711fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
254811fa71b9SJerome Forissier }
254911fa71b9SJerome Forissier
255032b31808SJens Wiklander while (ssl->handshake->cur_msg != NULL) {
255111fa71b9SJerome Forissier size_t max_frag_len;
255211fa71b9SJerome Forissier const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
255311fa71b9SJerome Forissier
255411fa71b9SJerome Forissier int const is_finished =
255511fa71b9SJerome Forissier (cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
255611fa71b9SJerome Forissier cur->p[0] == MBEDTLS_SSL_HS_FINISHED);
255711fa71b9SJerome Forissier
255832b31808SJens Wiklander int const force_flush = ssl->disable_datagram_packing == 1 ?
255911fa71b9SJerome Forissier SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
256011fa71b9SJerome Forissier
256111fa71b9SJerome Forissier /* Swap epochs before sending Finished: we can't do it after
256211fa71b9SJerome Forissier * sending ChangeCipherSpec, in case write returns WANT_READ.
256311fa71b9SJerome Forissier * Must be done before copying, may change out_msg pointer */
256432b31808SJens Wiklander if (is_finished && ssl->handshake->cur_msg_p == (cur->p + 12)) {
256511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("swap epochs to send finished message"));
256611fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl);
256732b31808SJens Wiklander if (ret != 0) {
256832b31808SJens Wiklander return ret;
256932b31808SJens Wiklander }
257011fa71b9SJerome Forissier }
257111fa71b9SJerome Forissier
257211fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram(ssl);
257332b31808SJens Wiklander if (ret < 0) {
257432b31808SJens Wiklander return ret;
257532b31808SJens Wiklander }
257611fa71b9SJerome Forissier max_frag_len = (size_t) ret;
257711fa71b9SJerome Forissier
257811fa71b9SJerome Forissier /* CCS is copied as is, while HS messages may need fragmentation */
257932b31808SJens Wiklander if (cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
258032b31808SJens Wiklander if (max_frag_len == 0) {
258132b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
258232b31808SJens Wiklander return ret;
258332b31808SJens Wiklander }
258411fa71b9SJerome Forissier
258511fa71b9SJerome Forissier continue;
258611fa71b9SJerome Forissier }
258711fa71b9SJerome Forissier
258811fa71b9SJerome Forissier memcpy(ssl->out_msg, cur->p, cur->len);
258911fa71b9SJerome Forissier ssl->out_msglen = cur->len;
259011fa71b9SJerome Forissier ssl->out_msgtype = cur->type;
259111fa71b9SJerome Forissier
259211fa71b9SJerome Forissier /* Update position inside current message */
259311fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur->len;
259432b31808SJens Wiklander } else {
259511fa71b9SJerome Forissier const unsigned char * const p = ssl->handshake->cur_msg_p;
259611fa71b9SJerome Forissier const size_t hs_len = cur->len - 12;
2597b0563631STom Van Eyck const size_t frag_off = (size_t) (p - (cur->p + 12));
259811fa71b9SJerome Forissier const size_t rem_len = hs_len - frag_off;
259911fa71b9SJerome Forissier size_t cur_hs_frag_len, max_hs_frag_len;
260011fa71b9SJerome Forissier
260132b31808SJens Wiklander if ((max_frag_len < 12) || (max_frag_len == 12 && hs_len != 0)) {
260232b31808SJens Wiklander if (is_finished) {
260311fa71b9SJerome Forissier ret = ssl_swap_epochs(ssl);
260432b31808SJens Wiklander if (ret != 0) {
260532b31808SJens Wiklander return ret;
260632b31808SJens Wiklander }
260711fa71b9SJerome Forissier }
260811fa71b9SJerome Forissier
260932b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
261032b31808SJens Wiklander return ret;
261132b31808SJens Wiklander }
261211fa71b9SJerome Forissier
261311fa71b9SJerome Forissier continue;
261411fa71b9SJerome Forissier }
261511fa71b9SJerome Forissier max_hs_frag_len = max_frag_len - 12;
261611fa71b9SJerome Forissier
261711fa71b9SJerome Forissier cur_hs_frag_len = rem_len > max_hs_frag_len ?
261811fa71b9SJerome Forissier max_hs_frag_len : rem_len;
261911fa71b9SJerome Forissier
262032b31808SJens Wiklander if (frag_off == 0 && cur_hs_frag_len != hs_len) {
262111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("fragmenting handshake message (%u > %u)",
262211fa71b9SJerome Forissier (unsigned) cur_hs_frag_len,
262311fa71b9SJerome Forissier (unsigned) max_hs_frag_len));
262411fa71b9SJerome Forissier }
262511fa71b9SJerome Forissier
262611fa71b9SJerome Forissier /* Messages are stored with handshake headers as if not fragmented,
262711fa71b9SJerome Forissier * copy beginning of headers then fill fragmentation fields.
262811fa71b9SJerome Forissier * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
262911fa71b9SJerome Forissier memcpy(ssl->out_msg, cur->p, 6);
263011fa71b9SJerome Forissier
2631039e02dfSJerome Forissier ssl->out_msg[6] = MBEDTLS_BYTE_2(frag_off);
2632039e02dfSJerome Forissier ssl->out_msg[7] = MBEDTLS_BYTE_1(frag_off);
2633039e02dfSJerome Forissier ssl->out_msg[8] = MBEDTLS_BYTE_0(frag_off);
263411fa71b9SJerome Forissier
2635039e02dfSJerome Forissier ssl->out_msg[9] = MBEDTLS_BYTE_2(cur_hs_frag_len);
2636039e02dfSJerome Forissier ssl->out_msg[10] = MBEDTLS_BYTE_1(cur_hs_frag_len);
2637039e02dfSJerome Forissier ssl->out_msg[11] = MBEDTLS_BYTE_0(cur_hs_frag_len);
263811fa71b9SJerome Forissier
263911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "handshake header", ssl->out_msg, 12);
264011fa71b9SJerome Forissier
264111fa71b9SJerome Forissier /* Copy the handshake message content and set records fields */
264211fa71b9SJerome Forissier memcpy(ssl->out_msg + 12, p, cur_hs_frag_len);
264311fa71b9SJerome Forissier ssl->out_msglen = cur_hs_frag_len + 12;
264411fa71b9SJerome Forissier ssl->out_msgtype = cur->type;
264511fa71b9SJerome Forissier
264611fa71b9SJerome Forissier /* Update position inside current message */
264711fa71b9SJerome Forissier ssl->handshake->cur_msg_p += cur_hs_frag_len;
264811fa71b9SJerome Forissier }
264911fa71b9SJerome Forissier
265011fa71b9SJerome Forissier /* If done with the current message move to the next one if any */
265132b31808SJens Wiklander if (ssl->handshake->cur_msg_p >= cur->p + cur->len) {
265232b31808SJens Wiklander if (cur->next != NULL) {
265311fa71b9SJerome Forissier ssl->handshake->cur_msg = cur->next;
265411fa71b9SJerome Forissier ssl->handshake->cur_msg_p = cur->next->p + 12;
265532b31808SJens Wiklander } else {
265611fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL;
265711fa71b9SJerome Forissier ssl->handshake->cur_msg_p = NULL;
265811fa71b9SJerome Forissier }
265911fa71b9SJerome Forissier }
266011fa71b9SJerome Forissier
266111fa71b9SJerome Forissier /* Actually send the message out */
266232b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
266311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
266432b31808SJens Wiklander return ret;
266511fa71b9SJerome Forissier }
266611fa71b9SJerome Forissier }
266711fa71b9SJerome Forissier
266832b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
266932b31808SJens Wiklander return ret;
267032b31808SJens Wiklander }
267111fa71b9SJerome Forissier
267211fa71b9SJerome Forissier /* Update state and set timer */
267332b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
267411fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
267532b31808SJens Wiklander } else {
267611fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
267711fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
267811fa71b9SJerome Forissier }
267911fa71b9SJerome Forissier
268011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_flight_transmit"));
268111fa71b9SJerome Forissier
268232b31808SJens Wiklander return 0;
268311fa71b9SJerome Forissier }
268411fa71b9SJerome Forissier
268511fa71b9SJerome Forissier /*
268611fa71b9SJerome Forissier * To be called when the last message of an incoming flight is received.
268711fa71b9SJerome Forissier */
mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context * ssl)268811fa71b9SJerome Forissier void mbedtls_ssl_recv_flight_completed(mbedtls_ssl_context *ssl)
268911fa71b9SJerome Forissier {
269011fa71b9SJerome Forissier /* We won't need to resend that one any more */
269111fa71b9SJerome Forissier mbedtls_ssl_flight_free(ssl->handshake->flight);
269211fa71b9SJerome Forissier ssl->handshake->flight = NULL;
269311fa71b9SJerome Forissier ssl->handshake->cur_msg = NULL;
269411fa71b9SJerome Forissier
269511fa71b9SJerome Forissier /* The next incoming flight will start with this msg_seq */
269611fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
269711fa71b9SJerome Forissier
269811fa71b9SJerome Forissier /* We don't want to remember CCS's across flight boundaries. */
269911fa71b9SJerome Forissier ssl->handshake->buffering.seen_ccs = 0;
270011fa71b9SJerome Forissier
270111fa71b9SJerome Forissier /* Clear future message buffering structure. */
270211fa71b9SJerome Forissier mbedtls_ssl_buffering_free(ssl);
270311fa71b9SJerome Forissier
270411fa71b9SJerome Forissier /* Cancel timer */
270511fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0);
270611fa71b9SJerome Forissier
270711fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
270832b31808SJens Wiklander ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
270911fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
271032b31808SJens Wiklander } else {
271111fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
271211fa71b9SJerome Forissier }
271332b31808SJens Wiklander }
271411fa71b9SJerome Forissier
271511fa71b9SJerome Forissier /*
271611fa71b9SJerome Forissier * To be called when the last message of an outgoing flight is send.
271711fa71b9SJerome Forissier */
mbedtls_ssl_send_flight_completed(mbedtls_ssl_context * ssl)271811fa71b9SJerome Forissier void mbedtls_ssl_send_flight_completed(mbedtls_ssl_context *ssl)
271911fa71b9SJerome Forissier {
272011fa71b9SJerome Forissier ssl_reset_retransmit_timeout(ssl);
272111fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->handshake->retransmit_timeout);
272211fa71b9SJerome Forissier
272311fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
272432b31808SJens Wiklander ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED) {
272511fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
272632b31808SJens Wiklander } else {
272711fa71b9SJerome Forissier ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
272811fa71b9SJerome Forissier }
272932b31808SJens Wiklander }
273011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
273111fa71b9SJerome Forissier
273211fa71b9SJerome Forissier /*
273311fa71b9SJerome Forissier * Handshake layer functions
273411fa71b9SJerome Forissier */
mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context * ssl,unsigned char hs_type,unsigned char ** buf,size_t * buf_len)2735b0563631STom Van Eyck int mbedtls_ssl_start_handshake_msg(mbedtls_ssl_context *ssl, unsigned char hs_type,
273632b31808SJens Wiklander unsigned char **buf, size_t *buf_len)
273732b31808SJens Wiklander {
273832b31808SJens Wiklander /*
273932b31808SJens Wiklander * Reserve 4 bytes for handshake header. ( Section 4,RFC 8446 )
274032b31808SJens Wiklander * ...
274132b31808SJens Wiklander * HandshakeType msg_type;
274232b31808SJens Wiklander * uint24 length;
274332b31808SJens Wiklander * ...
274432b31808SJens Wiklander */
274532b31808SJens Wiklander *buf = ssl->out_msg + 4;
274632b31808SJens Wiklander *buf_len = MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
274732b31808SJens Wiklander
274832b31808SJens Wiklander ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
274932b31808SJens Wiklander ssl->out_msg[0] = hs_type;
275032b31808SJens Wiklander
275132b31808SJens Wiklander return 0;
275232b31808SJens Wiklander }
275311fa71b9SJerome Forissier
275411fa71b9SJerome Forissier /*
275511fa71b9SJerome Forissier * Write (DTLS: or queue) current handshake (including CCS) message.
275611fa71b9SJerome Forissier *
275711fa71b9SJerome Forissier * - fill in handshake headers
275811fa71b9SJerome Forissier * - update handshake checksum
275911fa71b9SJerome Forissier * - DTLS: save message for resending
276011fa71b9SJerome Forissier * - then pass to the record layer
276111fa71b9SJerome Forissier *
276211fa71b9SJerome Forissier * DTLS: except for HelloRequest, messages are only queued, and will only be
276311fa71b9SJerome Forissier * actually sent when calling flight_transmit() or resend().
276411fa71b9SJerome Forissier *
276511fa71b9SJerome Forissier * Inputs:
276611fa71b9SJerome Forissier * - ssl->out_msglen: 4 + actual handshake message len
276711fa71b9SJerome Forissier * (4 is the size of handshake headers for TLS)
276811fa71b9SJerome Forissier * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
276911fa71b9SJerome Forissier * - ssl->out_msg + 4: the handshake message body
277011fa71b9SJerome Forissier *
277111fa71b9SJerome Forissier * Outputs, ie state before passing to flight_append() or write_record():
277211fa71b9SJerome Forissier * - ssl->out_msglen: the length of the record contents
277311fa71b9SJerome Forissier * (including handshake headers but excluding record headers)
277411fa71b9SJerome Forissier * - ssl->out_msg: the record contents (handshake headers + content)
277511fa71b9SJerome Forissier */
mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context * ssl,int update_checksum,int force_flush)277632b31808SJens Wiklander int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl,
277732b31808SJens Wiklander int update_checksum,
277832b31808SJens Wiklander int force_flush)
277911fa71b9SJerome Forissier {
278011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
278111fa71b9SJerome Forissier const size_t hs_len = ssl->out_msglen - 4;
278211fa71b9SJerome Forissier const unsigned char hs_type = ssl->out_msg[0];
278311fa71b9SJerome Forissier
278411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write handshake message"));
278511fa71b9SJerome Forissier
278611fa71b9SJerome Forissier /*
278711fa71b9SJerome Forissier * Sanity checks
278811fa71b9SJerome Forissier */
278911fa71b9SJerome Forissier if (ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
279032b31808SJens Wiklander ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
279111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
279232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
279311fa71b9SJerome Forissier }
279411fa71b9SJerome Forissier
279511fa71b9SJerome Forissier /* Whenever we send anything different from a
279611fa71b9SJerome Forissier * HelloRequest we should be in a handshake - double check. */
279711fa71b9SJerome Forissier if (!(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
279811fa71b9SJerome Forissier hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST) &&
279932b31808SJens Wiklander ssl->handshake == NULL) {
280011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
280132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
280211fa71b9SJerome Forissier }
280311fa71b9SJerome Forissier
280411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
280511fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
280611fa71b9SJerome Forissier ssl->handshake != NULL &&
280732b31808SJens Wiklander ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
280811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
280932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
281011fa71b9SJerome Forissier }
281111fa71b9SJerome Forissier #endif
281211fa71b9SJerome Forissier
281311fa71b9SJerome Forissier /* Double-check that we did not exceed the bounds
281411fa71b9SJerome Forissier * of the outgoing record buffer.
281511fa71b9SJerome Forissier * This should never fail as the various message
281611fa71b9SJerome Forissier * writing functions must obey the bounds of the
281711fa71b9SJerome Forissier * outgoing record buffer, but better be safe.
281811fa71b9SJerome Forissier *
281911fa71b9SJerome Forissier * Note: We deliberately do not check for the MTU or MFL here.
282011fa71b9SJerome Forissier */
282132b31808SJens Wiklander if (ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN) {
282211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Record too large: "
28237901324dSJerome Forissier "size %" MBEDTLS_PRINTF_SIZET
28247901324dSJerome Forissier ", maximum %" MBEDTLS_PRINTF_SIZET,
28257901324dSJerome Forissier ssl->out_msglen,
28267901324dSJerome Forissier (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN));
282732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
282811fa71b9SJerome Forissier }
282911fa71b9SJerome Forissier
283011fa71b9SJerome Forissier /*
283111fa71b9SJerome Forissier * Fill handshake headers
283211fa71b9SJerome Forissier */
283332b31808SJens Wiklander if (ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
2834039e02dfSJerome Forissier ssl->out_msg[1] = MBEDTLS_BYTE_2(hs_len);
2835039e02dfSJerome Forissier ssl->out_msg[2] = MBEDTLS_BYTE_1(hs_len);
2836039e02dfSJerome Forissier ssl->out_msg[3] = MBEDTLS_BYTE_0(hs_len);
283711fa71b9SJerome Forissier
283811fa71b9SJerome Forissier /*
283911fa71b9SJerome Forissier * DTLS has additional fields in the Handshake layer,
284011fa71b9SJerome Forissier * between the length field and the actual payload:
284111fa71b9SJerome Forissier * uint16 message_seq;
284211fa71b9SJerome Forissier * uint24 fragment_offset;
284311fa71b9SJerome Forissier * uint24 fragment_length;
284411fa71b9SJerome Forissier */
284511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
284632b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
284711fa71b9SJerome Forissier /* Make room for the additional DTLS fields */
284832b31808SJens Wiklander if (MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8) {
284911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS handshake message too large: "
285032b31808SJens Wiklander "size %" MBEDTLS_PRINTF_SIZET ", maximum %"
285132b31808SJens Wiklander MBEDTLS_PRINTF_SIZET,
28527901324dSJerome Forissier hs_len,
28537901324dSJerome Forissier (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN - 12)));
285432b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
285511fa71b9SJerome Forissier }
285611fa71b9SJerome Forissier
285711fa71b9SJerome Forissier memmove(ssl->out_msg + 12, ssl->out_msg + 4, hs_len);
285811fa71b9SJerome Forissier ssl->out_msglen += 8;
285911fa71b9SJerome Forissier
286011fa71b9SJerome Forissier /* Write message_seq and update it, except for HelloRequest */
286132b31808SJens Wiklander if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST) {
2862039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(ssl->handshake->out_msg_seq, ssl->out_msg, 4);
286311fa71b9SJerome Forissier ++(ssl->handshake->out_msg_seq);
286432b31808SJens Wiklander } else {
286511fa71b9SJerome Forissier ssl->out_msg[4] = 0;
286611fa71b9SJerome Forissier ssl->out_msg[5] = 0;
286711fa71b9SJerome Forissier }
286811fa71b9SJerome Forissier
286911fa71b9SJerome Forissier /* Handshake hashes are computed without fragmentation,
287011fa71b9SJerome Forissier * so set frag_offset = 0 and frag_len = hs_len for now */
287111fa71b9SJerome Forissier memset(ssl->out_msg + 6, 0x00, 3);
287211fa71b9SJerome Forissier memcpy(ssl->out_msg + 9, ssl->out_msg + 1, 3);
287311fa71b9SJerome Forissier }
287411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
287511fa71b9SJerome Forissier
287611fa71b9SJerome Forissier /* Update running hashes of handshake messages seen */
287732b31808SJens Wiklander if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) {
287832b31808SJens Wiklander ret = ssl->handshake->update_checksum(ssl, ssl->out_msg,
287932b31808SJens Wiklander ssl->out_msglen);
288032b31808SJens Wiklander if (ret != 0) {
288132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
288232b31808SJens Wiklander return ret;
288332b31808SJens Wiklander }
288432b31808SJens Wiklander }
288511fa71b9SJerome Forissier }
288611fa71b9SJerome Forissier
288711fa71b9SJerome Forissier /* Either send now, or just save to be sent (and resent) later */
288811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
288911fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
289011fa71b9SJerome Forissier !(ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
289132b31808SJens Wiklander hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST)) {
289232b31808SJens Wiklander if ((ret = ssl_flight_append(ssl)) != 0) {
289311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_flight_append", ret);
289432b31808SJens Wiklander return ret;
289511fa71b9SJerome Forissier }
289632b31808SJens Wiklander } else
289711fa71b9SJerome Forissier #endif
289811fa71b9SJerome Forissier {
289932b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, force_flush)) != 0) {
290011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_record", ret);
290132b31808SJens Wiklander return ret;
290211fa71b9SJerome Forissier }
290311fa71b9SJerome Forissier }
290411fa71b9SJerome Forissier
290511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write handshake message"));
290611fa71b9SJerome Forissier
290732b31808SJens Wiklander return 0;
290832b31808SJens Wiklander }
290932b31808SJens Wiklander
mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context * ssl,size_t buf_len,size_t msg_len)291032b31808SJens Wiklander int mbedtls_ssl_finish_handshake_msg(mbedtls_ssl_context *ssl,
291132b31808SJens Wiklander size_t buf_len, size_t msg_len)
291232b31808SJens Wiklander {
291332b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
291432b31808SJens Wiklander size_t msg_with_header_len;
291532b31808SJens Wiklander ((void) buf_len);
291632b31808SJens Wiklander
291732b31808SJens Wiklander /* Add reserved 4 bytes for handshake header */
291832b31808SJens Wiklander msg_with_header_len = msg_len + 4;
291932b31808SJens Wiklander ssl->out_msglen = msg_with_header_len;
292032b31808SJens Wiklander MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_write_handshake_msg_ext(ssl, 0, 0));
292132b31808SJens Wiklander
292232b31808SJens Wiklander cleanup:
292332b31808SJens Wiklander return ret;
292411fa71b9SJerome Forissier }
292511fa71b9SJerome Forissier
292611fa71b9SJerome Forissier /*
292711fa71b9SJerome Forissier * Record layer functions
292811fa71b9SJerome Forissier */
292911fa71b9SJerome Forissier
293011fa71b9SJerome Forissier /*
293111fa71b9SJerome Forissier * Write current record.
293211fa71b9SJerome Forissier *
293311fa71b9SJerome Forissier * Uses:
293411fa71b9SJerome Forissier * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
293511fa71b9SJerome Forissier * - ssl->out_msglen: length of the record content (excl headers)
293611fa71b9SJerome Forissier * - ssl->out_msg: record content
293711fa71b9SJerome Forissier */
mbedtls_ssl_write_record(mbedtls_ssl_context * ssl,int force_flush)293832b31808SJens Wiklander int mbedtls_ssl_write_record(mbedtls_ssl_context *ssl, int force_flush)
293911fa71b9SJerome Forissier {
294011fa71b9SJerome Forissier int ret, done = 0;
294111fa71b9SJerome Forissier size_t len = ssl->out_msglen;
294232b31808SJens Wiklander int flush = force_flush;
294311fa71b9SJerome Forissier
294411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write record"));
294511fa71b9SJerome Forissier
294632b31808SJens Wiklander if (!done) {
294711fa71b9SJerome Forissier unsigned i;
294811fa71b9SJerome Forissier size_t protected_record_size;
294911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
295011fa71b9SJerome Forissier size_t out_buf_len = ssl->out_buf_len;
295111fa71b9SJerome Forissier #else
295211fa71b9SJerome Forissier size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
295311fa71b9SJerome Forissier #endif
295411fa71b9SJerome Forissier /* Skip writing the record content type to after the encryption,
295511fa71b9SJerome Forissier * as it may change when using the CID extension. */
295632b31808SJens Wiklander mbedtls_ssl_protocol_version tls_ver = ssl->tls_version;
295732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
295832b31808SJens Wiklander /* TLS 1.3 still uses the TLS 1.2 version identifier
295932b31808SJens Wiklander * for backwards compatibility. */
296032b31808SJens Wiklander if (tls_ver == MBEDTLS_SSL_VERSION_TLS1_3) {
296132b31808SJens Wiklander tls_ver = MBEDTLS_SSL_VERSION_TLS1_2;
296232b31808SJens Wiklander }
296332b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
296432b31808SJens Wiklander mbedtls_ssl_write_version(ssl->out_hdr + 1, ssl->conf->transport,
296532b31808SJens Wiklander tls_ver);
296611fa71b9SJerome Forissier
296732b31808SJens Wiklander memcpy(ssl->out_ctr, ssl->cur_out_ctr, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
2968039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(len, ssl->out_len, 0);
296911fa71b9SJerome Forissier
297032b31808SJens Wiklander if (ssl->transform_out != NULL) {
297111fa71b9SJerome Forissier mbedtls_record rec;
297211fa71b9SJerome Forissier
297311fa71b9SJerome Forissier rec.buf = ssl->out_iv;
2974b0563631STom Van Eyck rec.buf_len = out_buf_len - (size_t) (ssl->out_iv - ssl->out_buf);
297511fa71b9SJerome Forissier rec.data_len = ssl->out_msglen;
2976b0563631STom Van Eyck rec.data_offset = (size_t) (ssl->out_msg - rec.buf);
297711fa71b9SJerome Forissier
297832b31808SJens Wiklander memcpy(&rec.ctr[0], ssl->out_ctr, sizeof(rec.ctr));
297932b31808SJens Wiklander mbedtls_ssl_write_version(rec.ver, ssl->conf->transport, tls_ver);
298011fa71b9SJerome Forissier rec.type = ssl->out_msgtype;
298111fa71b9SJerome Forissier
298211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
298311fa71b9SJerome Forissier /* The CID is set by mbedtls_ssl_encrypt_buf(). */
298411fa71b9SJerome Forissier rec.cid_len = 0;
298511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
298611fa71b9SJerome Forissier
298711fa71b9SJerome Forissier if ((ret = mbedtls_ssl_encrypt_buf(ssl, ssl->transform_out, &rec,
298832b31808SJens Wiklander ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
298911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_encrypt_buf", ret);
299032b31808SJens Wiklander return ret;
299111fa71b9SJerome Forissier }
299211fa71b9SJerome Forissier
299332b31808SJens Wiklander if (rec.data_offset != 0) {
299411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
299532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
299611fa71b9SJerome Forissier }
299711fa71b9SJerome Forissier
299811fa71b9SJerome Forissier /* Update the record content type and CID. */
299911fa71b9SJerome Forissier ssl->out_msgtype = rec.type;
300011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
300111fa71b9SJerome Forissier memcpy(ssl->out_cid, rec.cid, rec.cid_len);
300211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
300311fa71b9SJerome Forissier ssl->out_msglen = len = rec.data_len;
3004039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->out_len, 0);
300511fa71b9SJerome Forissier }
300611fa71b9SJerome Forissier
300711fa71b9SJerome Forissier protected_record_size = len + mbedtls_ssl_out_hdr_len(ssl);
300811fa71b9SJerome Forissier
300911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
301011fa71b9SJerome Forissier /* In case of DTLS, double-check that we don't exceed
301111fa71b9SJerome Forissier * the remaining space in the datagram. */
301232b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
301311fa71b9SJerome Forissier ret = ssl_get_remaining_space_in_datagram(ssl);
301432b31808SJens Wiklander if (ret < 0) {
301532b31808SJens Wiklander return ret;
301632b31808SJens Wiklander }
301711fa71b9SJerome Forissier
301832b31808SJens Wiklander if (protected_record_size > (size_t) ret) {
301911fa71b9SJerome Forissier /* Should never happen */
302032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
302111fa71b9SJerome Forissier }
302211fa71b9SJerome Forissier }
302311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
302411fa71b9SJerome Forissier
302511fa71b9SJerome Forissier /* Now write the potentially updated record content type. */
302611fa71b9SJerome Forissier ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
302711fa71b9SJerome Forissier
30287901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("output record: msgtype = %u, "
30297901324dSJerome Forissier "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
303011fa71b9SJerome Forissier ssl->out_hdr[0], ssl->out_hdr[1],
303111fa71b9SJerome Forissier ssl->out_hdr[2], len));
303211fa71b9SJerome Forissier
303311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
303411fa71b9SJerome Forissier ssl->out_hdr, protected_record_size);
303511fa71b9SJerome Forissier
303611fa71b9SJerome Forissier ssl->out_left += protected_record_size;
303711fa71b9SJerome Forissier ssl->out_hdr += protected_record_size;
303811fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, ssl->transform_out);
303911fa71b9SJerome Forissier
304032b31808SJens Wiklander for (i = 8; i > mbedtls_ssl_ep_len(ssl); i--) {
304132b31808SJens Wiklander if (++ssl->cur_out_ctr[i - 1] != 0) {
304211fa71b9SJerome Forissier break;
304332b31808SJens Wiklander }
304432b31808SJens Wiklander }
304511fa71b9SJerome Forissier
304632b31808SJens Wiklander /* The loop goes to its end if the counter is wrapping */
304732b31808SJens Wiklander if (i == mbedtls_ssl_ep_len(ssl)) {
304811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("outgoing message counter would wrap"));
304932b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
305011fa71b9SJerome Forissier }
305111fa71b9SJerome Forissier }
305211fa71b9SJerome Forissier
305311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
305411fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
305532b31808SJens Wiklander flush == SSL_DONT_FORCE_FLUSH) {
305611fa71b9SJerome Forissier size_t remaining;
305711fa71b9SJerome Forissier ret = ssl_get_remaining_payload_in_datagram(ssl);
305832b31808SJens Wiklander if (ret < 0) {
305911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_remaining_payload_in_datagram",
306011fa71b9SJerome Forissier ret);
306132b31808SJens Wiklander return ret;
306211fa71b9SJerome Forissier }
306311fa71b9SJerome Forissier
306411fa71b9SJerome Forissier remaining = (size_t) ret;
306532b31808SJens Wiklander if (remaining == 0) {
306611fa71b9SJerome Forissier flush = SSL_FORCE_FLUSH;
306732b31808SJens Wiklander } else {
306832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
306932b31808SJens Wiklander ("Still %u bytes available in current datagram",
307032b31808SJens Wiklander (unsigned) remaining));
307111fa71b9SJerome Forissier }
307211fa71b9SJerome Forissier }
307311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
307411fa71b9SJerome Forissier
307511fa71b9SJerome Forissier if ((flush == SSL_FORCE_FLUSH) &&
307632b31808SJens Wiklander (ret = mbedtls_ssl_flush_output(ssl)) != 0) {
307711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
307832b31808SJens Wiklander return ret;
307911fa71b9SJerome Forissier }
308011fa71b9SJerome Forissier
308111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write record"));
308211fa71b9SJerome Forissier
308332b31808SJens Wiklander return 0;
308411fa71b9SJerome Forissier }
308511fa71b9SJerome Forissier
308611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
308711fa71b9SJerome Forissier
3088039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_hs_is_proper_fragment(mbedtls_ssl_context * ssl)308911fa71b9SJerome Forissier static int ssl_hs_is_proper_fragment(mbedtls_ssl_context *ssl)
309011fa71b9SJerome Forissier {
309111fa71b9SJerome Forissier if (ssl->in_msglen < ssl->in_hslen ||
309211fa71b9SJerome Forissier memcmp(ssl->in_msg + 6, "\0\0\0", 3) != 0 ||
309332b31808SJens Wiklander memcmp(ssl->in_msg + 9, ssl->in_msg + 1, 3) != 0) {
309432b31808SJens Wiklander return 1;
309511fa71b9SJerome Forissier }
309632b31808SJens Wiklander return 0;
309711fa71b9SJerome Forissier }
309811fa71b9SJerome Forissier
ssl_get_hs_frag_len(mbedtls_ssl_context const * ssl)309911fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_len(mbedtls_ssl_context const *ssl)
310011fa71b9SJerome Forissier {
3101b0563631STom Van Eyck return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
310211fa71b9SJerome Forissier }
310311fa71b9SJerome Forissier
ssl_get_hs_frag_off(mbedtls_ssl_context const * ssl)310411fa71b9SJerome Forissier static uint32_t ssl_get_hs_frag_off(mbedtls_ssl_context const *ssl)
310511fa71b9SJerome Forissier {
3106b0563631STom Van Eyck return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
310711fa71b9SJerome Forissier }
310811fa71b9SJerome Forissier
3109039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_check_hs_header(mbedtls_ssl_context const * ssl)311011fa71b9SJerome Forissier static int ssl_check_hs_header(mbedtls_ssl_context const *ssl)
311111fa71b9SJerome Forissier {
311211fa71b9SJerome Forissier uint32_t msg_len, frag_off, frag_len;
311311fa71b9SJerome Forissier
311411fa71b9SJerome Forissier msg_len = ssl_get_hs_total_len(ssl);
311511fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off(ssl);
311611fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len(ssl);
311711fa71b9SJerome Forissier
311832b31808SJens Wiklander if (frag_off > msg_len) {
311932b31808SJens Wiklander return -1;
312032b31808SJens Wiklander }
312111fa71b9SJerome Forissier
312232b31808SJens Wiklander if (frag_len > msg_len - frag_off) {
312332b31808SJens Wiklander return -1;
312432b31808SJens Wiklander }
312511fa71b9SJerome Forissier
312632b31808SJens Wiklander if (frag_len + 12 > ssl->in_msglen) {
312732b31808SJens Wiklander return -1;
312832b31808SJens Wiklander }
312911fa71b9SJerome Forissier
313032b31808SJens Wiklander return 0;
313111fa71b9SJerome Forissier }
313211fa71b9SJerome Forissier
313311fa71b9SJerome Forissier /*
313411fa71b9SJerome Forissier * Mark bits in bitmask (used for DTLS HS reassembly)
313511fa71b9SJerome Forissier */
ssl_bitmask_set(unsigned char * mask,size_t offset,size_t len)313611fa71b9SJerome Forissier static void ssl_bitmask_set(unsigned char *mask, size_t offset, size_t len)
313711fa71b9SJerome Forissier {
313811fa71b9SJerome Forissier unsigned int start_bits, end_bits;
313911fa71b9SJerome Forissier
314011fa71b9SJerome Forissier start_bits = 8 - (offset % 8);
314132b31808SJens Wiklander if (start_bits != 8) {
314211fa71b9SJerome Forissier size_t first_byte_idx = offset / 8;
314311fa71b9SJerome Forissier
314411fa71b9SJerome Forissier /* Special case */
314532b31808SJens Wiklander if (len <= start_bits) {
314632b31808SJens Wiklander for (; len != 0; len--) {
314711fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << (start_bits - len);
314832b31808SJens Wiklander }
314911fa71b9SJerome Forissier
315011fa71b9SJerome Forissier /* Avoid potential issues with offset or len becoming invalid */
315111fa71b9SJerome Forissier return;
315211fa71b9SJerome Forissier }
315311fa71b9SJerome Forissier
315411fa71b9SJerome Forissier offset += start_bits; /* Now offset % 8 == 0 */
315511fa71b9SJerome Forissier len -= start_bits;
315611fa71b9SJerome Forissier
315732b31808SJens Wiklander for (; start_bits != 0; start_bits--) {
315811fa71b9SJerome Forissier mask[first_byte_idx] |= 1 << (start_bits - 1);
315911fa71b9SJerome Forissier }
316032b31808SJens Wiklander }
316111fa71b9SJerome Forissier
316211fa71b9SJerome Forissier end_bits = len % 8;
316332b31808SJens Wiklander if (end_bits != 0) {
316411fa71b9SJerome Forissier size_t last_byte_idx = (offset + len) / 8;
316511fa71b9SJerome Forissier
316611fa71b9SJerome Forissier len -= end_bits; /* Now len % 8 == 0 */
316711fa71b9SJerome Forissier
316832b31808SJens Wiklander for (; end_bits != 0; end_bits--) {
316911fa71b9SJerome Forissier mask[last_byte_idx] |= 1 << (8 - end_bits);
317011fa71b9SJerome Forissier }
317132b31808SJens Wiklander }
317211fa71b9SJerome Forissier
317311fa71b9SJerome Forissier memset(mask + offset / 8, 0xFF, len / 8);
317411fa71b9SJerome Forissier }
317511fa71b9SJerome Forissier
317611fa71b9SJerome Forissier /*
317711fa71b9SJerome Forissier * Check that bitmask is full
317811fa71b9SJerome Forissier */
3179039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_bitmask_check(unsigned char * mask,size_t len)318011fa71b9SJerome Forissier static int ssl_bitmask_check(unsigned char *mask, size_t len)
318111fa71b9SJerome Forissier {
318211fa71b9SJerome Forissier size_t i;
318311fa71b9SJerome Forissier
318432b31808SJens Wiklander for (i = 0; i < len / 8; i++) {
318532b31808SJens Wiklander if (mask[i] != 0xFF) {
318632b31808SJens Wiklander return -1;
318732b31808SJens Wiklander }
318832b31808SJens Wiklander }
318911fa71b9SJerome Forissier
319032b31808SJens Wiklander for (i = 0; i < len % 8; i++) {
319132b31808SJens Wiklander if ((mask[len / 8] & (1 << (7 - i))) == 0) {
319232b31808SJens Wiklander return -1;
319332b31808SJens Wiklander }
319432b31808SJens Wiklander }
319511fa71b9SJerome Forissier
319632b31808SJens Wiklander return 0;
319711fa71b9SJerome Forissier }
319811fa71b9SJerome Forissier
319911fa71b9SJerome Forissier /* msg_len does not include the handshake header */
ssl_get_reassembly_buffer_size(size_t msg_len,unsigned add_bitmap)320011fa71b9SJerome Forissier static size_t ssl_get_reassembly_buffer_size(size_t msg_len,
320111fa71b9SJerome Forissier unsigned add_bitmap)
320211fa71b9SJerome Forissier {
320311fa71b9SJerome Forissier size_t alloc_len;
320411fa71b9SJerome Forissier
320511fa71b9SJerome Forissier alloc_len = 12; /* Handshake header */
320611fa71b9SJerome Forissier alloc_len += msg_len; /* Content buffer */
320711fa71b9SJerome Forissier
320832b31808SJens Wiklander if (add_bitmap) {
320911fa71b9SJerome Forissier alloc_len += msg_len / 8 + (msg_len % 8 != 0); /* Bitmap */
321011fa71b9SJerome Forissier
321132b31808SJens Wiklander }
321232b31808SJens Wiklander return alloc_len;
321311fa71b9SJerome Forissier }
321411fa71b9SJerome Forissier
321511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
321611fa71b9SJerome Forissier
ssl_get_hs_total_len(mbedtls_ssl_context const * ssl)321711fa71b9SJerome Forissier static uint32_t ssl_get_hs_total_len(mbedtls_ssl_context const *ssl)
321811fa71b9SJerome Forissier {
3219b0563631STom Van Eyck return MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
322011fa71b9SJerome Forissier }
322111fa71b9SJerome Forissier
mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context * ssl)322211fa71b9SJerome Forissier int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl)
322311fa71b9SJerome Forissier {
3224c3deb3d6SEtienne Carriere if (ssl->badmac_seen_or_in_hsfraglen == 0) {
3225c3deb3d6SEtienne Carriere /* The handshake message must at least include the header.
3226c3deb3d6SEtienne Carriere * We may not have the full message yet in case of fragmentation.
3227c3deb3d6SEtienne Carriere * To simplify the code, we insist on having the header (and in
3228c3deb3d6SEtienne Carriere * particular the handshake message length) in the first
3229c3deb3d6SEtienne Carriere * fragment. */
323032b31808SJens Wiklander if (ssl->in_msglen < mbedtls_ssl_hs_hdr_len(ssl)) {
32317901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("handshake message too short: %" MBEDTLS_PRINTF_SIZET,
323211fa71b9SJerome Forissier ssl->in_msglen));
323332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
323411fa71b9SJerome Forissier }
323511fa71b9SJerome Forissier
323611fa71b9SJerome Forissier ssl->in_hslen = mbedtls_ssl_hs_hdr_len(ssl) + ssl_get_hs_total_len(ssl);
3237c3deb3d6SEtienne Carriere }
323811fa71b9SJerome Forissier
323911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("handshake message: msglen ="
324032b31808SJens Wiklander " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %"
324132b31808SJens Wiklander MBEDTLS_PRINTF_SIZET,
324211fa71b9SJerome Forissier ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen));
324311fa71b9SJerome Forissier
3244c3deb3d6SEtienne Carriere if (ssl->transform_in != NULL) {
3245c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(4, ("decrypted handshake message:"
3246c3deb3d6SEtienne Carriere " iv-buf=%d hdr-buf=%d hdr-buf=%d",
3247c3deb3d6SEtienne Carriere (int) (ssl->in_iv - ssl->in_buf),
3248c3deb3d6SEtienne Carriere (int) (ssl->in_hdr - ssl->in_buf),
3249c3deb3d6SEtienne Carriere (int) (ssl->in_msg - ssl->in_buf)));
3250c3deb3d6SEtienne Carriere }
3251c3deb3d6SEtienne Carriere
325211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
325332b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
325411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3255b0563631STom Van Eyck unsigned int recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
325611fa71b9SJerome Forissier
325732b31808SJens Wiklander if (ssl_check_hs_header(ssl) != 0) {
325811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid handshake header"));
325932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
326011fa71b9SJerome Forissier }
326111fa71b9SJerome Forissier
326211fa71b9SJerome Forissier if (ssl->handshake != NULL &&
326332b31808SJens Wiklander ((mbedtls_ssl_is_handshake_over(ssl) == 0 &&
326411fa71b9SJerome Forissier recv_msg_seq != ssl->handshake->in_msg_seq) ||
326532b31808SJens Wiklander (mbedtls_ssl_is_handshake_over(ssl) == 1 &&
326632b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO))) {
326732b31808SJens Wiklander if (recv_msg_seq > ssl->handshake->in_msg_seq) {
326832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
326932b31808SJens Wiklander (
327032b31808SJens Wiklander "received future handshake message of sequence number %u (next %u)",
327111fa71b9SJerome Forissier recv_msg_seq,
327211fa71b9SJerome Forissier ssl->handshake->in_msg_seq));
327332b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
327411fa71b9SJerome Forissier }
327511fa71b9SJerome Forissier
327611fa71b9SJerome Forissier /* Retransmit only on last message from previous flight, to avoid
327711fa71b9SJerome Forissier * too many retransmissions.
327811fa71b9SJerome Forissier * Besides, No sane server ever retransmits HelloVerifyRequest */
327911fa71b9SJerome Forissier if (recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
328032b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
328111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("received message from last flight, "
32827901324dSJerome Forissier "message_seq = %u, start_of_flight = %u",
328311fa71b9SJerome Forissier recv_msg_seq,
328411fa71b9SJerome Forissier ssl->handshake->in_flight_start_seq));
328511fa71b9SJerome Forissier
328632b31808SJens Wiklander if ((ret = mbedtls_ssl_resend(ssl)) != 0) {
328711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend", ret);
328832b31808SJens Wiklander return ret;
328911fa71b9SJerome Forissier }
329032b31808SJens Wiklander } else {
329111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("dropping out-of-sequence message: "
32927901324dSJerome Forissier "message_seq = %u, expected = %u",
329311fa71b9SJerome Forissier recv_msg_seq,
329411fa71b9SJerome Forissier ssl->handshake->in_msg_seq));
329511fa71b9SJerome Forissier }
329611fa71b9SJerome Forissier
329732b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
329811fa71b9SJerome Forissier }
329911fa71b9SJerome Forissier /* Wait until message completion to increment in_msg_seq */
330011fa71b9SJerome Forissier
330111fa71b9SJerome Forissier /* Message reassembly is handled alongside buffering of future
330211fa71b9SJerome Forissier * messages; the commonality is that both handshake fragments and
330311fa71b9SJerome Forissier * future messages cannot be forwarded immediately to the
330411fa71b9SJerome Forissier * handshake logic layer. */
330532b31808SJens Wiklander if (ssl_hs_is_proper_fragment(ssl) == 1) {
330611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("found fragmented DTLS handshake message"));
330732b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
330811fa71b9SJerome Forissier }
330932b31808SJens Wiklander } else
331011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
3311c3deb3d6SEtienne Carriere {
3312c3deb3d6SEtienne Carriere unsigned char *const reassembled_record_start =
3313c3deb3d6SEtienne Carriere ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
3314c3deb3d6SEtienne Carriere unsigned char *const payload_start =
3315c3deb3d6SEtienne Carriere reassembled_record_start + mbedtls_ssl_in_hdr_len(ssl);
3316c3deb3d6SEtienne Carriere unsigned char *payload_end = payload_start + ssl->badmac_seen_or_in_hsfraglen;
3317c3deb3d6SEtienne Carriere /* How many more bytes we want to have a complete handshake message. */
3318c3deb3d6SEtienne Carriere const size_t hs_remain = ssl->in_hslen - ssl->badmac_seen_or_in_hsfraglen;
3319c3deb3d6SEtienne Carriere /* How many bytes of the current record are part of the first
3320c3deb3d6SEtienne Carriere * handshake message. There may be more handshake messages (possibly
3321c3deb3d6SEtienne Carriere * incomplete) in the same record; if so, we leave them after the
3322c3deb3d6SEtienne Carriere * current record, and ssl_consume_current_message() will take
3323c3deb3d6SEtienne Carriere * care of consuming the next handshake message. */
3324c3deb3d6SEtienne Carriere const size_t hs_this_fragment_len =
3325c3deb3d6SEtienne Carriere ssl->in_msglen > hs_remain ? hs_remain : ssl->in_msglen;
3326c3deb3d6SEtienne Carriere (void) hs_this_fragment_len;
3327c3deb3d6SEtienne Carriere
3328c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(3,
3329c3deb3d6SEtienne Carriere ("%s handshake fragment: %" MBEDTLS_PRINTF_SIZET
3330c3deb3d6SEtienne Carriere ", %u..%u of %" MBEDTLS_PRINTF_SIZET,
3331c3deb3d6SEtienne Carriere (ssl->badmac_seen_or_in_hsfraglen != 0 ?
3332c3deb3d6SEtienne Carriere "subsequent" :
3333c3deb3d6SEtienne Carriere hs_this_fragment_len == ssl->in_hslen ?
3334c3deb3d6SEtienne Carriere "sole" :
3335c3deb3d6SEtienne Carriere "initial"),
3336c3deb3d6SEtienne Carriere ssl->in_msglen,
3337c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen,
3338c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen +
3339c3deb3d6SEtienne Carriere (unsigned) hs_this_fragment_len,
3340c3deb3d6SEtienne Carriere ssl->in_hslen));
3341c3deb3d6SEtienne Carriere
3342c3deb3d6SEtienne Carriere /* Move the received handshake fragment to have the whole message
3343c3deb3d6SEtienne Carriere * (at least the part received so far) in a single segment at a
3344c3deb3d6SEtienne Carriere * known offset in the input buffer.
3345c3deb3d6SEtienne Carriere * - When receiving a non-initial handshake fragment, append it to
3346c3deb3d6SEtienne Carriere * the initial segment.
3347c3deb3d6SEtienne Carriere * - Even the initial handshake fragment is moved, if it was
3348c3deb3d6SEtienne Carriere * encrypted with an explicit IV: decryption leaves the payload
3349c3deb3d6SEtienne Carriere * after the explicit IV, but here we move it to start where the
3350c3deb3d6SEtienne Carriere * IV was.
3351c3deb3d6SEtienne Carriere */
3352c3deb3d6SEtienne Carriere #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3353c3deb3d6SEtienne Carriere size_t const in_buf_len = ssl->in_buf_len;
3354c3deb3d6SEtienne Carriere #else
3355c3deb3d6SEtienne Carriere size_t const in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
3356c3deb3d6SEtienne Carriere #endif
3357c3deb3d6SEtienne Carriere if (payload_end + ssl->in_msglen > ssl->in_buf + in_buf_len) {
3358c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(1,
3359c3deb3d6SEtienne Carriere ("Shouldn't happen: no room to move handshake fragment %"
3360c3deb3d6SEtienne Carriere MBEDTLS_PRINTF_SIZET " from %p to %p (buf=%p len=%"
3361c3deb3d6SEtienne Carriere MBEDTLS_PRINTF_SIZET ")",
3362c3deb3d6SEtienne Carriere ssl->in_msglen,
3363c3deb3d6SEtienne Carriere (void *) ssl->in_msg, (void *) payload_end,
3364c3deb3d6SEtienne Carriere (void *) ssl->in_buf, in_buf_len));
3365c3deb3d6SEtienne Carriere return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3366c3deb3d6SEtienne Carriere }
3367c3deb3d6SEtienne Carriere memmove(payload_end, ssl->in_msg, ssl->in_msglen);
3368c3deb3d6SEtienne Carriere
3369c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen += (unsigned) ssl->in_msglen;
3370c3deb3d6SEtienne Carriere payload_end += ssl->in_msglen;
3371c3deb3d6SEtienne Carriere
3372c3deb3d6SEtienne Carriere if (ssl->badmac_seen_or_in_hsfraglen < ssl->in_hslen) {
3373c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(3, ("Prepare: waiting for more handshake fragments "
3374c3deb3d6SEtienne Carriere "%u/%" MBEDTLS_PRINTF_SIZET,
3375c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
3376c3deb3d6SEtienne Carriere ssl->in_hdr = payload_end;
3377c3deb3d6SEtienne Carriere ssl->in_msglen = 0;
3378c3deb3d6SEtienne Carriere mbedtls_ssl_update_in_pointers(ssl);
3379c3deb3d6SEtienne Carriere return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
3380c3deb3d6SEtienne Carriere } else {
3381c3deb3d6SEtienne Carriere ssl->in_msglen = ssl->badmac_seen_or_in_hsfraglen;
3382c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen = 0;
3383c3deb3d6SEtienne Carriere ssl->in_hdr = reassembled_record_start;
3384c3deb3d6SEtienne Carriere mbedtls_ssl_update_in_pointers(ssl);
3385c3deb3d6SEtienne Carriere
3386c3deb3d6SEtienne Carriere /* Update the record length in the fully reassembled record */
3387c3deb3d6SEtienne Carriere if (ssl->in_msglen > 0xffff) {
3388c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(1,
3389c3deb3d6SEtienne Carriere ("Shouldn't happen: in_msglen=%"
3390c3deb3d6SEtienne Carriere MBEDTLS_PRINTF_SIZET " > 0xffff",
3391c3deb3d6SEtienne Carriere ssl->in_msglen));
3392c3deb3d6SEtienne Carriere return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3393c3deb3d6SEtienne Carriere }
3394c3deb3d6SEtienne Carriere MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
3395c3deb3d6SEtienne Carriere
3396c3deb3d6SEtienne Carriere size_t record_len = mbedtls_ssl_in_hdr_len(ssl) + ssl->in_msglen;
3397c3deb3d6SEtienne Carriere (void) record_len;
3398c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_BUF(4, "reassembled record",
3399c3deb3d6SEtienne Carriere ssl->in_hdr, record_len);
3400c3deb3d6SEtienne Carriere if (ssl->in_hslen < ssl->in_msglen) {
3401c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(3,
3402c3deb3d6SEtienne Carriere ("More handshake messages in the record: "
3403c3deb3d6SEtienne Carriere "%" MBEDTLS_PRINTF_SIZET " + %" MBEDTLS_PRINTF_SIZET,
3404c3deb3d6SEtienne Carriere ssl->in_hslen,
3405c3deb3d6SEtienne Carriere ssl->in_msglen - ssl->in_hslen));
3406c3deb3d6SEtienne Carriere }
3407c3deb3d6SEtienne Carriere }
340811fa71b9SJerome Forissier }
340911fa71b9SJerome Forissier
341032b31808SJens Wiklander return 0;
341111fa71b9SJerome Forissier }
341211fa71b9SJerome Forissier
mbedtls_ssl_update_handshake_status(mbedtls_ssl_context * ssl)341332b31808SJens Wiklander int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl)
341411fa71b9SJerome Forissier {
341532b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
341611fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
341711fa71b9SJerome Forissier
341832b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) {
341932b31808SJens Wiklander ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen);
342032b31808SJens Wiklander if (ret != 0) {
342132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
342232b31808SJens Wiklander return ret;
342332b31808SJens Wiklander }
342411fa71b9SJerome Forissier }
342511fa71b9SJerome Forissier
342611fa71b9SJerome Forissier /* Handshake message is complete, increment counter */
342711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
342811fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
342932b31808SJens Wiklander ssl->handshake != NULL) {
343011fa71b9SJerome Forissier unsigned offset;
343111fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf;
343211fa71b9SJerome Forissier
343311fa71b9SJerome Forissier /* Increment handshake sequence number */
343411fa71b9SJerome Forissier hs->in_msg_seq++;
343511fa71b9SJerome Forissier
343611fa71b9SJerome Forissier /*
343711fa71b9SJerome Forissier * Clear up handshake buffering and reassembly structure.
343811fa71b9SJerome Forissier */
343911fa71b9SJerome Forissier
344011fa71b9SJerome Forissier /* Free first entry */
344111fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, 0);
344211fa71b9SJerome Forissier
344311fa71b9SJerome Forissier /* Shift all other entries */
344411fa71b9SJerome Forissier for (offset = 0, hs_buf = &hs->buffering.hs[0];
344511fa71b9SJerome Forissier offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
344632b31808SJens Wiklander offset++, hs_buf++) {
344711fa71b9SJerome Forissier *hs_buf = *(hs_buf + 1);
344811fa71b9SJerome Forissier }
344911fa71b9SJerome Forissier
345011fa71b9SJerome Forissier /* Create a fresh last entry */
345111fa71b9SJerome Forissier memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
345211fa71b9SJerome Forissier }
345311fa71b9SJerome Forissier #endif
345432b31808SJens Wiklander return 0;
345511fa71b9SJerome Forissier }
345611fa71b9SJerome Forissier
345711fa71b9SJerome Forissier /*
345811fa71b9SJerome Forissier * DTLS anti-replay: RFC 6347 4.1.2.6
345911fa71b9SJerome Forissier *
346011fa71b9SJerome Forissier * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
346111fa71b9SJerome Forissier * Bit n is set iff record number in_window_top - n has been seen.
346211fa71b9SJerome Forissier *
346311fa71b9SJerome Forissier * Usually, in_window_top is the last record number seen and the lsb of
346411fa71b9SJerome Forissier * in_window is set. The only exception is the initial state (record number 0
346511fa71b9SJerome Forissier * not seen yet).
346611fa71b9SJerome Forissier */
346711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context * ssl)346811fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_reset(mbedtls_ssl_context *ssl)
346911fa71b9SJerome Forissier {
347011fa71b9SJerome Forissier ssl->in_window_top = 0;
347111fa71b9SJerome Forissier ssl->in_window = 0;
347211fa71b9SJerome Forissier }
347311fa71b9SJerome Forissier
ssl_load_six_bytes(unsigned char * buf)347411fa71b9SJerome Forissier static inline uint64_t ssl_load_six_bytes(unsigned char *buf)
347511fa71b9SJerome Forissier {
347632b31808SJens Wiklander return ((uint64_t) buf[0] << 40) |
347711fa71b9SJerome Forissier ((uint64_t) buf[1] << 32) |
347811fa71b9SJerome Forissier ((uint64_t) buf[2] << 24) |
347911fa71b9SJerome Forissier ((uint64_t) buf[3] << 16) |
348011fa71b9SJerome Forissier ((uint64_t) buf[4] << 8) |
348132b31808SJens Wiklander ((uint64_t) buf[5]);
348211fa71b9SJerome Forissier }
348311fa71b9SJerome Forissier
3484039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context * ssl,uint8_t * record_in_ctr)348511fa71b9SJerome Forissier static int mbedtls_ssl_dtls_record_replay_check(mbedtls_ssl_context *ssl, uint8_t *record_in_ctr)
348611fa71b9SJerome Forissier {
348711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
348811fa71b9SJerome Forissier unsigned char *original_in_ctr;
348911fa71b9SJerome Forissier
349011fa71b9SJerome Forissier // save original in_ctr
349111fa71b9SJerome Forissier original_in_ctr = ssl->in_ctr;
349211fa71b9SJerome Forissier
349311fa71b9SJerome Forissier // use counter from record
349411fa71b9SJerome Forissier ssl->in_ctr = record_in_ctr;
349511fa71b9SJerome Forissier
349611fa71b9SJerome Forissier ret = mbedtls_ssl_dtls_replay_check((mbedtls_ssl_context const *) ssl);
349711fa71b9SJerome Forissier
349811fa71b9SJerome Forissier // restore the counter
349911fa71b9SJerome Forissier ssl->in_ctr = original_in_ctr;
350011fa71b9SJerome Forissier
350111fa71b9SJerome Forissier return ret;
350211fa71b9SJerome Forissier }
350311fa71b9SJerome Forissier
350411fa71b9SJerome Forissier /*
350511fa71b9SJerome Forissier * Return 0 if sequence number is acceptable, -1 otherwise
350611fa71b9SJerome Forissier */
mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const * ssl)350711fa71b9SJerome Forissier int mbedtls_ssl_dtls_replay_check(mbedtls_ssl_context const *ssl)
350811fa71b9SJerome Forissier {
350911fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
351011fa71b9SJerome Forissier uint64_t bit;
351111fa71b9SJerome Forissier
351232b31808SJens Wiklander if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
351332b31808SJens Wiklander return 0;
351432b31808SJens Wiklander }
351511fa71b9SJerome Forissier
351632b31808SJens Wiklander if (rec_seqnum > ssl->in_window_top) {
351732b31808SJens Wiklander return 0;
351832b31808SJens Wiklander }
351911fa71b9SJerome Forissier
352011fa71b9SJerome Forissier bit = ssl->in_window_top - rec_seqnum;
352111fa71b9SJerome Forissier
352232b31808SJens Wiklander if (bit >= 64) {
352332b31808SJens Wiklander return -1;
352432b31808SJens Wiklander }
352511fa71b9SJerome Forissier
352632b31808SJens Wiklander if ((ssl->in_window & ((uint64_t) 1 << bit)) != 0) {
352732b31808SJens Wiklander return -1;
352832b31808SJens Wiklander }
352911fa71b9SJerome Forissier
353032b31808SJens Wiklander return 0;
353111fa71b9SJerome Forissier }
353211fa71b9SJerome Forissier
353311fa71b9SJerome Forissier /*
353411fa71b9SJerome Forissier * Update replay window on new validated record
353511fa71b9SJerome Forissier */
mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context * ssl)353611fa71b9SJerome Forissier void mbedtls_ssl_dtls_replay_update(mbedtls_ssl_context *ssl)
353711fa71b9SJerome Forissier {
353811fa71b9SJerome Forissier uint64_t rec_seqnum = ssl_load_six_bytes(ssl->in_ctr + 2);
353911fa71b9SJerome Forissier
354032b31808SJens Wiklander if (ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED) {
354111fa71b9SJerome Forissier return;
354232b31808SJens Wiklander }
354311fa71b9SJerome Forissier
354432b31808SJens Wiklander if (rec_seqnum > ssl->in_window_top) {
354511fa71b9SJerome Forissier /* Update window_top and the contents of the window */
354611fa71b9SJerome Forissier uint64_t shift = rec_seqnum - ssl->in_window_top;
354711fa71b9SJerome Forissier
354832b31808SJens Wiklander if (shift >= 64) {
354911fa71b9SJerome Forissier ssl->in_window = 1;
355032b31808SJens Wiklander } else {
355111fa71b9SJerome Forissier ssl->in_window <<= shift;
355211fa71b9SJerome Forissier ssl->in_window |= 1;
355311fa71b9SJerome Forissier }
355411fa71b9SJerome Forissier
355511fa71b9SJerome Forissier ssl->in_window_top = rec_seqnum;
355632b31808SJens Wiklander } else {
355711fa71b9SJerome Forissier /* Mark that number as seen in the current window */
355811fa71b9SJerome Forissier uint64_t bit = ssl->in_window_top - rec_seqnum;
355911fa71b9SJerome Forissier
356032b31808SJens Wiklander if (bit < 64) { /* Always true, but be extra sure */
356111fa71b9SJerome Forissier ssl->in_window |= (uint64_t) 1 << bit;
356211fa71b9SJerome Forissier }
356311fa71b9SJerome Forissier }
356432b31808SJens Wiklander }
356511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
356611fa71b9SJerome Forissier
356711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
356811fa71b9SJerome Forissier /*
3569039e02dfSJerome Forissier * Check if a datagram looks like a ClientHello with a valid cookie,
3570039e02dfSJerome Forissier * and if it doesn't, generate a HelloVerifyRequest message.
357111fa71b9SJerome Forissier * Both input and output include full DTLS headers.
357211fa71b9SJerome Forissier *
357311fa71b9SJerome Forissier * - if cookie is valid, return 0
357411fa71b9SJerome Forissier * - if ClientHello looks superficially valid but cookie is not,
357511fa71b9SJerome Forissier * fill obuf and set olen, then
357611fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
357711fa71b9SJerome Forissier * - otherwise return a specific error code
357811fa71b9SJerome Forissier */
3579039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
3580039e02dfSJerome Forissier MBEDTLS_STATIC_TESTABLE
mbedtls_ssl_check_dtls_clihlo_cookie(mbedtls_ssl_context * ssl,const unsigned char * cli_id,size_t cli_id_len,const unsigned char * in,size_t in_len,unsigned char * obuf,size_t buf_len,size_t * olen)3581039e02dfSJerome Forissier int mbedtls_ssl_check_dtls_clihlo_cookie(
3582039e02dfSJerome Forissier mbedtls_ssl_context *ssl,
358311fa71b9SJerome Forissier const unsigned char *cli_id, size_t cli_id_len,
358411fa71b9SJerome Forissier const unsigned char *in, size_t in_len,
358511fa71b9SJerome Forissier unsigned char *obuf, size_t buf_len, size_t *olen)
358611fa71b9SJerome Forissier {
358732b31808SJens Wiklander size_t sid_len, cookie_len, epoch, fragment_offset;
358811fa71b9SJerome Forissier unsigned char *p;
358911fa71b9SJerome Forissier
359011fa71b9SJerome Forissier /*
359111fa71b9SJerome Forissier * Structure of ClientHello with record and handshake headers,
359211fa71b9SJerome Forissier * and expected values. We don't need to check a lot, more checks will be
359311fa71b9SJerome Forissier * done when actually parsing the ClientHello - skipping those checks
359411fa71b9SJerome Forissier * avoids code duplication and does not make cookie forging any easier.
359511fa71b9SJerome Forissier *
359611fa71b9SJerome Forissier * 0-0 ContentType type; copied, must be handshake
359711fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied
359811fa71b9SJerome Forissier * 3-4 uint16 epoch; copied, must be 0
359911fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied
360011fa71b9SJerome Forissier * 11-12 uint16 length; (ignored)
360111fa71b9SJerome Forissier *
360211fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; (ignored)
360311fa71b9SJerome Forissier * 14-16 uint24 length; (ignored)
360411fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied
360511fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied, must be 0
360611fa71b9SJerome Forissier * 22-24 uint24 fragment_length; (ignored)
360711fa71b9SJerome Forissier *
360811fa71b9SJerome Forissier * 25-26 ProtocolVersion client_version; (ignored)
360911fa71b9SJerome Forissier * 27-58 Random random; (ignored)
361011fa71b9SJerome Forissier * 59-xx SessionID session_id; 1 byte len + sid_len content
361111fa71b9SJerome Forissier * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
361211fa71b9SJerome Forissier * ...
361311fa71b9SJerome Forissier *
361411fa71b9SJerome Forissier * Minimum length is 61 bytes.
361511fa71b9SJerome Forissier */
3616039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: in_len=%u",
3617039e02dfSJerome Forissier (unsigned) in_len));
3618039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "cli_id", cli_id, cli_id_len);
361932b31808SJens Wiklander if (in_len < 61) {
3620039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: record too short"));
362132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR;
3622039e02dfSJerome Forissier }
362332b31808SJens Wiklander
362432b31808SJens Wiklander epoch = MBEDTLS_GET_UINT16_BE(in, 3);
362532b31808SJens Wiklander fragment_offset = MBEDTLS_GET_UINT24_BE(in, 19);
362632b31808SJens Wiklander
362732b31808SJens Wiklander if (in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || epoch != 0 ||
362832b31808SJens Wiklander fragment_offset != 0) {
3629039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: not a good ClientHello"));
3630039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, (" type=%u epoch=%u fragment_offset=%u",
363132b31808SJens Wiklander in[0], (unsigned) epoch,
363232b31808SJens Wiklander (unsigned) fragment_offset));
363332b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR;
363411fa71b9SJerome Forissier }
363511fa71b9SJerome Forissier
363611fa71b9SJerome Forissier sid_len = in[59];
363732b31808SJens Wiklander if (59 + 1 + sid_len + 1 > in_len) {
3638039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: sid_len=%u > %u",
3639039e02dfSJerome Forissier (unsigned) sid_len,
3640039e02dfSJerome Forissier (unsigned) in_len - 61));
364132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR;
3642039e02dfSJerome Forissier }
3643039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "sid received from network",
3644039e02dfSJerome Forissier in + 60, sid_len);
364511fa71b9SJerome Forissier
364611fa71b9SJerome Forissier cookie_len = in[60 + sid_len];
364732b31808SJens Wiklander if (59 + 1 + sid_len + 1 + cookie_len > in_len) {
3648039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: cookie_len=%u > %u",
3649039e02dfSJerome Forissier (unsigned) cookie_len,
3650039e02dfSJerome Forissier (unsigned) (in_len - sid_len - 61)));
365132b31808SJens Wiklander return MBEDTLS_ERR_SSL_DECODE_ERROR;
3652039e02dfSJerome Forissier }
365311fa71b9SJerome Forissier
3654039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "cookie received from network",
3655039e02dfSJerome Forissier in + sid_len + 61, cookie_len);
3656039e02dfSJerome Forissier if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
3657039e02dfSJerome Forissier in + sid_len + 61, cookie_len,
365832b31808SJens Wiklander cli_id, cli_id_len) == 0) {
3659039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("check cookie: valid"));
366032b31808SJens Wiklander return 0;
366111fa71b9SJerome Forissier }
366211fa71b9SJerome Forissier
366311fa71b9SJerome Forissier /*
366411fa71b9SJerome Forissier * If we get here, we've got an invalid cookie, let's prepare HVR.
366511fa71b9SJerome Forissier *
366611fa71b9SJerome Forissier * 0-0 ContentType type; copied
366711fa71b9SJerome Forissier * 1-2 ProtocolVersion version; copied
366811fa71b9SJerome Forissier * 3-4 uint16 epoch; copied
366911fa71b9SJerome Forissier * 5-10 uint48 sequence_number; copied
367011fa71b9SJerome Forissier * 11-12 uint16 length; olen - 13
367111fa71b9SJerome Forissier *
367211fa71b9SJerome Forissier * 13-13 HandshakeType msg_type; hello_verify_request
367311fa71b9SJerome Forissier * 14-16 uint24 length; olen - 25
367411fa71b9SJerome Forissier * 17-18 uint16 message_seq; copied
367511fa71b9SJerome Forissier * 19-21 uint24 fragment_offset; copied
367611fa71b9SJerome Forissier * 22-24 uint24 fragment_length; olen - 25
367711fa71b9SJerome Forissier *
367811fa71b9SJerome Forissier * 25-26 ProtocolVersion server_version; 0xfe 0xff
367911fa71b9SJerome Forissier * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
368011fa71b9SJerome Forissier *
368111fa71b9SJerome Forissier * Minimum length is 28.
368211fa71b9SJerome Forissier */
368332b31808SJens Wiklander if (buf_len < 28) {
368432b31808SJens Wiklander return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
368532b31808SJens Wiklander }
368611fa71b9SJerome Forissier
368711fa71b9SJerome Forissier /* Copy most fields and adapt others */
368811fa71b9SJerome Forissier memcpy(obuf, in, 25);
368911fa71b9SJerome Forissier obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
369011fa71b9SJerome Forissier obuf[25] = 0xfe;
369111fa71b9SJerome Forissier obuf[26] = 0xff;
369211fa71b9SJerome Forissier
369311fa71b9SJerome Forissier /* Generate and write actual cookie */
369411fa71b9SJerome Forissier p = obuf + 28;
3695039e02dfSJerome Forissier if (ssl->conf->f_cookie_write(ssl->conf->p_cookie,
3696039e02dfSJerome Forissier &p, obuf + buf_len,
369732b31808SJens Wiklander cli_id, cli_id_len) != 0) {
369832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
369911fa71b9SJerome Forissier }
370011fa71b9SJerome Forissier
3701b0563631STom Van Eyck *olen = (size_t) (p - obuf);
370211fa71b9SJerome Forissier
370311fa71b9SJerome Forissier /* Go back and fill length fields */
370411fa71b9SJerome Forissier obuf[27] = (unsigned char) (*olen - 28);
370511fa71b9SJerome Forissier
3706039e02dfSJerome Forissier obuf[14] = obuf[22] = MBEDTLS_BYTE_2(*olen - 25);
3707039e02dfSJerome Forissier obuf[15] = obuf[23] = MBEDTLS_BYTE_1(*olen - 25);
3708039e02dfSJerome Forissier obuf[16] = obuf[24] = MBEDTLS_BYTE_0(*olen - 25);
370911fa71b9SJerome Forissier
3710039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(*olen - 13, obuf, 11);
371111fa71b9SJerome Forissier
371232b31808SJens Wiklander return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
371311fa71b9SJerome Forissier }
371411fa71b9SJerome Forissier
371511fa71b9SJerome Forissier /*
371611fa71b9SJerome Forissier * Handle possible client reconnect with the same UDP quadruplet
371711fa71b9SJerome Forissier * (RFC 6347 Section 4.2.8).
371811fa71b9SJerome Forissier *
371911fa71b9SJerome Forissier * Called by ssl_parse_record_header() in case we receive an epoch 0 record
372011fa71b9SJerome Forissier * that looks like a ClientHello.
372111fa71b9SJerome Forissier *
372211fa71b9SJerome Forissier * - if the input looks like a ClientHello without cookies,
372311fa71b9SJerome Forissier * send back HelloVerifyRequest, then return 0
372411fa71b9SJerome Forissier * - if the input looks like a ClientHello with a valid cookie,
372511fa71b9SJerome Forissier * reset the session of the current context, and
372611fa71b9SJerome Forissier * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
372711fa71b9SJerome Forissier * - if anything goes wrong, return a specific error code
372811fa71b9SJerome Forissier *
372911fa71b9SJerome Forissier * This function is called (through ssl_check_client_reconnect()) when an
373011fa71b9SJerome Forissier * unexpected record is found in ssl_get_next_record(), which will discard the
373111fa71b9SJerome Forissier * record if we return 0, and bubble up the return value otherwise (this
373211fa71b9SJerome Forissier * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
373311fa71b9SJerome Forissier * errors, and is the right thing to do in both cases).
373411fa71b9SJerome Forissier */
3735039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_handle_possible_reconnect(mbedtls_ssl_context * ssl)373611fa71b9SJerome Forissier static int ssl_handle_possible_reconnect(mbedtls_ssl_context *ssl)
373711fa71b9SJerome Forissier {
373811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3739b0563631STom Van Eyck size_t len = 0;
374011fa71b9SJerome Forissier
374111fa71b9SJerome Forissier if (ssl->conf->f_cookie_write == NULL ||
374232b31808SJens Wiklander ssl->conf->f_cookie_check == NULL) {
374311fa71b9SJerome Forissier /* If we can't use cookies to verify reachability of the peer,
374411fa71b9SJerome Forissier * drop the record. */
374511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("no cookie callbacks, "
374611fa71b9SJerome Forissier "can't check reconnect validity"));
374732b31808SJens Wiklander return 0;
374811fa71b9SJerome Forissier }
374911fa71b9SJerome Forissier
3750039e02dfSJerome Forissier ret = mbedtls_ssl_check_dtls_clihlo_cookie(
3751039e02dfSJerome Forissier ssl,
375211fa71b9SJerome Forissier ssl->cli_id, ssl->cli_id_len,
375311fa71b9SJerome Forissier ssl->in_buf, ssl->in_left,
375411fa71b9SJerome Forissier ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len);
375511fa71b9SJerome Forissier
3756039e02dfSJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "mbedtls_ssl_check_dtls_clihlo_cookie", ret);
375711fa71b9SJerome Forissier
375832b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
375911fa71b9SJerome Forissier int send_ret;
376011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("sending HelloVerifyRequest"));
376111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "output record sent to network",
376211fa71b9SJerome Forissier ssl->out_buf, len);
376311fa71b9SJerome Forissier /* Don't check write errors as we can't do anything here.
376411fa71b9SJerome Forissier * If the error is permanent we'll catch it later,
376511fa71b9SJerome Forissier * if it's not, then hopefully it'll work next time. */
376611fa71b9SJerome Forissier send_ret = ssl->f_send(ssl->p_bio, ssl->out_buf, len);
376711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl->f_send", send_ret);
376811fa71b9SJerome Forissier (void) send_ret;
376911fa71b9SJerome Forissier
377032b31808SJens Wiklander return 0;
377111fa71b9SJerome Forissier }
377211fa71b9SJerome Forissier
377332b31808SJens Wiklander if (ret == 0) {
377411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("cookie is valid, resetting context"));
377532b31808SJens Wiklander if ((ret = mbedtls_ssl_session_reset_int(ssl, 1)) != 0) {
377611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "reset", ret);
377732b31808SJens Wiklander return ret;
377811fa71b9SJerome Forissier }
377911fa71b9SJerome Forissier
378032b31808SJens Wiklander return MBEDTLS_ERR_SSL_CLIENT_RECONNECT;
378111fa71b9SJerome Forissier }
378211fa71b9SJerome Forissier
378332b31808SJens Wiklander return ret;
378411fa71b9SJerome Forissier }
378511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
378611fa71b9SJerome Forissier
3787039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_check_record_type(uint8_t record_type)378811fa71b9SJerome Forissier static int ssl_check_record_type(uint8_t record_type)
378911fa71b9SJerome Forissier {
379011fa71b9SJerome Forissier if (record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
379111fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_ALERT &&
379211fa71b9SJerome Forissier record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
379332b31808SJens Wiklander record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
379432b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
379511fa71b9SJerome Forissier }
379611fa71b9SJerome Forissier
379732b31808SJens Wiklander return 0;
379811fa71b9SJerome Forissier }
379911fa71b9SJerome Forissier
380011fa71b9SJerome Forissier /*
380111fa71b9SJerome Forissier * ContentType type;
380211fa71b9SJerome Forissier * ProtocolVersion version;
380311fa71b9SJerome Forissier * uint16 epoch; // DTLS only
380411fa71b9SJerome Forissier * uint48 sequence_number; // DTLS only
380511fa71b9SJerome Forissier * uint16 length;
380611fa71b9SJerome Forissier *
380711fa71b9SJerome Forissier * Return 0 if header looks sane (and, for DTLS, the record is expected)
380811fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
380911fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
381011fa71b9SJerome Forissier *
381111fa71b9SJerome Forissier * With DTLS, mbedtls_ssl_read_record() will:
381211fa71b9SJerome Forissier * 1. proceed with the record if this function returns 0
381311fa71b9SJerome Forissier * 2. drop only the current record if this function returns UNEXPECTED_RECORD
381411fa71b9SJerome Forissier * 3. return CLIENT_RECONNECT if this function return that value
381511fa71b9SJerome Forissier * 4. drop the whole datagram if this function returns anything else.
381611fa71b9SJerome Forissier * Point 2 is needed when the peer is resending, and we have already received
381711fa71b9SJerome Forissier * the first record from a datagram but are still waiting for the others.
381811fa71b9SJerome Forissier */
3819039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_record_header(mbedtls_ssl_context const * ssl,unsigned char * buf,size_t len,mbedtls_record * rec)382011fa71b9SJerome Forissier static int ssl_parse_record_header(mbedtls_ssl_context const *ssl,
382111fa71b9SJerome Forissier unsigned char *buf,
382211fa71b9SJerome Forissier size_t len,
382311fa71b9SJerome Forissier mbedtls_record *rec)
382411fa71b9SJerome Forissier {
382532b31808SJens Wiklander mbedtls_ssl_protocol_version tls_version;
382611fa71b9SJerome Forissier
382711fa71b9SJerome Forissier size_t const rec_hdr_type_offset = 0;
382811fa71b9SJerome Forissier size_t const rec_hdr_type_len = 1;
382911fa71b9SJerome Forissier
383011fa71b9SJerome Forissier size_t const rec_hdr_version_offset = rec_hdr_type_offset +
383111fa71b9SJerome Forissier rec_hdr_type_len;
383211fa71b9SJerome Forissier size_t const rec_hdr_version_len = 2;
383311fa71b9SJerome Forissier
383411fa71b9SJerome Forissier size_t const rec_hdr_ctr_len = 8;
383511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
383611fa71b9SJerome Forissier uint32_t rec_epoch;
383711fa71b9SJerome Forissier size_t const rec_hdr_ctr_offset = rec_hdr_version_offset +
383811fa71b9SJerome Forissier rec_hdr_version_len;
383911fa71b9SJerome Forissier
384011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
384111fa71b9SJerome Forissier size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset +
384211fa71b9SJerome Forissier rec_hdr_ctr_len;
384311fa71b9SJerome Forissier size_t rec_hdr_cid_len = 0;
384411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
384511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
384611fa71b9SJerome Forissier
384711fa71b9SJerome Forissier size_t rec_hdr_len_offset; /* To be determined */
384811fa71b9SJerome Forissier size_t const rec_hdr_len_len = 2;
384911fa71b9SJerome Forissier
385011fa71b9SJerome Forissier /*
385111fa71b9SJerome Forissier * Check minimum lengths for record header.
385211fa71b9SJerome Forissier */
385311fa71b9SJerome Forissier
385411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
385532b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
385611fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
385732b31808SJens Wiklander } else
385811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
385911fa71b9SJerome Forissier {
386011fa71b9SJerome Forissier rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
386111fa71b9SJerome Forissier }
386211fa71b9SJerome Forissier
386332b31808SJens Wiklander if (len < rec_hdr_len_offset + rec_hdr_len_len) {
386432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1,
386532b31808SJens Wiklander (
386632b31808SJens Wiklander "datagram of length %u too small to hold DTLS record header of length %u",
386711fa71b9SJerome Forissier (unsigned) len,
386811fa71b9SJerome Forissier (unsigned) (rec_hdr_len_len + rec_hdr_len_len)));
386932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
387011fa71b9SJerome Forissier }
387111fa71b9SJerome Forissier
387211fa71b9SJerome Forissier /*
387311fa71b9SJerome Forissier * Parse and validate record content type
387411fa71b9SJerome Forissier */
387511fa71b9SJerome Forissier
387611fa71b9SJerome Forissier rec->type = buf[rec_hdr_type_offset];
387711fa71b9SJerome Forissier
387811fa71b9SJerome Forissier /* Check record content type */
387911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
388011fa71b9SJerome Forissier rec->cid_len = 0;
388111fa71b9SJerome Forissier
388211fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
388311fa71b9SJerome Forissier ssl->conf->cid_len != 0 &&
388432b31808SJens Wiklander rec->type == MBEDTLS_SSL_MSG_CID) {
388511fa71b9SJerome Forissier /* Shift pointers to account for record header including CID
388611fa71b9SJerome Forissier * struct {
388732b31808SJens Wiklander * ContentType outer_type = tls12_cid;
388811fa71b9SJerome Forissier * ProtocolVersion version;
388911fa71b9SJerome Forissier * uint16 epoch;
389011fa71b9SJerome Forissier * uint48 sequence_number;
389111fa71b9SJerome Forissier * opaque cid[cid_length]; // Additional field compared to
389211fa71b9SJerome Forissier * // default DTLS record format
389311fa71b9SJerome Forissier * uint16 length;
389411fa71b9SJerome Forissier * opaque enc_content[DTLSCiphertext.length];
389511fa71b9SJerome Forissier * } DTLSCiphertext;
389611fa71b9SJerome Forissier */
389711fa71b9SJerome Forissier
389811fa71b9SJerome Forissier /* So far, we only support static CID lengths
389911fa71b9SJerome Forissier * fixed in the configuration. */
390011fa71b9SJerome Forissier rec_hdr_cid_len = ssl->conf->cid_len;
390111fa71b9SJerome Forissier rec_hdr_len_offset += rec_hdr_cid_len;
390211fa71b9SJerome Forissier
390332b31808SJens Wiklander if (len < rec_hdr_len_offset + rec_hdr_len_len) {
390432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1,
390532b31808SJens Wiklander (
390632b31808SJens Wiklander "datagram of length %u too small to hold DTLS record header including CID, length %u",
390711fa71b9SJerome Forissier (unsigned) len,
390811fa71b9SJerome Forissier (unsigned) (rec_hdr_len_offset + rec_hdr_len_len)));
390932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
391011fa71b9SJerome Forissier }
391111fa71b9SJerome Forissier
391211fa71b9SJerome Forissier /* configured CID len is guaranteed at most 255, see
391311fa71b9SJerome Forissier * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
391411fa71b9SJerome Forissier rec->cid_len = (uint8_t) rec_hdr_cid_len;
391511fa71b9SJerome Forissier memcpy(rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len);
391632b31808SJens Wiklander } else
391711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
391811fa71b9SJerome Forissier {
391932b31808SJens Wiklander if (ssl_check_record_type(rec->type)) {
392011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type %u",
392111fa71b9SJerome Forissier (unsigned) rec->type));
392232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
392311fa71b9SJerome Forissier }
392411fa71b9SJerome Forissier }
392511fa71b9SJerome Forissier
392611fa71b9SJerome Forissier /*
392711fa71b9SJerome Forissier * Parse and validate record version
392811fa71b9SJerome Forissier */
392911fa71b9SJerome Forissier rec->ver[0] = buf[rec_hdr_version_offset + 0];
393011fa71b9SJerome Forissier rec->ver[1] = buf[rec_hdr_version_offset + 1];
3931b0563631STom Van Eyck tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(
3932b0563631STom Van Eyck buf + rec_hdr_version_offset,
393332b31808SJens Wiklander ssl->conf->transport);
393411fa71b9SJerome Forissier
393532b31808SJens Wiklander if (tls_version > ssl->conf->max_tls_version) {
393632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("TLS version mismatch: got %u, expected max %u",
393732b31808SJens Wiklander (unsigned) tls_version,
393832b31808SJens Wiklander (unsigned) ssl->conf->max_tls_version));
393911fa71b9SJerome Forissier
394032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
394111fa71b9SJerome Forissier }
394211fa71b9SJerome Forissier /*
394311fa71b9SJerome Forissier * Parse/Copy record sequence number.
394411fa71b9SJerome Forissier */
394511fa71b9SJerome Forissier
394611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
394732b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
394811fa71b9SJerome Forissier /* Copy explicit record sequence number from input buffer. */
394911fa71b9SJerome Forissier memcpy(&rec->ctr[0], buf + rec_hdr_ctr_offset,
395011fa71b9SJerome Forissier rec_hdr_ctr_len);
395132b31808SJens Wiklander } else
395211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
395311fa71b9SJerome Forissier {
395411fa71b9SJerome Forissier /* Copy implicit record sequence number from SSL context structure. */
395511fa71b9SJerome Forissier memcpy(&rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len);
395611fa71b9SJerome Forissier }
395711fa71b9SJerome Forissier
395811fa71b9SJerome Forissier /*
395911fa71b9SJerome Forissier * Parse record length.
396011fa71b9SJerome Forissier */
396111fa71b9SJerome Forissier
396211fa71b9SJerome Forissier rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
3963b0563631STom Van Eyck rec->data_len = MBEDTLS_GET_UINT16_BE(buf, rec_hdr_len_offset);
396411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input record header", buf, rec->data_offset);
396511fa71b9SJerome Forissier
39667901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("input record: msgtype = %u, "
396732b31808SJens Wiklander "version = [0x%x], msglen = %" MBEDTLS_PRINTF_SIZET,
396832b31808SJens Wiklander rec->type, (unsigned) tls_version, rec->data_len));
396911fa71b9SJerome Forissier
397011fa71b9SJerome Forissier rec->buf = buf;
397111fa71b9SJerome Forissier rec->buf_len = rec->data_offset + rec->data_len;
397211fa71b9SJerome Forissier
397332b31808SJens Wiklander if (rec->data_len == 0) {
3974*273a583eSThomas Bourgoin MBEDTLS_SSL_DEBUG_MSG(1, ("rejecting empty record"));
397532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
397632b31808SJens Wiklander }
397711fa71b9SJerome Forissier
397811fa71b9SJerome Forissier /*
397911fa71b9SJerome Forissier * DTLS-related tests.
398011fa71b9SJerome Forissier * Check epoch before checking length constraint because
398111fa71b9SJerome Forissier * the latter varies with the epoch. E.g., if a ChangeCipherSpec
398211fa71b9SJerome Forissier * message gets duplicated before the corresponding Finished message,
398311fa71b9SJerome Forissier * the second ChangeCipherSpec should be discarded because it belongs
398411fa71b9SJerome Forissier * to an old epoch, but not because its length is shorter than
398511fa71b9SJerome Forissier * the minimum record length for packets using the new record transform.
398611fa71b9SJerome Forissier * Note that these two kinds of failures are handled differently,
398711fa71b9SJerome Forissier * as an unexpected record is silently skipped but an invalid
398811fa71b9SJerome Forissier * record leads to the entire datagram being dropped.
398911fa71b9SJerome Forissier */
399011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
399132b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3992b0563631STom Van Eyck rec_epoch = MBEDTLS_GET_UINT16_BE(rec->ctr, 0);
399311fa71b9SJerome Forissier
399411fa71b9SJerome Forissier /* Check that the datagram is large enough to contain a record
399511fa71b9SJerome Forissier * of the advertised length. */
399632b31808SJens Wiklander if (len < rec->data_offset + rec->data_len) {
399732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1,
399832b31808SJens Wiklander (
399932b31808SJens Wiklander "Datagram of length %u too small to contain record of advertised length %u.",
400011fa71b9SJerome Forissier (unsigned) len,
400111fa71b9SJerome Forissier (unsigned) (rec->data_offset + rec->data_len)));
400232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
400311fa71b9SJerome Forissier }
400411fa71b9SJerome Forissier
400511fa71b9SJerome Forissier /* Records from other, non-matching epochs are silently discarded.
400611fa71b9SJerome Forissier * (The case of same-port Client reconnects must be considered in
400711fa71b9SJerome Forissier * the caller). */
400832b31808SJens Wiklander if (rec_epoch != ssl->in_epoch) {
400911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("record from another epoch: "
40107901324dSJerome Forissier "expected %u, received %lu",
40117901324dSJerome Forissier ssl->in_epoch, (unsigned long) rec_epoch));
401211fa71b9SJerome Forissier
401311fa71b9SJerome Forissier /* Records from the next epoch are considered for buffering
401411fa71b9SJerome Forissier * (concretely: early Finished messages). */
401532b31808SJens Wiklander if (rec_epoch == (unsigned) ssl->in_epoch + 1) {
401611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Consider record for buffering"));
401732b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
401811fa71b9SJerome Forissier }
401911fa71b9SJerome Forissier
402032b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
402111fa71b9SJerome Forissier }
402211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
402311fa71b9SJerome Forissier /* For records from the correct epoch, check whether their
402411fa71b9SJerome Forissier * sequence number has been seen before. */
402511fa71b9SJerome Forissier else if (mbedtls_ssl_dtls_record_replay_check((mbedtls_ssl_context *) ssl,
402632b31808SJens Wiklander &rec->ctr[0]) != 0) {
402711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record"));
402832b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
402911fa71b9SJerome Forissier }
403011fa71b9SJerome Forissier #endif
403111fa71b9SJerome Forissier }
403211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
403311fa71b9SJerome Forissier
403432b31808SJens Wiklander return 0;
403511fa71b9SJerome Forissier }
403611fa71b9SJerome Forissier
403711fa71b9SJerome Forissier
403811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
4039039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_check_client_reconnect(mbedtls_ssl_context * ssl)404011fa71b9SJerome Forissier static int ssl_check_client_reconnect(mbedtls_ssl_context *ssl)
404111fa71b9SJerome Forissier {
4042b0563631STom Van Eyck unsigned int rec_epoch = MBEDTLS_GET_UINT16_BE(ssl->in_ctr, 0);
404311fa71b9SJerome Forissier
404411fa71b9SJerome Forissier /*
404511fa71b9SJerome Forissier * Check for an epoch 0 ClientHello. We can't use in_msg here to
404611fa71b9SJerome Forissier * access the first byte of record content (handshake type), as we
404711fa71b9SJerome Forissier * have an active transform (possibly iv_len != 0), so use the
404811fa71b9SJerome Forissier * fact that the record header len is 13 instead.
404911fa71b9SJerome Forissier */
405011fa71b9SJerome Forissier if (rec_epoch == 0 &&
405111fa71b9SJerome Forissier ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
405232b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 1 &&
405311fa71b9SJerome Forissier ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
405411fa71b9SJerome Forissier ssl->in_left > 13 &&
405532b31808SJens Wiklander ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO) {
405611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("possible client reconnect "
405711fa71b9SJerome Forissier "from the same port"));
405832b31808SJens Wiklander return ssl_handle_possible_reconnect(ssl);
405911fa71b9SJerome Forissier }
406011fa71b9SJerome Forissier
406132b31808SJens Wiklander return 0;
406211fa71b9SJerome Forissier }
406311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
406411fa71b9SJerome Forissier
406511fa71b9SJerome Forissier /*
406611fa71b9SJerome Forissier * If applicable, decrypt record content
406711fa71b9SJerome Forissier */
4068039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_prepare_record_content(mbedtls_ssl_context * ssl,mbedtls_record * rec)406911fa71b9SJerome Forissier static int ssl_prepare_record_content(mbedtls_ssl_context *ssl,
407011fa71b9SJerome Forissier mbedtls_record *rec)
407111fa71b9SJerome Forissier {
407211fa71b9SJerome Forissier int ret, done = 0;
407311fa71b9SJerome Forissier
407411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input record from network",
407511fa71b9SJerome Forissier rec->buf, rec->buf_len);
407611fa71b9SJerome Forissier
407732b31808SJens Wiklander /*
407832b31808SJens Wiklander * In TLS 1.3, always treat ChangeCipherSpec records
407932b31808SJens Wiklander * as unencrypted. The only thing we do with them is
408032b31808SJens Wiklander * check the length and content and ignore them.
408132b31808SJens Wiklander */
408232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
408332b31808SJens Wiklander if (ssl->transform_in != NULL &&
408432b31808SJens Wiklander ssl->transform_in->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
408532b31808SJens Wiklander if (rec->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
408611fa71b9SJerome Forissier done = 1;
408711fa71b9SJerome Forissier }
408832b31808SJens Wiklander }
408932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
409032b31808SJens Wiklander
409132b31808SJens Wiklander if (!done && ssl->transform_in != NULL) {
409211fa71b9SJerome Forissier unsigned char const old_msg_type = rec->type;
409311fa71b9SJerome Forissier
409411fa71b9SJerome Forissier if ((ret = mbedtls_ssl_decrypt_buf(ssl, ssl->transform_in,
409532b31808SJens Wiklander rec)) != 0) {
409611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_decrypt_buf", ret);
409711fa71b9SJerome Forissier
4098b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4099b0563631STom Van Eyck /*
4100b0563631STom Van Eyck * Although the server rejected early data, it might receive early
4101b0563631STom Van Eyck * data as long as it has not received the client Finished message.
4102b0563631STom Van Eyck * It is encrypted with early keys and should be ignored as stated
4103b0563631STom Van Eyck * in section 4.2.10 of RFC 8446:
4104b0563631STom Van Eyck *
4105b0563631STom Van Eyck * "Ignore the extension and return a regular 1-RTT response. The
4106b0563631STom Van Eyck * server then skips past early data by attempting to deprotect
4107b0563631STom Van Eyck * received records using the handshake traffic key, discarding
4108b0563631STom Van Eyck * records which fail deprotection (up to the configured
4109b0563631STom Van Eyck * max_early_data_size). Once a record is deprotected successfully,
4110b0563631STom Van Eyck * it is treated as the start of the client's second flight and the
4111b0563631STom Van Eyck * server proceeds as with an ordinary 1-RTT handshake."
4112b0563631STom Van Eyck */
4113b0563631STom Van Eyck if ((old_msg_type == MBEDTLS_SSL_MSG_APPLICATION_DATA) &&
4114b0563631STom Van Eyck (ssl->discard_early_data_record ==
4115b0563631STom Van Eyck MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD)) {
4116b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(
4117b0563631STom Van Eyck 3, ("EarlyData: deprotect and discard app data records."));
4118b0563631STom Van Eyck
4119b0563631STom Van Eyck ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4120b0563631STom Van Eyck if (ret != 0) {
4121b0563631STom Van Eyck return ret;
4122b0563631STom Van Eyck }
4123b0563631STom Van Eyck ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4124b0563631STom Van Eyck }
4125b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4126b0563631STom Van Eyck
412711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
412811fa71b9SJerome Forissier if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
412911fa71b9SJerome Forissier ssl->conf->ignore_unexpected_cid
413032b31808SJens Wiklander == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE) {
413111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ignoring unexpected CID"));
413211fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
413311fa71b9SJerome Forissier }
413411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
413511fa71b9SJerome Forissier
4136b0563631STom Van Eyck /*
4137b0563631STom Van Eyck * The decryption of the record failed, no reason to ignore it,
4138b0563631STom Van Eyck * return in error with the decryption error code.
4139b0563631STom Van Eyck */
414032b31808SJens Wiklander return ret;
414111fa71b9SJerome Forissier }
414211fa71b9SJerome Forissier
4143b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4144b0563631STom Van Eyck /*
4145b0563631STom Van Eyck * If the server were discarding protected records that it fails to
4146b0563631STom Van Eyck * deprotect because it has rejected early data, as we have just
4147b0563631STom Van Eyck * deprotected successfully a record, the server has to resume normal
4148b0563631STom Van Eyck * operation and fail the connection if the deprotection of a record
4149b0563631STom Van Eyck * fails.
4150b0563631STom Van Eyck */
4151b0563631STom Van Eyck if (ssl->discard_early_data_record ==
4152b0563631STom Van Eyck MBEDTLS_SSL_EARLY_DATA_TRY_TO_DEPROTECT_AND_DISCARD) {
4153b0563631STom Van Eyck ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4154b0563631STom Van Eyck }
4155b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4156b0563631STom Van Eyck
415732b31808SJens Wiklander if (old_msg_type != rec->type) {
415811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(4, ("record type after decrypt (before %d): %d",
415911fa71b9SJerome Forissier old_msg_type, rec->type));
416011fa71b9SJerome Forissier }
416111fa71b9SJerome Forissier
416211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "input payload after decrypt",
416311fa71b9SJerome Forissier rec->buf + rec->data_offset, rec->data_len);
416411fa71b9SJerome Forissier
416511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
416611fa71b9SJerome Forissier /* We have already checked the record content type
416711fa71b9SJerome Forissier * in ssl_parse_record_header(), failing or silently
416811fa71b9SJerome Forissier * dropping the record in the case of an unknown type.
416911fa71b9SJerome Forissier *
417011fa71b9SJerome Forissier * Since with the use of CIDs, the record content type
417111fa71b9SJerome Forissier * might change during decryption, re-check the record
417211fa71b9SJerome Forissier * content type, but treat a failure as fatal this time. */
417332b31808SJens Wiklander if (ssl_check_record_type(rec->type)) {
417411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("unknown record type"));
417532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
417611fa71b9SJerome Forissier }
417711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
417811fa71b9SJerome Forissier
417932b31808SJens Wiklander if (rec->data_len == 0) {
418011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
418132b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2
418232b31808SJens Wiklander && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
418311fa71b9SJerome Forissier /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
418411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid zero-length message type: %d", ssl->in_msgtype));
418532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
418611fa71b9SJerome Forissier }
418711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
418811fa71b9SJerome Forissier
418911fa71b9SJerome Forissier ssl->nb_zero++;
419011fa71b9SJerome Forissier
419111fa71b9SJerome Forissier /*
419211fa71b9SJerome Forissier * Three or more empty messages may be a DoS attack
419311fa71b9SJerome Forissier * (excessive CPU consumption).
419411fa71b9SJerome Forissier */
419532b31808SJens Wiklander if (ssl->nb_zero > 3) {
419611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("received four consecutive empty "
419711fa71b9SJerome Forissier "messages, possible DoS attack"));
419811fa71b9SJerome Forissier /* Treat the records as if they were not properly authenticated,
419911fa71b9SJerome Forissier * thereby failing the connection if we see more than allowed
420011fa71b9SJerome Forissier * by the configured bad MAC threshold. */
420132b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
420211fa71b9SJerome Forissier }
420332b31808SJens Wiklander } else {
420411fa71b9SJerome Forissier ssl->nb_zero = 0;
420532b31808SJens Wiklander }
420611fa71b9SJerome Forissier
420711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
420832b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
420911fa71b9SJerome Forissier ; /* in_ctr read from peer, not maintained internally */
421032b31808SJens Wiklander } else
421111fa71b9SJerome Forissier #endif
421211fa71b9SJerome Forissier {
421311fa71b9SJerome Forissier unsigned i;
421432b31808SJens Wiklander for (i = MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
421532b31808SJens Wiklander i > mbedtls_ssl_ep_len(ssl); i--) {
421632b31808SJens Wiklander if (++ssl->in_ctr[i - 1] != 0) {
421711fa71b9SJerome Forissier break;
421832b31808SJens Wiklander }
421932b31808SJens Wiklander }
422011fa71b9SJerome Forissier
422111fa71b9SJerome Forissier /* The loop goes to its end iff the counter is wrapping */
422232b31808SJens Wiklander if (i == mbedtls_ssl_ep_len(ssl)) {
422311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("incoming message counter would wrap"));
422432b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
422511fa71b9SJerome Forissier }
422611fa71b9SJerome Forissier }
422711fa71b9SJerome Forissier
422811fa71b9SJerome Forissier }
422911fa71b9SJerome Forissier
4230b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C)
4231b0563631STom Van Eyck /*
4232b0563631STom Van Eyck * Although the server rejected early data because it needed to send an
4233b0563631STom Van Eyck * HelloRetryRequest message, it might receive early data as long as it has
4234b0563631STom Van Eyck * not received the client Finished message.
4235b0563631STom Van Eyck * The early data is encrypted with early keys and should be ignored as
4236b0563631STom Van Eyck * stated in section 4.2.10 of RFC 8446 (second case):
4237b0563631STom Van Eyck *
4238b0563631STom Van Eyck * "The server then ignores early data by skipping all records with an
4239b0563631STom Van Eyck * external content type of "application_data" (indicating that they are
4240b0563631STom Van Eyck * encrypted), up to the configured max_early_data_size. Ignore application
4241b0563631STom Van Eyck * data message before 2nd ClientHello when early_data was received in 1st
4242b0563631STom Van Eyck * ClientHello."
4243b0563631STom Van Eyck */
4244b0563631STom Van Eyck if (ssl->discard_early_data_record == MBEDTLS_SSL_EARLY_DATA_DISCARD) {
4245b0563631STom Van Eyck if (rec->type == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
4246b0563631STom Van Eyck
4247b0563631STom Van Eyck ret = mbedtls_ssl_tls13_check_early_data_len(ssl, rec->data_len);
4248b0563631STom Van Eyck if (ret != 0) {
4249b0563631STom Van Eyck return ret;
4250b0563631STom Van Eyck }
4251b0563631STom Van Eyck
4252b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(
4253b0563631STom Van Eyck 3, ("EarlyData: Ignore application message before 2nd ClientHello"));
4254b0563631STom Van Eyck
4255b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
4256b0563631STom Van Eyck } else if (rec->type == MBEDTLS_SSL_MSG_HANDSHAKE) {
4257b0563631STom Van Eyck ssl->discard_early_data_record = MBEDTLS_SSL_EARLY_DATA_NO_DISCARD;
4258b0563631STom Van Eyck }
4259b0563631STom Van Eyck }
4260b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_SRV_C */
4261b0563631STom Van Eyck
426211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
426332b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
426411fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_update(ssl);
426511fa71b9SJerome Forissier }
426611fa71b9SJerome Forissier #endif
426711fa71b9SJerome Forissier
426811fa71b9SJerome Forissier /* Check actual (decrypted) record content length against
426911fa71b9SJerome Forissier * configured maximum. */
427032b31808SJens Wiklander if (rec->data_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
427111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad message length"));
427232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
427311fa71b9SJerome Forissier }
427411fa71b9SJerome Forissier
427532b31808SJens Wiklander return 0;
427611fa71b9SJerome Forissier }
427711fa71b9SJerome Forissier
427811fa71b9SJerome Forissier /*
427911fa71b9SJerome Forissier * Read a record.
428011fa71b9SJerome Forissier *
428111fa71b9SJerome Forissier * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
428211fa71b9SJerome Forissier * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
428311fa71b9SJerome Forissier *
428411fa71b9SJerome Forissier */
428511fa71b9SJerome Forissier
428611fa71b9SJerome Forissier /* Helper functions for mbedtls_ssl_read_record(). */
4287039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
428811fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl);
4289039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
429011fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl);
4291039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
429211fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl);
429311fa71b9SJerome Forissier
mbedtls_ssl_read_record(mbedtls_ssl_context * ssl,unsigned update_hs_digest)429411fa71b9SJerome Forissier int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl,
429511fa71b9SJerome Forissier unsigned update_hs_digest)
429611fa71b9SJerome Forissier {
429711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
429811fa71b9SJerome Forissier
429911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> read record"));
430011fa71b9SJerome Forissier
430132b31808SJens Wiklander if (ssl->keep_current_message == 0) {
430211fa71b9SJerome Forissier do {
430311fa71b9SJerome Forissier
430411fa71b9SJerome Forissier ret = ssl_consume_current_message(ssl);
430532b31808SJens Wiklander if (ret != 0) {
430632b31808SJens Wiklander return ret;
430732b31808SJens Wiklander }
430811fa71b9SJerome Forissier
430932b31808SJens Wiklander if (ssl_record_is_in_progress(ssl) == 0) {
431032b31808SJens Wiklander int dtls_have_buffered = 0;
431111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
431211fa71b9SJerome Forissier
431311fa71b9SJerome Forissier /* We only check for buffered messages if the
431411fa71b9SJerome Forissier * current datagram is fully consumed. */
431511fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
431632b31808SJens Wiklander ssl_next_record_is_in_datagram(ssl) == 0) {
431732b31808SJens Wiklander if (ssl_load_buffered_message(ssl) == 0) {
431832b31808SJens Wiklander dtls_have_buffered = 1;
431932b31808SJens Wiklander }
432011fa71b9SJerome Forissier }
432111fa71b9SJerome Forissier
432211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
432332b31808SJens Wiklander if (dtls_have_buffered == 0) {
432411fa71b9SJerome Forissier ret = ssl_get_next_record(ssl);
432532b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) {
432611fa71b9SJerome Forissier continue;
432732b31808SJens Wiklander }
432811fa71b9SJerome Forissier
432932b31808SJens Wiklander if (ret != 0) {
433011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, ("ssl_get_next_record"), ret);
433132b31808SJens Wiklander return ret;
433211fa71b9SJerome Forissier }
433311fa71b9SJerome Forissier }
433411fa71b9SJerome Forissier }
433511fa71b9SJerome Forissier
433611fa71b9SJerome Forissier ret = mbedtls_ssl_handle_message_type(ssl);
433711fa71b9SJerome Forissier
433811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
433932b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
434011fa71b9SJerome Forissier /* Buffer future message */
434111fa71b9SJerome Forissier ret = ssl_buffer_message(ssl);
434232b31808SJens Wiklander if (ret != 0) {
434332b31808SJens Wiklander return ret;
434432b31808SJens Wiklander }
434511fa71b9SJerome Forissier
434611fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
434711fa71b9SJerome Forissier }
434811fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
434911fa71b9SJerome Forissier
435011fa71b9SJerome Forissier } while (MBEDTLS_ERR_SSL_NON_FATAL == ret ||
435111fa71b9SJerome Forissier MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret);
435211fa71b9SJerome Forissier
435332b31808SJens Wiklander if (0 != ret) {
435411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_handle_message_type"), ret);
435532b31808SJens Wiklander return ret;
435611fa71b9SJerome Forissier }
435711fa71b9SJerome Forissier
435811fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
435932b31808SJens Wiklander update_hs_digest == 1) {
436032b31808SJens Wiklander ret = mbedtls_ssl_update_handshake_status(ssl);
436132b31808SJens Wiklander if (0 != ret) {
436232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
436332b31808SJens Wiklander return ret;
436411fa71b9SJerome Forissier }
436511fa71b9SJerome Forissier }
436632b31808SJens Wiklander } else {
436711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message"));
436811fa71b9SJerome Forissier ssl->keep_current_message = 0;
436911fa71b9SJerome Forissier }
437011fa71b9SJerome Forissier
437111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= read record"));
437211fa71b9SJerome Forissier
437332b31808SJens Wiklander return 0;
437411fa71b9SJerome Forissier }
437511fa71b9SJerome Forissier
437611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
4377039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_next_record_is_in_datagram(mbedtls_ssl_context * ssl)437811fa71b9SJerome Forissier static int ssl_next_record_is_in_datagram(mbedtls_ssl_context *ssl)
437911fa71b9SJerome Forissier {
438032b31808SJens Wiklander if (ssl->in_left > ssl->next_record_offset) {
438132b31808SJens Wiklander return 1;
438232b31808SJens Wiklander }
438311fa71b9SJerome Forissier
438432b31808SJens Wiklander return 0;
438511fa71b9SJerome Forissier }
438611fa71b9SJerome Forissier
4387039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_load_buffered_message(mbedtls_ssl_context * ssl)438811fa71b9SJerome Forissier static int ssl_load_buffered_message(mbedtls_ssl_context *ssl)
438911fa71b9SJerome Forissier {
439011fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
439111fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf;
439211fa71b9SJerome Forissier int ret = 0;
439311fa71b9SJerome Forissier
439432b31808SJens Wiklander if (hs == NULL) {
439532b31808SJens Wiklander return -1;
439632b31808SJens Wiklander }
439711fa71b9SJerome Forissier
439832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_message"));
439911fa71b9SJerome Forissier
440011fa71b9SJerome Forissier if (ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
440132b31808SJens Wiklander ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
440211fa71b9SJerome Forissier /* Check if we have seen a ChangeCipherSpec before.
440311fa71b9SJerome Forissier * If yes, synthesize a CCS record. */
440432b31808SJens Wiklander if (!hs->buffering.seen_ccs) {
440511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("CCS not seen in the current flight"));
440611fa71b9SJerome Forissier ret = -1;
440711fa71b9SJerome Forissier goto exit;
440811fa71b9SJerome Forissier }
440911fa71b9SJerome Forissier
441011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Injecting buffered CCS message"));
441111fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
441211fa71b9SJerome Forissier ssl->in_msglen = 1;
441311fa71b9SJerome Forissier ssl->in_msg[0] = 1;
441411fa71b9SJerome Forissier
441511fa71b9SJerome Forissier /* As long as they are equal, the exact value doesn't matter. */
441611fa71b9SJerome Forissier ssl->in_left = 0;
441711fa71b9SJerome Forissier ssl->next_record_offset = 0;
441811fa71b9SJerome Forissier
441911fa71b9SJerome Forissier hs->buffering.seen_ccs = 0;
442011fa71b9SJerome Forissier goto exit;
442111fa71b9SJerome Forissier }
442211fa71b9SJerome Forissier
442311fa71b9SJerome Forissier #if defined(MBEDTLS_DEBUG_C)
442411fa71b9SJerome Forissier /* Debug only */
442511fa71b9SJerome Forissier {
442611fa71b9SJerome Forissier unsigned offset;
442732b31808SJens Wiklander for (offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
442811fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[offset];
442932b31808SJens Wiklander if (hs_buf->is_valid == 1) {
443011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Future message with sequence number %u %s buffered.",
443111fa71b9SJerome Forissier hs->in_msg_seq + offset,
443211fa71b9SJerome Forissier hs_buf->is_complete ? "fully" : "partially"));
443311fa71b9SJerome Forissier }
443411fa71b9SJerome Forissier }
443511fa71b9SJerome Forissier }
443611fa71b9SJerome Forissier #endif /* MBEDTLS_DEBUG_C */
443711fa71b9SJerome Forissier
443811fa71b9SJerome Forissier /* Check if we have buffered and/or fully reassembled the
443911fa71b9SJerome Forissier * next handshake message. */
444011fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[0];
444132b31808SJens Wiklander if ((hs_buf->is_valid == 1) && (hs_buf->is_complete == 1)) {
444211fa71b9SJerome Forissier /* Synthesize a record containing the buffered HS message. */
4443b0563631STom Van Eyck size_t msg_len = MBEDTLS_GET_UINT24_BE(hs_buf->data, 1);
444411fa71b9SJerome Forissier
444511fa71b9SJerome Forissier /* Double-check that we haven't accidentally buffered
444611fa71b9SJerome Forissier * a message that doesn't fit into the input buffer. */
444732b31808SJens Wiklander if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
444811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
444932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
445011fa71b9SJerome Forissier }
445111fa71b9SJerome Forissier
445211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message has been buffered - load"));
445311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "Buffered handshake message (incl. header)",
445411fa71b9SJerome Forissier hs_buf->data, msg_len + 12);
445511fa71b9SJerome Forissier
445611fa71b9SJerome Forissier ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
445711fa71b9SJerome Forissier ssl->in_hslen = msg_len + 12;
445811fa71b9SJerome Forissier ssl->in_msglen = msg_len + 12;
445911fa71b9SJerome Forissier memcpy(ssl->in_msg, hs_buf->data, ssl->in_hslen);
446011fa71b9SJerome Forissier
446111fa71b9SJerome Forissier ret = 0;
446211fa71b9SJerome Forissier goto exit;
446332b31808SJens Wiklander } else {
446411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Next handshake message %u not or only partially bufffered",
446511fa71b9SJerome Forissier hs->in_msg_seq));
446611fa71b9SJerome Forissier }
446711fa71b9SJerome Forissier
446811fa71b9SJerome Forissier ret = -1;
446911fa71b9SJerome Forissier
447011fa71b9SJerome Forissier exit:
447111fa71b9SJerome Forissier
447211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_message"));
447332b31808SJens Wiklander return ret;
447411fa71b9SJerome Forissier }
447511fa71b9SJerome Forissier
4476039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_buffer_make_space(mbedtls_ssl_context * ssl,size_t desired)447711fa71b9SJerome Forissier static int ssl_buffer_make_space(mbedtls_ssl_context *ssl,
447811fa71b9SJerome Forissier size_t desired)
447911fa71b9SJerome Forissier {
448011fa71b9SJerome Forissier int offset;
448111fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
448211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Attempt to free buffered messages to have %u bytes available",
448311fa71b9SJerome Forissier (unsigned) desired));
448411fa71b9SJerome Forissier
448511fa71b9SJerome Forissier /* Get rid of future records epoch first, if such exist. */
448611fa71b9SJerome Forissier ssl_free_buffered_record(ssl);
448711fa71b9SJerome Forissier
448811fa71b9SJerome Forissier /* Check if we have enough space available now. */
448911fa71b9SJerome Forissier if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
449032b31808SJens Wiklander hs->buffering.total_bytes_buffered)) {
449111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing future epoch record"));
449232b31808SJens Wiklander return 0;
449311fa71b9SJerome Forissier }
449411fa71b9SJerome Forissier
449511fa71b9SJerome Forissier /* We don't have enough space to buffer the next expected handshake
449611fa71b9SJerome Forissier * message. Remove buffers used for future messages to gain space,
449711fa71b9SJerome Forissier * starting with the most distant one. */
449811fa71b9SJerome Forissier for (offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
449932b31808SJens Wiklander offset >= 0; offset--) {
450032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
450132b31808SJens Wiklander (
450232b31808SJens Wiklander "Free buffering slot %d to make space for reassembly of next handshake message",
450311fa71b9SJerome Forissier offset));
450411fa71b9SJerome Forissier
450511fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, (uint8_t) offset);
450611fa71b9SJerome Forissier
450711fa71b9SJerome Forissier /* Check if we have enough space available now. */
450811fa71b9SJerome Forissier if (desired <= (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
450932b31808SJens Wiklander hs->buffering.total_bytes_buffered)) {
451011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Enough space available after freeing buffered HS messages"));
451132b31808SJens Wiklander return 0;
451211fa71b9SJerome Forissier }
451311fa71b9SJerome Forissier }
451411fa71b9SJerome Forissier
451532b31808SJens Wiklander return -1;
451611fa71b9SJerome Forissier }
451711fa71b9SJerome Forissier
4518039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_buffer_message(mbedtls_ssl_context * ssl)451911fa71b9SJerome Forissier static int ssl_buffer_message(mbedtls_ssl_context *ssl)
452011fa71b9SJerome Forissier {
452111fa71b9SJerome Forissier int ret = 0;
452211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
452311fa71b9SJerome Forissier
452432b31808SJens Wiklander if (hs == NULL) {
452532b31808SJens Wiklander return 0;
452632b31808SJens Wiklander }
452711fa71b9SJerome Forissier
452811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_buffer_message"));
452911fa71b9SJerome Forissier
453032b31808SJens Wiklander switch (ssl->in_msgtype) {
453111fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
453211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Remember CCS message"));
453311fa71b9SJerome Forissier
453411fa71b9SJerome Forissier hs->buffering.seen_ccs = 1;
453511fa71b9SJerome Forissier break;
453611fa71b9SJerome Forissier
453711fa71b9SJerome Forissier case MBEDTLS_SSL_MSG_HANDSHAKE:
453811fa71b9SJerome Forissier {
453911fa71b9SJerome Forissier unsigned recv_msg_seq_offset;
4540b0563631STom Van Eyck unsigned recv_msg_seq = MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
454111fa71b9SJerome Forissier mbedtls_ssl_hs_buffer *hs_buf;
454211fa71b9SJerome Forissier size_t msg_len = ssl->in_hslen - 12;
454311fa71b9SJerome Forissier
454411fa71b9SJerome Forissier /* We should never receive an old handshake
454511fa71b9SJerome Forissier * message - double-check nonetheless. */
454632b31808SJens Wiklander if (recv_msg_seq < ssl->handshake->in_msg_seq) {
454711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
454832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
454911fa71b9SJerome Forissier }
455011fa71b9SJerome Forissier
455111fa71b9SJerome Forissier recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
455232b31808SJens Wiklander if (recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
455311fa71b9SJerome Forissier /* Silently ignore -- message too far in the future */
455411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2,
455511fa71b9SJerome Forissier ("Ignore future HS message with sequence number %u, "
455611fa71b9SJerome Forissier "buffering window %u - %u",
455711fa71b9SJerome Forissier recv_msg_seq, ssl->handshake->in_msg_seq,
455832b31808SJens Wiklander ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS -
455932b31808SJens Wiklander 1));
456011fa71b9SJerome Forissier
456111fa71b9SJerome Forissier goto exit;
456211fa71b9SJerome Forissier }
456311fa71b9SJerome Forissier
456411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering HS message with sequence number %u, offset %u ",
456511fa71b9SJerome Forissier recv_msg_seq, recv_msg_seq_offset));
456611fa71b9SJerome Forissier
456711fa71b9SJerome Forissier hs_buf = &hs->buffering.hs[recv_msg_seq_offset];
456811fa71b9SJerome Forissier
456911fa71b9SJerome Forissier /* Check if the buffering for this seq nr has already commenced. */
457032b31808SJens Wiklander if (!hs_buf->is_valid) {
457111fa71b9SJerome Forissier size_t reassembly_buf_sz;
457211fa71b9SJerome Forissier
457311fa71b9SJerome Forissier hs_buf->is_fragmented =
457411fa71b9SJerome Forissier (ssl_hs_is_proper_fragment(ssl) == 1);
457511fa71b9SJerome Forissier
457611fa71b9SJerome Forissier /* We copy the message back into the input buffer
457711fa71b9SJerome Forissier * after reassembly, so check that it's not too large.
457811fa71b9SJerome Forissier * This is an implementation-specific limitation
457911fa71b9SJerome Forissier * and not one from the standard, hence it is not
458011fa71b9SJerome Forissier * checked in ssl_check_hs_header(). */
458132b31808SJens Wiklander if (msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN) {
458211fa71b9SJerome Forissier /* Ignore message */
458311fa71b9SJerome Forissier goto exit;
458411fa71b9SJerome Forissier }
458511fa71b9SJerome Forissier
458611fa71b9SJerome Forissier /* Check if we have enough space to buffer the message. */
458711fa71b9SJerome Forissier if (hs->buffering.total_bytes_buffered >
458832b31808SJens Wiklander MBEDTLS_SSL_DTLS_MAX_BUFFERING) {
458911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
459032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
459111fa71b9SJerome Forissier }
459211fa71b9SJerome Forissier
459311fa71b9SJerome Forissier reassembly_buf_sz = ssl_get_reassembly_buffer_size(msg_len,
459411fa71b9SJerome Forissier hs_buf->is_fragmented);
459511fa71b9SJerome Forissier
459611fa71b9SJerome Forissier if (reassembly_buf_sz > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
459732b31808SJens Wiklander hs->buffering.total_bytes_buffered)) {
459832b31808SJens Wiklander if (recv_msg_seq_offset > 0) {
459911fa71b9SJerome Forissier /* If we can't buffer a future message because
460011fa71b9SJerome Forissier * of space limitations -- ignore. */
460132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
460232b31808SJens Wiklander ("Buffering of future message of size %"
460332b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
460432b31808SJens Wiklander " would exceed the compile-time limit %"
460532b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
46067901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET
46077901324dSJerome Forissier " bytes buffered) -- ignore\n",
46087901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
46097901324dSJerome Forissier hs->buffering.total_bytes_buffered));
461011fa71b9SJerome Forissier goto exit;
461132b31808SJens Wiklander } else {
461232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
461332b31808SJens Wiklander ("Buffering of future message of size %"
461432b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
461532b31808SJens Wiklander " would exceed the compile-time limit %"
461632b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
46177901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET
46187901324dSJerome Forissier " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
46197901324dSJerome Forissier msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
46207901324dSJerome Forissier hs->buffering.total_bytes_buffered));
462111fa71b9SJerome Forissier }
462211fa71b9SJerome Forissier
462332b31808SJens Wiklander if (ssl_buffer_make_space(ssl, reassembly_buf_sz) != 0) {
462432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
462532b31808SJens Wiklander ("Reassembly of next message of size %"
462632b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
462732b31808SJens Wiklander " (%" MBEDTLS_PRINTF_SIZET
462832b31808SJens Wiklander " with bitmap) would exceed"
462932b31808SJens Wiklander " the compile-time limit %"
463032b31808SJens Wiklander MBEDTLS_PRINTF_SIZET
46317901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET
46327901324dSJerome Forissier " bytes buffered) -- fail\n",
46337901324dSJerome Forissier msg_len,
46347901324dSJerome Forissier reassembly_buf_sz,
46357901324dSJerome Forissier (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
46367901324dSJerome Forissier hs->buffering.total_bytes_buffered));
463711fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
463811fa71b9SJerome Forissier goto exit;
463911fa71b9SJerome Forissier }
464011fa71b9SJerome Forissier }
464111fa71b9SJerome Forissier
464232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2,
464332b31808SJens Wiklander ("initialize reassembly, total length = %"
464432b31808SJens Wiklander MBEDTLS_PRINTF_SIZET,
464511fa71b9SJerome Forissier msg_len));
464611fa71b9SJerome Forissier
464711fa71b9SJerome Forissier hs_buf->data = mbedtls_calloc(1, reassembly_buf_sz);
464832b31808SJens Wiklander if (hs_buf->data == NULL) {
464911fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
465011fa71b9SJerome Forissier goto exit;
465111fa71b9SJerome Forissier }
465211fa71b9SJerome Forissier hs_buf->data_len = reassembly_buf_sz;
465311fa71b9SJerome Forissier
465411fa71b9SJerome Forissier /* Prepare final header: copy msg_type, length and message_seq,
465511fa71b9SJerome Forissier * then add standardised fragment_offset and fragment_length */
465611fa71b9SJerome Forissier memcpy(hs_buf->data, ssl->in_msg, 6);
465711fa71b9SJerome Forissier memset(hs_buf->data + 6, 0, 3);
465811fa71b9SJerome Forissier memcpy(hs_buf->data + 9, hs_buf->data + 1, 3);
465911fa71b9SJerome Forissier
466011fa71b9SJerome Forissier hs_buf->is_valid = 1;
466111fa71b9SJerome Forissier
466211fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += reassembly_buf_sz;
466332b31808SJens Wiklander } else {
466411fa71b9SJerome Forissier /* Make sure msg_type and length are consistent */
466532b31808SJens Wiklander if (memcmp(hs_buf->data, ssl->in_msg, 4) != 0) {
466611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("Fragment header mismatch - ignore"));
466711fa71b9SJerome Forissier /* Ignore */
466811fa71b9SJerome Forissier goto exit;
466911fa71b9SJerome Forissier }
467011fa71b9SJerome Forissier }
467111fa71b9SJerome Forissier
467232b31808SJens Wiklander if (!hs_buf->is_complete) {
467311fa71b9SJerome Forissier size_t frag_len, frag_off;
467411fa71b9SJerome Forissier unsigned char * const msg = hs_buf->data + 12;
467511fa71b9SJerome Forissier
467611fa71b9SJerome Forissier /*
467711fa71b9SJerome Forissier * Check and copy current fragment
467811fa71b9SJerome Forissier */
467911fa71b9SJerome Forissier
468011fa71b9SJerome Forissier /* Validation of header fields already done in
468111fa71b9SJerome Forissier * mbedtls_ssl_prepare_handshake_record(). */
468211fa71b9SJerome Forissier frag_off = ssl_get_hs_frag_off(ssl);
468311fa71b9SJerome Forissier frag_len = ssl_get_hs_frag_len(ssl);
468411fa71b9SJerome Forissier
46857901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
46867901324dSJerome Forissier ", length = %" MBEDTLS_PRINTF_SIZET,
468711fa71b9SJerome Forissier frag_off, frag_len));
468811fa71b9SJerome Forissier memcpy(msg + frag_off, ssl->in_msg + 12, frag_len);
468911fa71b9SJerome Forissier
469032b31808SJens Wiklander if (hs_buf->is_fragmented) {
469111fa71b9SJerome Forissier unsigned char * const bitmask = msg + msg_len;
469211fa71b9SJerome Forissier ssl_bitmask_set(bitmask, frag_off, frag_len);
469311fa71b9SJerome Forissier hs_buf->is_complete = (ssl_bitmask_check(bitmask,
469411fa71b9SJerome Forissier msg_len) == 0);
469532b31808SJens Wiklander } else {
469611fa71b9SJerome Forissier hs_buf->is_complete = 1;
469711fa71b9SJerome Forissier }
469811fa71b9SJerome Forissier
469911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("message %scomplete",
470011fa71b9SJerome Forissier hs_buf->is_complete ? "" : "not yet "));
470111fa71b9SJerome Forissier }
470211fa71b9SJerome Forissier
470311fa71b9SJerome Forissier break;
470411fa71b9SJerome Forissier }
470511fa71b9SJerome Forissier
470611fa71b9SJerome Forissier default:
470711fa71b9SJerome Forissier /* We don't buffer other types of messages. */
470811fa71b9SJerome Forissier break;
470911fa71b9SJerome Forissier }
471011fa71b9SJerome Forissier
471111fa71b9SJerome Forissier exit:
471211fa71b9SJerome Forissier
471311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_buffer_message"));
471432b31808SJens Wiklander return ret;
471511fa71b9SJerome Forissier }
471611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
471711fa71b9SJerome Forissier
4718039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_consume_current_message(mbedtls_ssl_context * ssl)471911fa71b9SJerome Forissier static int ssl_consume_current_message(mbedtls_ssl_context *ssl)
472011fa71b9SJerome Forissier {
472111fa71b9SJerome Forissier /*
472211fa71b9SJerome Forissier * Consume last content-layer message and potentially
472311fa71b9SJerome Forissier * update in_msglen which keeps track of the contents'
472411fa71b9SJerome Forissier * consumption state.
472511fa71b9SJerome Forissier *
472611fa71b9SJerome Forissier * (1) Handshake messages:
472711fa71b9SJerome Forissier * Remove last handshake message, move content
472811fa71b9SJerome Forissier * and adapt in_msglen.
472911fa71b9SJerome Forissier *
473011fa71b9SJerome Forissier * (2) Alert messages:
473111fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0.
473211fa71b9SJerome Forissier *
473311fa71b9SJerome Forissier * (3) Change cipher spec:
473411fa71b9SJerome Forissier * Consume whole record content, in_msglen = 0.
473511fa71b9SJerome Forissier *
473611fa71b9SJerome Forissier * (4) Application data:
473711fa71b9SJerome Forissier * Don't do anything - the record layer provides
473811fa71b9SJerome Forissier * the application data as a stream transport
473911fa71b9SJerome Forissier * and consumes through mbedtls_ssl_read only.
474011fa71b9SJerome Forissier *
474111fa71b9SJerome Forissier */
474211fa71b9SJerome Forissier
474311fa71b9SJerome Forissier /* Case (1): Handshake messages */
474432b31808SJens Wiklander if (ssl->in_hslen != 0) {
474511fa71b9SJerome Forissier /* Hard assertion to be sure that no application data
474611fa71b9SJerome Forissier * is in flight, as corrupting ssl->in_msglen during
474711fa71b9SJerome Forissier * ssl->in_offt != NULL is fatal. */
474832b31808SJens Wiklander if (ssl->in_offt != NULL) {
474911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
475032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
475111fa71b9SJerome Forissier }
475211fa71b9SJerome Forissier
4753c3deb3d6SEtienne Carriere if (ssl->badmac_seen_or_in_hsfraglen != 0) {
4754c3deb3d6SEtienne Carriere /* Not all handshake fragments have arrived, do not consume. */
4755c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(3, ("Consume: waiting for more handshake fragments "
4756c3deb3d6SEtienne Carriere "%u/%" MBEDTLS_PRINTF_SIZET,
4757c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen, ssl->in_hslen));
4758c3deb3d6SEtienne Carriere return 0;
4759c3deb3d6SEtienne Carriere }
4760c3deb3d6SEtienne Carriere
476111fa71b9SJerome Forissier /*
476211fa71b9SJerome Forissier * Get next Handshake message in the current record
476311fa71b9SJerome Forissier */
476411fa71b9SJerome Forissier
476511fa71b9SJerome Forissier /* Notes:
476611fa71b9SJerome Forissier * (1) in_hslen is not necessarily the size of the
476711fa71b9SJerome Forissier * current handshake content: If DTLS handshake
476811fa71b9SJerome Forissier * fragmentation is used, that's the fragment
476911fa71b9SJerome Forissier * size instead. Using the total handshake message
477011fa71b9SJerome Forissier * size here is faulty and should be changed at
477111fa71b9SJerome Forissier * some point.
477211fa71b9SJerome Forissier * (2) While it doesn't seem to cause problems, one
477311fa71b9SJerome Forissier * has to be very careful not to assume that in_hslen
477411fa71b9SJerome Forissier * is always <= in_msglen in a sensible communication.
477511fa71b9SJerome Forissier * Again, it's wrong for DTLS handshake fragmentation.
477611fa71b9SJerome Forissier * The following check is therefore mandatory, and
477711fa71b9SJerome Forissier * should not be treated as a silently corrected assertion.
477811fa71b9SJerome Forissier * Additionally, ssl->in_hslen might be arbitrarily out of
477911fa71b9SJerome Forissier * bounds after handling a DTLS message with an unexpected
478011fa71b9SJerome Forissier * sequence number, see mbedtls_ssl_prepare_handshake_record.
478111fa71b9SJerome Forissier */
478232b31808SJens Wiklander if (ssl->in_hslen < ssl->in_msglen) {
478311fa71b9SJerome Forissier ssl->in_msglen -= ssl->in_hslen;
478411fa71b9SJerome Forissier memmove(ssl->in_msg, ssl->in_msg + ssl->in_hslen,
478511fa71b9SJerome Forissier ssl->in_msglen);
4786c3deb3d6SEtienne Carriere MBEDTLS_PUT_UINT16_BE(ssl->in_msglen, ssl->in_len, 0);
478711fa71b9SJerome Forissier
478811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(4, "remaining content in record",
478911fa71b9SJerome Forissier ssl->in_msg, ssl->in_msglen);
479032b31808SJens Wiklander } else {
479111fa71b9SJerome Forissier ssl->in_msglen = 0;
479211fa71b9SJerome Forissier }
479311fa71b9SJerome Forissier
479411fa71b9SJerome Forissier ssl->in_hslen = 0;
479511fa71b9SJerome Forissier }
479611fa71b9SJerome Forissier /* Case (4): Application data */
479732b31808SJens Wiklander else if (ssl->in_offt != NULL) {
479832b31808SJens Wiklander return 0;
479911fa71b9SJerome Forissier }
480011fa71b9SJerome Forissier /* Everything else (CCS & Alerts) */
480132b31808SJens Wiklander else {
480211fa71b9SJerome Forissier ssl->in_msglen = 0;
480311fa71b9SJerome Forissier }
480411fa71b9SJerome Forissier
480532b31808SJens Wiklander return 0;
480611fa71b9SJerome Forissier }
480711fa71b9SJerome Forissier
4808039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_record_is_in_progress(mbedtls_ssl_context * ssl)480911fa71b9SJerome Forissier static int ssl_record_is_in_progress(mbedtls_ssl_context *ssl)
481011fa71b9SJerome Forissier {
481132b31808SJens Wiklander if (ssl->in_msglen > 0) {
481232b31808SJens Wiklander return 1;
481332b31808SJens Wiklander }
481411fa71b9SJerome Forissier
481532b31808SJens Wiklander return 0;
481611fa71b9SJerome Forissier }
481711fa71b9SJerome Forissier
481811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
481911fa71b9SJerome Forissier
ssl_free_buffered_record(mbedtls_ssl_context * ssl)482011fa71b9SJerome Forissier static void ssl_free_buffered_record(mbedtls_ssl_context *ssl)
482111fa71b9SJerome Forissier {
482211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
482332b31808SJens Wiklander if (hs == NULL) {
482411fa71b9SJerome Forissier return;
482532b31808SJens Wiklander }
482611fa71b9SJerome Forissier
482732b31808SJens Wiklander if (hs->buffering.future_record.data != NULL) {
482811fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -=
482911fa71b9SJerome Forissier hs->buffering.future_record.len;
483011fa71b9SJerome Forissier
483111fa71b9SJerome Forissier mbedtls_free(hs->buffering.future_record.data);
483211fa71b9SJerome Forissier hs->buffering.future_record.data = NULL;
483311fa71b9SJerome Forissier }
483411fa71b9SJerome Forissier }
483511fa71b9SJerome Forissier
4836039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_load_buffered_record(mbedtls_ssl_context * ssl)483711fa71b9SJerome Forissier static int ssl_load_buffered_record(mbedtls_ssl_context *ssl)
483811fa71b9SJerome Forissier {
483911fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
484011fa71b9SJerome Forissier unsigned char *rec;
484111fa71b9SJerome Forissier size_t rec_len;
484211fa71b9SJerome Forissier unsigned rec_epoch;
484311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
484411fa71b9SJerome Forissier size_t in_buf_len = ssl->in_buf_len;
484511fa71b9SJerome Forissier #else
484611fa71b9SJerome Forissier size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
484711fa71b9SJerome Forissier #endif
484832b31808SJens Wiklander if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
484932b31808SJens Wiklander return 0;
485032b31808SJens Wiklander }
485111fa71b9SJerome Forissier
485232b31808SJens Wiklander if (hs == NULL) {
485332b31808SJens Wiklander return 0;
485432b31808SJens Wiklander }
485511fa71b9SJerome Forissier
485611fa71b9SJerome Forissier rec = hs->buffering.future_record.data;
485711fa71b9SJerome Forissier rec_len = hs->buffering.future_record.len;
485811fa71b9SJerome Forissier rec_epoch = hs->buffering.future_record.epoch;
485911fa71b9SJerome Forissier
486032b31808SJens Wiklander if (rec == NULL) {
486132b31808SJens Wiklander return 0;
486232b31808SJens Wiklander }
486311fa71b9SJerome Forissier
486411fa71b9SJerome Forissier /* Only consider loading future records if the
486511fa71b9SJerome Forissier * input buffer is empty. */
486632b31808SJens Wiklander if (ssl_next_record_is_in_datagram(ssl) == 1) {
486732b31808SJens Wiklander return 0;
486832b31808SJens Wiklander }
486911fa71b9SJerome Forissier
487011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_load_buffered_record"));
487111fa71b9SJerome Forissier
487232b31808SJens Wiklander if (rec_epoch != ssl->in_epoch) {
487311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffered record not from current epoch."));
487411fa71b9SJerome Forissier goto exit;
487511fa71b9SJerome Forissier }
487611fa71b9SJerome Forissier
487711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Found buffered record from current epoch - load"));
487811fa71b9SJerome Forissier
487911fa71b9SJerome Forissier /* Double-check that the record is not too large */
488032b31808SJens Wiklander if (rec_len > in_buf_len - (size_t) (ssl->in_hdr - ssl->in_buf)) {
488111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
488232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
488311fa71b9SJerome Forissier }
488411fa71b9SJerome Forissier
488511fa71b9SJerome Forissier memcpy(ssl->in_hdr, rec, rec_len);
488611fa71b9SJerome Forissier ssl->in_left = rec_len;
488711fa71b9SJerome Forissier ssl->next_record_offset = 0;
488811fa71b9SJerome Forissier
488911fa71b9SJerome Forissier ssl_free_buffered_record(ssl);
489011fa71b9SJerome Forissier
489111fa71b9SJerome Forissier exit:
489211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_load_buffered_record"));
489332b31808SJens Wiklander return 0;
489411fa71b9SJerome Forissier }
489511fa71b9SJerome Forissier
4896039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_buffer_future_record(mbedtls_ssl_context * ssl,mbedtls_record const * rec)489711fa71b9SJerome Forissier static int ssl_buffer_future_record(mbedtls_ssl_context *ssl,
489811fa71b9SJerome Forissier mbedtls_record const *rec)
489911fa71b9SJerome Forissier {
490011fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
490111fa71b9SJerome Forissier
490211fa71b9SJerome Forissier /* Don't buffer future records outside handshakes. */
490332b31808SJens Wiklander if (hs == NULL) {
490432b31808SJens Wiklander return 0;
490532b31808SJens Wiklander }
490611fa71b9SJerome Forissier
490711fa71b9SJerome Forissier /* Only buffer handshake records (we are only interested
490811fa71b9SJerome Forissier * in Finished messages). */
490932b31808SJens Wiklander if (rec->type != MBEDTLS_SSL_MSG_HANDSHAKE) {
491032b31808SJens Wiklander return 0;
491132b31808SJens Wiklander }
491211fa71b9SJerome Forissier
491311fa71b9SJerome Forissier /* Don't buffer more than one future epoch record. */
491432b31808SJens Wiklander if (hs->buffering.future_record.data != NULL) {
491532b31808SJens Wiklander return 0;
491632b31808SJens Wiklander }
491711fa71b9SJerome Forissier
491811fa71b9SJerome Forissier /* Don't buffer record if there's not enough buffering space remaining. */
491911fa71b9SJerome Forissier if (rec->buf_len > (MBEDTLS_SSL_DTLS_MAX_BUFFERING -
492032b31808SJens Wiklander hs->buffering.total_bytes_buffered)) {
49217901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
49227901324dSJerome Forissier " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
49237901324dSJerome Forissier " (already %" MBEDTLS_PRINTF_SIZET
49247901324dSJerome Forissier " bytes buffered) -- ignore\n",
49257901324dSJerome Forissier rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
49267901324dSJerome Forissier hs->buffering.total_bytes_buffered));
492732b31808SJens Wiklander return 0;
492811fa71b9SJerome Forissier }
492911fa71b9SJerome Forissier
493011fa71b9SJerome Forissier /* Buffer record */
493111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("Buffer record from epoch %u",
49327901324dSJerome Forissier ssl->in_epoch + 1U));
493311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_BUF(3, "Buffered record", rec->buf, rec->buf_len);
493411fa71b9SJerome Forissier
493511fa71b9SJerome Forissier /* ssl_parse_record_header() only considers records
493611fa71b9SJerome Forissier * of the next epoch as candidates for buffering. */
493711fa71b9SJerome Forissier hs->buffering.future_record.epoch = ssl->in_epoch + 1;
493811fa71b9SJerome Forissier hs->buffering.future_record.len = rec->buf_len;
493911fa71b9SJerome Forissier
494011fa71b9SJerome Forissier hs->buffering.future_record.data =
494111fa71b9SJerome Forissier mbedtls_calloc(1, hs->buffering.future_record.len);
494232b31808SJens Wiklander if (hs->buffering.future_record.data == NULL) {
494311fa71b9SJerome Forissier /* If we run out of RAM trying to buffer a
494411fa71b9SJerome Forissier * record from the next epoch, just ignore. */
494532b31808SJens Wiklander return 0;
494611fa71b9SJerome Forissier }
494711fa71b9SJerome Forissier
494811fa71b9SJerome Forissier memcpy(hs->buffering.future_record.data, rec->buf, rec->buf_len);
494911fa71b9SJerome Forissier
495011fa71b9SJerome Forissier hs->buffering.total_bytes_buffered += rec->buf_len;
495132b31808SJens Wiklander return 0;
495211fa71b9SJerome Forissier }
495311fa71b9SJerome Forissier
495411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
495511fa71b9SJerome Forissier
4956039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_next_record(mbedtls_ssl_context * ssl)495711fa71b9SJerome Forissier static int ssl_get_next_record(mbedtls_ssl_context *ssl)
495811fa71b9SJerome Forissier {
495911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
496011fa71b9SJerome Forissier mbedtls_record rec;
496111fa71b9SJerome Forissier
496211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
496311fa71b9SJerome Forissier /* We might have buffered a future record; if so,
496411fa71b9SJerome Forissier * and if the epoch matches now, load it.
496511fa71b9SJerome Forissier * On success, this call will set ssl->in_left to
496611fa71b9SJerome Forissier * the length of the buffered record, so that
496711fa71b9SJerome Forissier * the calls to ssl_fetch_input() below will
496811fa71b9SJerome Forissier * essentially be no-ops. */
496911fa71b9SJerome Forissier ret = ssl_load_buffered_record(ssl);
497032b31808SJens Wiklander if (ret != 0) {
497132b31808SJens Wiklander return ret;
497232b31808SJens Wiklander }
497311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
497411fa71b9SJerome Forissier
497511fa71b9SJerome Forissier /* Ensure that we have enough space available for the default form
497611fa71b9SJerome Forissier * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
497711fa71b9SJerome Forissier * with no space for CIDs counted in). */
497811fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl));
497932b31808SJens Wiklander if (ret != 0) {
498011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
498132b31808SJens Wiklander return ret;
498211fa71b9SJerome Forissier }
498311fa71b9SJerome Forissier
498411fa71b9SJerome Forissier ret = ssl_parse_record_header(ssl, ssl->in_hdr, ssl->in_left, &rec);
498532b31808SJens Wiklander if (ret != 0) {
498611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
498732b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
498832b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE) {
498911fa71b9SJerome Forissier ret = ssl_buffer_future_record(ssl, &rec);
499032b31808SJens Wiklander if (ret != 0) {
499132b31808SJens Wiklander return ret;
499232b31808SJens Wiklander }
499311fa71b9SJerome Forissier
499411fa71b9SJerome Forissier /* Fall through to handling of unexpected records */
499511fa71b9SJerome Forissier ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
499611fa71b9SJerome Forissier }
499711fa71b9SJerome Forissier
499832b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) {
499911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
500011fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records,
500111fa71b9SJerome Forissier * assuming no CID and no offset between record content and
500211fa71b9SJerome Forissier * record plaintext. */
500311fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl);
500411fa71b9SJerome Forissier
500511fa71b9SJerome Forissier /* Setup internal message pointers from record structure. */
500611fa71b9SJerome Forissier ssl->in_msgtype = rec.type;
500711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
500811fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len;
500911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
501011fa71b9SJerome Forissier ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
501111fa71b9SJerome Forissier ssl->in_msglen = rec.data_len;
501211fa71b9SJerome Forissier
501311fa71b9SJerome Forissier ret = ssl_check_client_reconnect(ssl);
501411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(2, "ssl_check_client_reconnect", ret);
501532b31808SJens Wiklander if (ret != 0) {
501632b31808SJens Wiklander return ret;
501732b31808SJens Wiklander }
501811fa71b9SJerome Forissier #endif
501911fa71b9SJerome Forissier
502011fa71b9SJerome Forissier /* Skip unexpected record (but not whole datagram) */
502111fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len;
502211fa71b9SJerome Forissier
502311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding unexpected record "
502411fa71b9SJerome Forissier "(header)"));
502532b31808SJens Wiklander } else {
502611fa71b9SJerome Forissier /* Skip invalid record and the rest of the datagram */
502711fa71b9SJerome Forissier ssl->next_record_offset = 0;
502811fa71b9SJerome Forissier ssl->in_left = 0;
502911fa71b9SJerome Forissier
503011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record "
503111fa71b9SJerome Forissier "(header)"));
503211fa71b9SJerome Forissier }
503311fa71b9SJerome Forissier
503411fa71b9SJerome Forissier /* Get next record */
503532b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
503632b31808SJens Wiklander } else
503711fa71b9SJerome Forissier #endif
503811fa71b9SJerome Forissier {
503932b31808SJens Wiklander return ret;
504011fa71b9SJerome Forissier }
504111fa71b9SJerome Forissier }
504211fa71b9SJerome Forissier
504311fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
504432b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
504511fa71b9SJerome Forissier /* Remember offset of next record within datagram. */
504611fa71b9SJerome Forissier ssl->next_record_offset = rec.buf_len;
504732b31808SJens Wiklander if (ssl->next_record_offset < ssl->in_left) {
504811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("more than one record within datagram"));
504911fa71b9SJerome Forissier }
505032b31808SJens Wiklander } else
505111fa71b9SJerome Forissier #endif
505211fa71b9SJerome Forissier {
505311fa71b9SJerome Forissier /*
505411fa71b9SJerome Forissier * Fetch record contents from underlying transport.
505511fa71b9SJerome Forissier */
505611fa71b9SJerome Forissier ret = mbedtls_ssl_fetch_input(ssl, rec.buf_len);
505732b31808SJens Wiklander if (ret != 0) {
505811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
505932b31808SJens Wiklander return ret;
506011fa71b9SJerome Forissier }
506111fa71b9SJerome Forissier
506211fa71b9SJerome Forissier ssl->in_left = 0;
506311fa71b9SJerome Forissier }
506411fa71b9SJerome Forissier
506511fa71b9SJerome Forissier /*
506611fa71b9SJerome Forissier * Decrypt record contents.
506711fa71b9SJerome Forissier */
506811fa71b9SJerome Forissier
506932b31808SJens Wiklander if ((ret = ssl_prepare_record_content(ssl, &rec)) != 0) {
507011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
507132b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
507211fa71b9SJerome Forissier /* Silently discard invalid records */
507332b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
507411fa71b9SJerome Forissier /* Except when waiting for Finished as a bad mac here
507511fa71b9SJerome Forissier * probably means something went wrong in the handshake
507611fa71b9SJerome Forissier * (eg wrong psk used, mitm downgrade attempt, etc.) */
507711fa71b9SJerome Forissier if (ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
507832b31808SJens Wiklander ssl->state == MBEDTLS_SSL_SERVER_FINISHED) {
507911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
508032b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
508111fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl,
508211fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL,
508311fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
508411fa71b9SJerome Forissier }
508511fa71b9SJerome Forissier #endif
508632b31808SJens Wiklander return ret;
508711fa71b9SJerome Forissier }
508811fa71b9SJerome Forissier
5089c3deb3d6SEtienne Carriere if (ssl->conf->badmac_limit != 0) {
5090c3deb3d6SEtienne Carriere ++ssl->badmac_seen_or_in_hsfraglen;
5091c3deb3d6SEtienne Carriere if (ssl->badmac_seen_or_in_hsfraglen >= ssl->conf->badmac_limit) {
509211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("too many records with bad MAC"));
509332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_MAC;
509411fa71b9SJerome Forissier }
5095c3deb3d6SEtienne Carriere }
509611fa71b9SJerome Forissier
509711fa71b9SJerome Forissier /* As above, invalid records cause
509811fa71b9SJerome Forissier * dismissal of the whole datagram. */
509911fa71b9SJerome Forissier
510011fa71b9SJerome Forissier ssl->next_record_offset = 0;
510111fa71b9SJerome Forissier ssl->in_left = 0;
510211fa71b9SJerome Forissier
510311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("discarding invalid record (mac)"));
510432b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
510511fa71b9SJerome Forissier }
510611fa71b9SJerome Forissier
510732b31808SJens Wiklander return ret;
510832b31808SJens Wiklander } else
510911fa71b9SJerome Forissier #endif
511011fa71b9SJerome Forissier {
511111fa71b9SJerome Forissier /* Error out (and send alert) on invalid records */
511211fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
511332b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
511411fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl,
511511fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL,
511611fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC);
511711fa71b9SJerome Forissier }
511811fa71b9SJerome Forissier #endif
511932b31808SJens Wiklander return ret;
512011fa71b9SJerome Forissier }
512111fa71b9SJerome Forissier }
512211fa71b9SJerome Forissier
512311fa71b9SJerome Forissier
512411fa71b9SJerome Forissier /* Reset in pointers to default state for TLS/DTLS records,
512511fa71b9SJerome Forissier * assuming no CID and no offset between record content and
512611fa71b9SJerome Forissier * record plaintext. */
512711fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl);
512811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
512911fa71b9SJerome Forissier ssl->in_len = ssl->in_cid + rec.cid_len;
513011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
513111fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2;
513211fa71b9SJerome Forissier
513311fa71b9SJerome Forissier /* The record content type may change during decryption,
513411fa71b9SJerome Forissier * so re-read it. */
513511fa71b9SJerome Forissier ssl->in_msgtype = rec.type;
513611fa71b9SJerome Forissier /* Also update the input buffer, because unfortunately
513711fa71b9SJerome Forissier * the server-side ssl_parse_client_hello() reparses the
513811fa71b9SJerome Forissier * record header when receiving a ClientHello initiating
513911fa71b9SJerome Forissier * a renegotiation. */
514011fa71b9SJerome Forissier ssl->in_hdr[0] = rec.type;
514111fa71b9SJerome Forissier ssl->in_msg = rec.buf + rec.data_offset;
514211fa71b9SJerome Forissier ssl->in_msglen = rec.data_len;
5143039e02dfSJerome Forissier MBEDTLS_PUT_UINT16_BE(rec.data_len, ssl->in_len, 0);
514411fa71b9SJerome Forissier
514532b31808SJens Wiklander return 0;
514611fa71b9SJerome Forissier }
514711fa71b9SJerome Forissier
mbedtls_ssl_handle_message_type(mbedtls_ssl_context * ssl)514811fa71b9SJerome Forissier int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl)
514911fa71b9SJerome Forissier {
515011fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
515111fa71b9SJerome Forissier
5152c3deb3d6SEtienne Carriere /* If we're in the middle of a fragmented TLS handshake message,
5153c3deb3d6SEtienne Carriere * we don't accept any other message type. For TLS 1.3, the spec forbids
5154c3deb3d6SEtienne Carriere * interleaving other message types between handshake fragments. For TLS
5155c3deb3d6SEtienne Carriere * 1.2, the spec does not forbid it but we do. */
5156c3deb3d6SEtienne Carriere if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM &&
5157c3deb3d6SEtienne Carriere ssl->badmac_seen_or_in_hsfraglen != 0 &&
5158c3deb3d6SEtienne Carriere ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
5159c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(1, ("non-handshake message in the middle"
5160c3deb3d6SEtienne Carriere " of a fragmented handshake message"));
5161c3deb3d6SEtienne Carriere return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
5162c3deb3d6SEtienne Carriere }
5163c3deb3d6SEtienne Carriere
516411fa71b9SJerome Forissier /*
516511fa71b9SJerome Forissier * Handle particular types of records
516611fa71b9SJerome Forissier */
516732b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
516832b31808SJens Wiklander if ((ret = mbedtls_ssl_prepare_handshake_record(ssl)) != 0) {
516932b31808SJens Wiklander return ret;
517011fa71b9SJerome Forissier }
517111fa71b9SJerome Forissier }
517211fa71b9SJerome Forissier
517332b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
517432b31808SJens Wiklander if (ssl->in_msglen != 1) {
51757901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
517611fa71b9SJerome Forissier ssl->in_msglen));
517732b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
517811fa71b9SJerome Forissier }
517911fa71b9SJerome Forissier
518032b31808SJens Wiklander if (ssl->in_msg[0] != 1) {
518111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid CCS message, content: %02x",
518211fa71b9SJerome Forissier ssl->in_msg[0]));
518332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
518411fa71b9SJerome Forissier }
518511fa71b9SJerome Forissier
518611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
518711fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
518811fa71b9SJerome Forissier ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
518932b31808SJens Wiklander ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC) {
519032b31808SJens Wiklander if (ssl->handshake == NULL) {
519111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("dropping ChangeCipherSpec outside handshake"));
519232b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
519311fa71b9SJerome Forissier }
519411fa71b9SJerome Forissier
519511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("received out-of-order ChangeCipherSpec - remember"));
519632b31808SJens Wiklander return MBEDTLS_ERR_SSL_EARLY_MESSAGE;
519711fa71b9SJerome Forissier }
519811fa71b9SJerome Forissier #endif
519932b31808SJens Wiklander
520032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
520132b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
5202c3deb3d6SEtienne Carriere MBEDTLS_SSL_DEBUG_MSG(2,
520332b31808SJens Wiklander ("Ignore ChangeCipherSpec in TLS 1.3 compatibility mode"));
520432b31808SJens Wiklander return MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
520532b31808SJens Wiklander }
520632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
520711fa71b9SJerome Forissier }
520811fa71b9SJerome Forissier
520932b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
521032b31808SJens Wiklander if (ssl->in_msglen != 2) {
521111fa71b9SJerome Forissier /* Note: Standard allows for more than one 2 byte alert
521211fa71b9SJerome Forissier to be packed in a single message, but Mbed TLS doesn't
521311fa71b9SJerome Forissier currently support this. */
52147901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
521511fa71b9SJerome Forissier ssl->in_msglen));
521632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INVALID_RECORD;
521711fa71b9SJerome Forissier }
521811fa71b9SJerome Forissier
52197901324dSJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("got an alert message, type: [%u:%u]",
522011fa71b9SJerome Forissier ssl->in_msg[0], ssl->in_msg[1]));
522111fa71b9SJerome Forissier
522211fa71b9SJerome Forissier /*
522311fa71b9SJerome Forissier * Ignore non-fatal alerts, except close_notify and no_renegotiation
522411fa71b9SJerome Forissier */
522532b31808SJens Wiklander if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL) {
522611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("is a fatal alert message (msg %d)",
522711fa71b9SJerome Forissier ssl->in_msg[1]));
522832b31808SJens Wiklander return MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE;
522911fa71b9SJerome Forissier }
523011fa71b9SJerome Forissier
523111fa71b9SJerome Forissier if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
523232b31808SJens Wiklander ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY) {
523311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("is a close notify message"));
523432b31808SJens Wiklander return MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY;
523511fa71b9SJerome Forissier }
523611fa71b9SJerome Forissier
523711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
523811fa71b9SJerome Forissier if (ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
523932b31808SJens Wiklander ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION) {
524032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("is a no renegotiation alert"));
524111fa71b9SJerome Forissier /* Will be handled when trying to parse ServerHello */
524232b31808SJens Wiklander return 0;
524311fa71b9SJerome Forissier }
524411fa71b9SJerome Forissier #endif
524511fa71b9SJerome Forissier /* Silently ignore: fetch new message */
524611fa71b9SJerome Forissier return MBEDTLS_ERR_SSL_NON_FATAL;
524711fa71b9SJerome Forissier }
524811fa71b9SJerome Forissier
524911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
525032b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
525111fa71b9SJerome Forissier /* Drop unexpected ApplicationData records,
525211fa71b9SJerome Forissier * except at the beginning of renegotiations */
525311fa71b9SJerome Forissier if (ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
525432b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 0
525511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
525611fa71b9SJerome Forissier && !(ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
525711fa71b9SJerome Forissier ssl->state == MBEDTLS_SSL_SERVER_HELLO)
525811fa71b9SJerome Forissier #endif
525932b31808SJens Wiklander ) {
526011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("dropping unexpected ApplicationData"));
526132b31808SJens Wiklander return MBEDTLS_ERR_SSL_NON_FATAL;
526211fa71b9SJerome Forissier }
526311fa71b9SJerome Forissier
526411fa71b9SJerome Forissier if (ssl->handshake != NULL &&
526532b31808SJens Wiklander mbedtls_ssl_is_handshake_over(ssl) == 1) {
526611fa71b9SJerome Forissier mbedtls_ssl_handshake_wrapup_free_hs_transform(ssl);
526711fa71b9SJerome Forissier }
526811fa71b9SJerome Forissier }
526911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
527011fa71b9SJerome Forissier
527132b31808SJens Wiklander return 0;
527211fa71b9SJerome Forissier }
527311fa71b9SJerome Forissier
mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context * ssl)527411fa71b9SJerome Forissier int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl)
527511fa71b9SJerome Forissier {
527632b31808SJens Wiklander return mbedtls_ssl_send_alert_message(ssl,
527711fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_FATAL,
527832b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
527911fa71b9SJerome Forissier }
528011fa71b9SJerome Forissier
mbedtls_ssl_send_alert_message(mbedtls_ssl_context * ssl,unsigned char level,unsigned char message)528111fa71b9SJerome Forissier int mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl,
528211fa71b9SJerome Forissier unsigned char level,
528311fa71b9SJerome Forissier unsigned char message)
528411fa71b9SJerome Forissier {
528511fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
528611fa71b9SJerome Forissier
528732b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) {
528832b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
528932b31808SJens Wiklander }
529011fa71b9SJerome Forissier
529132b31808SJens Wiklander if (ssl->out_left != 0) {
529232b31808SJens Wiklander return mbedtls_ssl_flush_output(ssl);
529332b31808SJens Wiklander }
5294039e02dfSJerome Forissier
529511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> send alert message"));
529611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("send alert level=%u message=%u", level, message));
529711fa71b9SJerome Forissier
529811fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
529911fa71b9SJerome Forissier ssl->out_msglen = 2;
530011fa71b9SJerome Forissier ssl->out_msg[0] = level;
530111fa71b9SJerome Forissier ssl->out_msg[1] = message;
530211fa71b9SJerome Forissier
530332b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
530411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
530532b31808SJens Wiklander return ret;
530611fa71b9SJerome Forissier }
530711fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= send alert message"));
530811fa71b9SJerome Forissier
530932b31808SJens Wiklander return 0;
531011fa71b9SJerome Forissier }
531111fa71b9SJerome Forissier
mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context * ssl)531211fa71b9SJerome Forissier int mbedtls_ssl_write_change_cipher_spec(mbedtls_ssl_context *ssl)
531311fa71b9SJerome Forissier {
531411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
531511fa71b9SJerome Forissier
531611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write change cipher spec"));
531711fa71b9SJerome Forissier
531811fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
531911fa71b9SJerome Forissier ssl->out_msglen = 1;
532011fa71b9SJerome Forissier ssl->out_msg[0] = 1;
532111fa71b9SJerome Forissier
5322*273a583eSThomas Bourgoin mbedtls_ssl_handshake_increment_state(ssl);
532311fa71b9SJerome Forissier
532432b31808SJens Wiklander if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
532511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
532632b31808SJens Wiklander return ret;
532711fa71b9SJerome Forissier }
532811fa71b9SJerome Forissier
532911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write change cipher spec"));
533011fa71b9SJerome Forissier
533132b31808SJens Wiklander return 0;
533211fa71b9SJerome Forissier }
533311fa71b9SJerome Forissier
mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context * ssl)533411fa71b9SJerome Forissier int mbedtls_ssl_parse_change_cipher_spec(mbedtls_ssl_context *ssl)
533511fa71b9SJerome Forissier {
533611fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
533711fa71b9SJerome Forissier
533811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse change cipher spec"));
533911fa71b9SJerome Forissier
534032b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
534111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
534232b31808SJens Wiklander return ret;
534311fa71b9SJerome Forissier }
534411fa71b9SJerome Forissier
534532b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC) {
534611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad change cipher spec message"));
534711fa71b9SJerome Forissier mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
534811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
534932b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
535011fa71b9SJerome Forissier }
535111fa71b9SJerome Forissier
535211fa71b9SJerome Forissier /* CCS records are only accepted if they have length 1 and content '1',
535311fa71b9SJerome Forissier * so we don't need to check this here. */
535411fa71b9SJerome Forissier
535511fa71b9SJerome Forissier /*
535611fa71b9SJerome Forissier * Switch to our negotiated transform and session parameters for inbound
535711fa71b9SJerome Forissier * data.
535811fa71b9SJerome Forissier */
535911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("switching to new transform spec for inbound data"));
536032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
536111fa71b9SJerome Forissier ssl->transform_in = ssl->transform_negotiate;
536232b31808SJens Wiklander #endif
536311fa71b9SJerome Forissier ssl->session_in = ssl->session_negotiate;
536411fa71b9SJerome Forissier
536511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
536632b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
536711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
536811fa71b9SJerome Forissier mbedtls_ssl_dtls_replay_reset(ssl);
536911fa71b9SJerome Forissier #endif
537011fa71b9SJerome Forissier
537111fa71b9SJerome Forissier /* Increment epoch */
537232b31808SJens Wiklander if (++ssl->in_epoch == 0) {
537311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("DTLS epoch would wrap"));
537411fa71b9SJerome Forissier /* This is highly unlikely to happen for legitimate reasons, so
537511fa71b9SJerome Forissier treat it as an attack and don't send an alert. */
537632b31808SJens Wiklander return MBEDTLS_ERR_SSL_COUNTER_WRAPPING;
537711fa71b9SJerome Forissier }
537832b31808SJens Wiklander } else
537911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
538032b31808SJens Wiklander memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
538111fa71b9SJerome Forissier
538211fa71b9SJerome Forissier mbedtls_ssl_update_in_pointers(ssl);
538311fa71b9SJerome Forissier
5384*273a583eSThomas Bourgoin mbedtls_ssl_handshake_increment_state(ssl);
538511fa71b9SJerome Forissier
538611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse change cipher spec"));
538711fa71b9SJerome Forissier
538832b31808SJens Wiklander return 0;
538911fa71b9SJerome Forissier }
539011fa71b9SJerome Forissier
539111fa71b9SJerome Forissier /* Once ssl->out_hdr as the address of the beginning of the
539211fa71b9SJerome Forissier * next outgoing record is set, deduce the other pointers.
539311fa71b9SJerome Forissier *
539411fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number
539511fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
539611fa71b9SJerome Forissier * and the caller has to make sure there's space for this.
539711fa71b9SJerome Forissier */
539811fa71b9SJerome Forissier
ssl_transform_get_explicit_iv_len(mbedtls_ssl_transform const * transform)53997901324dSJerome Forissier static size_t ssl_transform_get_explicit_iv_len(
54007901324dSJerome Forissier mbedtls_ssl_transform const *transform)
54017901324dSJerome Forissier {
540232b31808SJens Wiklander return transform->ivlen - transform->fixed_ivlen;
54037901324dSJerome Forissier }
54047901324dSJerome Forissier
mbedtls_ssl_update_out_pointers(mbedtls_ssl_context * ssl,mbedtls_ssl_transform * transform)540511fa71b9SJerome Forissier void mbedtls_ssl_update_out_pointers(mbedtls_ssl_context *ssl,
540611fa71b9SJerome Forissier mbedtls_ssl_transform *transform)
540711fa71b9SJerome Forissier {
540811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
540932b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
541011fa71b9SJerome Forissier ssl->out_ctr = ssl->out_hdr + 3;
541111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
541232b31808SJens Wiklander ssl->out_cid = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
541311fa71b9SJerome Forissier ssl->out_len = ssl->out_cid;
541432b31808SJens Wiklander if (transform != NULL) {
541511fa71b9SJerome Forissier ssl->out_len += transform->out_cid_len;
541632b31808SJens Wiklander }
541711fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
541832b31808SJens Wiklander ssl->out_len = ssl->out_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
541911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
542011fa71b9SJerome Forissier ssl->out_iv = ssl->out_len + 2;
542132b31808SJens Wiklander } else
542211fa71b9SJerome Forissier #endif
542311fa71b9SJerome Forissier {
542411fa71b9SJerome Forissier ssl->out_len = ssl->out_hdr + 3;
542511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
542611fa71b9SJerome Forissier ssl->out_cid = ssl->out_len;
542711fa71b9SJerome Forissier #endif
542811fa71b9SJerome Forissier ssl->out_iv = ssl->out_hdr + 5;
542911fa71b9SJerome Forissier }
543011fa71b9SJerome Forissier
543111fa71b9SJerome Forissier ssl->out_msg = ssl->out_iv;
54327901324dSJerome Forissier /* Adjust out_msg to make space for explicit IV, if used. */
543332b31808SJens Wiklander if (transform != NULL) {
54347901324dSJerome Forissier ssl->out_msg += ssl_transform_get_explicit_iv_len(transform);
543511fa71b9SJerome Forissier }
543632b31808SJens Wiklander }
543711fa71b9SJerome Forissier
543811fa71b9SJerome Forissier /* Once ssl->in_hdr as the address of the beginning of the
543911fa71b9SJerome Forissier * next incoming record is set, deduce the other pointers.
544011fa71b9SJerome Forissier *
544111fa71b9SJerome Forissier * Note: For TLS, we save the implicit record sequence number
544211fa71b9SJerome Forissier * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
544311fa71b9SJerome Forissier * and the caller has to make sure there's space for this.
544411fa71b9SJerome Forissier */
544511fa71b9SJerome Forissier
mbedtls_ssl_update_in_pointers(mbedtls_ssl_context * ssl)544611fa71b9SJerome Forissier void mbedtls_ssl_update_in_pointers(mbedtls_ssl_context *ssl)
544711fa71b9SJerome Forissier {
544811fa71b9SJerome Forissier /* This function sets the pointers to match the case
544911fa71b9SJerome Forissier * of unprotected TLS/DTLS records, with both ssl->in_iv
545011fa71b9SJerome Forissier * and ssl->in_msg pointing to the beginning of the record
545111fa71b9SJerome Forissier * content.
545211fa71b9SJerome Forissier *
545311fa71b9SJerome Forissier * When decrypting a protected record, ssl->in_msg
545411fa71b9SJerome Forissier * will be shifted to point to the beginning of the
545511fa71b9SJerome Forissier * record plaintext.
545611fa71b9SJerome Forissier */
545711fa71b9SJerome Forissier
545811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
545932b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
546011fa71b9SJerome Forissier /* This sets the header pointers to match records
546111fa71b9SJerome Forissier * without CID. When we receive a record containing
546211fa71b9SJerome Forissier * a CID, the fields are shifted accordingly in
546311fa71b9SJerome Forissier * ssl_parse_record_header(). */
546411fa71b9SJerome Forissier ssl->in_ctr = ssl->in_hdr + 3;
546511fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
546632b31808SJens Wiklander ssl->in_cid = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
546711fa71b9SJerome Forissier ssl->in_len = ssl->in_cid; /* Default: no CID */
546811fa71b9SJerome Forissier #else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
546932b31808SJens Wiklander ssl->in_len = ssl->in_ctr + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
547011fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
547111fa71b9SJerome Forissier ssl->in_iv = ssl->in_len + 2;
547232b31808SJens Wiklander } else
547311fa71b9SJerome Forissier #endif
547411fa71b9SJerome Forissier {
5475c3deb3d6SEtienne Carriere ssl->in_ctr = ssl->in_buf;
547611fa71b9SJerome Forissier ssl->in_len = ssl->in_hdr + 3;
547711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
547811fa71b9SJerome Forissier ssl->in_cid = ssl->in_len;
547911fa71b9SJerome Forissier #endif
548011fa71b9SJerome Forissier ssl->in_iv = ssl->in_hdr + 5;
548111fa71b9SJerome Forissier }
548211fa71b9SJerome Forissier
548311fa71b9SJerome Forissier /* This will be adjusted at record decryption time. */
548411fa71b9SJerome Forissier ssl->in_msg = ssl->in_iv;
548511fa71b9SJerome Forissier }
548611fa71b9SJerome Forissier
548711fa71b9SJerome Forissier /*
548811fa71b9SJerome Forissier * Setup an SSL context
548911fa71b9SJerome Forissier */
549011fa71b9SJerome Forissier
mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context * ssl)5491c3deb3d6SEtienne Carriere void mbedtls_ssl_reset_in_pointers(mbedtls_ssl_context *ssl)
5492c3deb3d6SEtienne Carriere {
5493c3deb3d6SEtienne Carriere #if defined(MBEDTLS_SSL_PROTO_DTLS)
5494c3deb3d6SEtienne Carriere if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
5495c3deb3d6SEtienne Carriere ssl->in_hdr = ssl->in_buf;
5496c3deb3d6SEtienne Carriere } else
5497c3deb3d6SEtienne Carriere #endif /* MBEDTLS_SSL_PROTO_DTLS */
5498c3deb3d6SEtienne Carriere {
5499c3deb3d6SEtienne Carriere ssl->in_hdr = ssl->in_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
5500c3deb3d6SEtienne Carriere }
5501c3deb3d6SEtienne Carriere
5502c3deb3d6SEtienne Carriere /* Derive other internal pointers. */
5503c3deb3d6SEtienne Carriere mbedtls_ssl_update_in_pointers(ssl);
5504c3deb3d6SEtienne Carriere }
5505c3deb3d6SEtienne Carriere
mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context * ssl)5506c3deb3d6SEtienne Carriere void mbedtls_ssl_reset_out_pointers(mbedtls_ssl_context *ssl)
550711fa71b9SJerome Forissier {
550811fa71b9SJerome Forissier /* Set the incoming and outgoing record pointers. */
550911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
551032b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
551111fa71b9SJerome Forissier ssl->out_hdr = ssl->out_buf;
551232b31808SJens Wiklander } else
551311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
551411fa71b9SJerome Forissier {
551532b31808SJens Wiklander ssl->out_ctr = ssl->out_buf;
5516c3deb3d6SEtienne Carriere ssl->out_hdr = ssl->out_buf + MBEDTLS_SSL_SEQUENCE_NUMBER_LEN;
551711fa71b9SJerome Forissier }
551811fa71b9SJerome Forissier /* Derive other internal pointers. */
551911fa71b9SJerome Forissier mbedtls_ssl_update_out_pointers(ssl, NULL /* no transform enabled */);
552011fa71b9SJerome Forissier }
552111fa71b9SJerome Forissier
552211fa71b9SJerome Forissier /*
552311fa71b9SJerome Forissier * SSL get accessors
552411fa71b9SJerome Forissier */
mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context * ssl)552511fa71b9SJerome Forissier size_t mbedtls_ssl_get_bytes_avail(const mbedtls_ssl_context *ssl)
552611fa71b9SJerome Forissier {
552732b31808SJens Wiklander return ssl->in_offt == NULL ? 0 : ssl->in_msglen;
552811fa71b9SJerome Forissier }
552911fa71b9SJerome Forissier
mbedtls_ssl_check_pending(const mbedtls_ssl_context * ssl)553011fa71b9SJerome Forissier int mbedtls_ssl_check_pending(const mbedtls_ssl_context *ssl)
553111fa71b9SJerome Forissier {
553211fa71b9SJerome Forissier /*
553311fa71b9SJerome Forissier * Case A: We're currently holding back
553411fa71b9SJerome Forissier * a message for further processing.
553511fa71b9SJerome Forissier */
553611fa71b9SJerome Forissier
553732b31808SJens Wiklander if (ssl->keep_current_message == 1) {
553811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: record held back for processing"));
553932b31808SJens Wiklander return 1;
554011fa71b9SJerome Forissier }
554111fa71b9SJerome Forissier
554211fa71b9SJerome Forissier /*
554311fa71b9SJerome Forissier * Case B: Further records are pending in the current datagram.
554411fa71b9SJerome Forissier */
554511fa71b9SJerome Forissier
554611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
554711fa71b9SJerome Forissier if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
554832b31808SJens Wiklander ssl->in_left > ssl->next_record_offset) {
554911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: more records within current datagram"));
555032b31808SJens Wiklander return 1;
555111fa71b9SJerome Forissier }
555211fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
555311fa71b9SJerome Forissier
555411fa71b9SJerome Forissier /*
555511fa71b9SJerome Forissier * Case C: A handshake message is being processed.
555611fa71b9SJerome Forissier */
555711fa71b9SJerome Forissier
555832b31808SJens Wiklander if (ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen) {
555932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3,
556032b31808SJens Wiklander ("ssl_check_pending: more handshake messages within current record"));
556132b31808SJens Wiklander return 1;
556211fa71b9SJerome Forissier }
556311fa71b9SJerome Forissier
556411fa71b9SJerome Forissier /*
556511fa71b9SJerome Forissier * Case D: An application data message is being processed
556611fa71b9SJerome Forissier */
556732b31808SJens Wiklander if (ssl->in_offt != NULL) {
556811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: application data record is being processed"));
556932b31808SJens Wiklander return 1;
557011fa71b9SJerome Forissier }
557111fa71b9SJerome Forissier
557211fa71b9SJerome Forissier /*
557311fa71b9SJerome Forissier * In all other cases, the rest of the message can be dropped.
557411fa71b9SJerome Forissier * As in ssl_get_next_record, this needs to be adapted if
557511fa71b9SJerome Forissier * we implement support for multiple alerts in single records.
557611fa71b9SJerome Forissier */
557711fa71b9SJerome Forissier
557811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_check_pending: nothing pending"));
557932b31808SJens Wiklander return 0;
558011fa71b9SJerome Forissier }
558111fa71b9SJerome Forissier
558211fa71b9SJerome Forissier
mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context * ssl)558311fa71b9SJerome Forissier int mbedtls_ssl_get_record_expansion(const mbedtls_ssl_context *ssl)
558411fa71b9SJerome Forissier {
558511fa71b9SJerome Forissier size_t transform_expansion = 0;
558611fa71b9SJerome Forissier const mbedtls_ssl_transform *transform = ssl->transform_out;
558711fa71b9SJerome Forissier unsigned block_size;
558832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
558932b31808SJens Wiklander psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
559032b31808SJens Wiklander psa_key_type_t key_type;
559132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
559211fa71b9SJerome Forissier
559311fa71b9SJerome Forissier size_t out_hdr_len = mbedtls_ssl_out_hdr_len(ssl);
559411fa71b9SJerome Forissier
559532b31808SJens Wiklander if (transform == NULL) {
559632b31808SJens Wiklander return (int) out_hdr_len;
559732b31808SJens Wiklander }
559811fa71b9SJerome Forissier
559911fa71b9SJerome Forissier
560032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
560132b31808SJens Wiklander if (transform->psa_alg == PSA_ALG_GCM ||
560232b31808SJens Wiklander transform->psa_alg == PSA_ALG_CCM ||
560332b31808SJens Wiklander transform->psa_alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 8) ||
560432b31808SJens Wiklander transform->psa_alg == PSA_ALG_CHACHA20_POLY1305 ||
560532b31808SJens Wiklander transform->psa_alg == MBEDTLS_SSL_NULL_CIPHER) {
560632b31808SJens Wiklander transform_expansion = transform->minlen;
560732b31808SJens Wiklander } else if (transform->psa_alg == PSA_ALG_CBC_NO_PADDING) {
560832b31808SJens Wiklander (void) psa_get_key_attributes(transform->psa_key_enc, &attr);
560932b31808SJens Wiklander key_type = psa_get_key_type(&attr);
561032b31808SJens Wiklander
561132b31808SJens Wiklander block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type);
561232b31808SJens Wiklander
561332b31808SJens Wiklander /* Expansion due to the addition of the MAC. */
561432b31808SJens Wiklander transform_expansion += transform->maclen;
561532b31808SJens Wiklander
561632b31808SJens Wiklander /* Expansion due to the addition of CBC padding;
561732b31808SJens Wiklander * Theoretically up to 256 bytes, but we never use
561832b31808SJens Wiklander * more than the block size of the underlying cipher. */
561932b31808SJens Wiklander transform_expansion += block_size;
562032b31808SJens Wiklander
562132b31808SJens Wiklander /* For TLS 1.2 or higher, an explicit IV is added
562232b31808SJens Wiklander * after the record header. */
562332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
562432b31808SJens Wiklander transform_expansion += block_size;
562532b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
562632b31808SJens Wiklander } else {
562732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1,
562832b31808SJens Wiklander ("Unsupported psa_alg spotted in mbedtls_ssl_get_record_expansion()"));
562932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
563032b31808SJens Wiklander }
563132b31808SJens Wiklander #else
563232b31808SJens Wiklander switch (mbedtls_cipher_get_cipher_mode(&transform->cipher_ctx_enc)) {
563311fa71b9SJerome Forissier case MBEDTLS_MODE_GCM:
563411fa71b9SJerome Forissier case MBEDTLS_MODE_CCM:
563511fa71b9SJerome Forissier case MBEDTLS_MODE_CHACHAPOLY:
563611fa71b9SJerome Forissier case MBEDTLS_MODE_STREAM:
563711fa71b9SJerome Forissier transform_expansion = transform->minlen;
563811fa71b9SJerome Forissier break;
563911fa71b9SJerome Forissier
564011fa71b9SJerome Forissier case MBEDTLS_MODE_CBC:
564111fa71b9SJerome Forissier
564211fa71b9SJerome Forissier block_size = mbedtls_cipher_get_block_size(
564311fa71b9SJerome Forissier &transform->cipher_ctx_enc);
564411fa71b9SJerome Forissier
564511fa71b9SJerome Forissier /* Expansion due to the addition of the MAC. */
564611fa71b9SJerome Forissier transform_expansion += transform->maclen;
564711fa71b9SJerome Forissier
564811fa71b9SJerome Forissier /* Expansion due to the addition of CBC padding;
564911fa71b9SJerome Forissier * Theoretically up to 256 bytes, but we never use
565011fa71b9SJerome Forissier * more than the block size of the underlying cipher. */
565111fa71b9SJerome Forissier transform_expansion += block_size;
565211fa71b9SJerome Forissier
565332b31808SJens Wiklander /* For TLS 1.2 or higher, an explicit IV is added
565411fa71b9SJerome Forissier * after the record header. */
565532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
565611fa71b9SJerome Forissier transform_expansion += block_size;
565732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
565811fa71b9SJerome Forissier
565911fa71b9SJerome Forissier break;
566011fa71b9SJerome Forissier
566111fa71b9SJerome Forissier default:
566211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
566332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
566411fa71b9SJerome Forissier }
566532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
566611fa71b9SJerome Forissier
566711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
566832b31808SJens Wiklander if (transform->out_cid_len != 0) {
566911fa71b9SJerome Forissier transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
567032b31808SJens Wiklander }
567111fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
567211fa71b9SJerome Forissier
567332b31808SJens Wiklander return (int) (out_hdr_len + transform_expansion);
567411fa71b9SJerome Forissier }
567511fa71b9SJerome Forissier
567611fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
567711fa71b9SJerome Forissier /*
567811fa71b9SJerome Forissier * Check record counters and renegotiate if they're above the limit.
567911fa71b9SJerome Forissier */
5680039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_check_ctr_renegotiate(mbedtls_ssl_context * ssl)568111fa71b9SJerome Forissier static int ssl_check_ctr_renegotiate(mbedtls_ssl_context *ssl)
568211fa71b9SJerome Forissier {
568311fa71b9SJerome Forissier size_t ep_len = mbedtls_ssl_ep_len(ssl);
568411fa71b9SJerome Forissier int in_ctr_cmp;
568511fa71b9SJerome Forissier int out_ctr_cmp;
568611fa71b9SJerome Forissier
568732b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 0 ||
568811fa71b9SJerome Forissier ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
568932b31808SJens Wiklander ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED) {
569032b31808SJens Wiklander return 0;
569111fa71b9SJerome Forissier }
569211fa71b9SJerome Forissier
569311fa71b9SJerome Forissier in_ctr_cmp = memcmp(ssl->in_ctr + ep_len,
569432b31808SJens Wiklander &ssl->conf->renego_period[ep_len],
569532b31808SJens Wiklander MBEDTLS_SSL_SEQUENCE_NUMBER_LEN - ep_len);
569632b31808SJens Wiklander out_ctr_cmp = memcmp(&ssl->cur_out_ctr[ep_len],
569732b31808SJens Wiklander &ssl->conf->renego_period[ep_len],
569832b31808SJens Wiklander sizeof(ssl->cur_out_ctr) - ep_len);
569911fa71b9SJerome Forissier
570032b31808SJens Wiklander if (in_ctr_cmp <= 0 && out_ctr_cmp <= 0) {
570132b31808SJens Wiklander return 0;
570211fa71b9SJerome Forissier }
570311fa71b9SJerome Forissier
570411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("record counter limit reached: renegotiate"));
570532b31808SJens Wiklander return mbedtls_ssl_renegotiate(ssl);
570611fa71b9SJerome Forissier }
570711fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
570811fa71b9SJerome Forissier
570932b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
571032b31808SJens Wiklander
5711cb034002SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C)
571232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_is_new_session_ticket(mbedtls_ssl_context * ssl)5713cb034002SJerome Forissier static int ssl_tls13_is_new_session_ticket(mbedtls_ssl_context *ssl)
571432b31808SJens Wiklander {
571532b31808SJens Wiklander
571632b31808SJens Wiklander if ((ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl)) ||
571732b31808SJens Wiklander (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET)) {
571832b31808SJens Wiklander return 0;
571932b31808SJens Wiklander }
572032b31808SJens Wiklander
5721cb034002SJerome Forissier return 1;
572232b31808SJens Wiklander }
5723cb034002SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */
572432b31808SJens Wiklander
572532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context * ssl)572632b31808SJens Wiklander static int ssl_tls13_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
572732b31808SJens Wiklander {
572832b31808SJens Wiklander
572932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("received post-handshake message"));
573032b31808SJens Wiklander
5731cb034002SJerome Forissier #if defined(MBEDTLS_SSL_CLI_C)
573232b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
5733cb034002SJerome Forissier if (ssl_tls13_is_new_session_ticket(ssl)) {
5734cb034002SJerome Forissier #if defined(MBEDTLS_SSL_SESSION_TICKETS)
5735cb034002SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("NewSessionTicket received"));
5736cb034002SJerome Forissier if (mbedtls_ssl_conf_is_signal_new_session_tickets_enabled(ssl->conf) ==
5737cb034002SJerome Forissier MBEDTLS_SSL_TLS1_3_SIGNAL_NEW_SESSION_TICKETS_ENABLED) {
5738cb034002SJerome Forissier ssl->keep_current_message = 1;
5739cb034002SJerome Forissier
5740cb034002SJerome Forissier mbedtls_ssl_handshake_set_state(ssl,
5741cb034002SJerome Forissier MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET);
5742cb034002SJerome Forissier return MBEDTLS_ERR_SSL_WANT_READ;
5743cb034002SJerome Forissier } else {
5744cb034002SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, handling disabled."));
5745cb034002SJerome Forissier return 0;
5746cb034002SJerome Forissier }
5747cb034002SJerome Forissier #else
5748cb034002SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(3, ("Ignoring NewSessionTicket, not supported."));
5749cb034002SJerome Forissier return 0;
5750cb034002SJerome Forissier #endif
575132b31808SJens Wiklander }
575232b31808SJens Wiklander }
5753cb034002SJerome Forissier #endif /* MBEDTLS_SSL_CLI_C */
575432b31808SJens Wiklander
575532b31808SJens Wiklander /* Fail in all other cases. */
575632b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
575732b31808SJens Wiklander }
575832b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
575932b31808SJens Wiklander
576032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
576132b31808SJens Wiklander /* This function is called from mbedtls_ssl_read() when a handshake message is
576232b31808SJens Wiklander * received after the initial handshake. In this context, handshake messages
576332b31808SJens Wiklander * may only be sent for the purpose of initiating renegotiations.
576432b31808SJens Wiklander *
576532b31808SJens Wiklander * This function is introduced as a separate helper since the handling
576632b31808SJens Wiklander * of post-handshake handshake messages changes significantly in TLS 1.3,
576732b31808SJens Wiklander * and having a helper function allows to distinguish between TLS <= 1.2 and
576832b31808SJens Wiklander * TLS 1.3 in the future without bloating the logic of mbedtls_ssl_read().
576932b31808SJens Wiklander */
577032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context * ssl)577132b31808SJens Wiklander static int ssl_tls12_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
577232b31808SJens Wiklander {
577332b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
577432b31808SJens Wiklander
577532b31808SJens Wiklander /*
577632b31808SJens Wiklander * - For client-side, expect SERVER_HELLO_REQUEST.
577732b31808SJens Wiklander * - For server-side, expect CLIENT_HELLO.
577832b31808SJens Wiklander * - Fail (TLS) or silently drop record (DTLS) in other cases.
577932b31808SJens Wiklander */
578032b31808SJens Wiklander
578132b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C)
578232b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
578332b31808SJens Wiklander (ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
578432b31808SJens Wiklander ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl))) {
578532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not HelloRequest)"));
578632b31808SJens Wiklander
578732b31808SJens Wiklander /* With DTLS, drop the packet (probably from last handshake) */
578832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
578932b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
579032b31808SJens Wiklander return 0;
579132b31808SJens Wiklander }
579232b31808SJens Wiklander #endif
579332b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
579432b31808SJens Wiklander }
579532b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C */
579632b31808SJens Wiklander
579732b31808SJens Wiklander #if defined(MBEDTLS_SSL_SRV_C)
579832b31808SJens Wiklander if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
579932b31808SJens Wiklander ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
580032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("handshake received (not ClientHello)"));
580132b31808SJens Wiklander
580232b31808SJens Wiklander /* With DTLS, drop the packet (probably from last handshake) */
580332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
580432b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
580532b31808SJens Wiklander return 0;
580632b31808SJens Wiklander }
580732b31808SJens Wiklander #endif
580832b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
580932b31808SJens Wiklander }
581032b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C */
581132b31808SJens Wiklander
581232b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
581332b31808SJens Wiklander /* Determine whether renegotiation attempt should be accepted */
581432b31808SJens Wiklander if (!(ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
581532b31808SJens Wiklander (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
581632b31808SJens Wiklander ssl->conf->allow_legacy_renegotiation ==
581732b31808SJens Wiklander MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION))) {
581832b31808SJens Wiklander /*
581932b31808SJens Wiklander * Accept renegotiation request
582032b31808SJens Wiklander */
582132b31808SJens Wiklander
582232b31808SJens Wiklander /* DTLS clients need to know renego is server-initiated */
582332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
582432b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
582532b31808SJens Wiklander ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT) {
582632b31808SJens Wiklander ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
582732b31808SJens Wiklander }
582832b31808SJens Wiklander #endif
582932b31808SJens Wiklander ret = mbedtls_ssl_start_renegotiation(ssl);
583032b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
583132b31808SJens Wiklander ret != 0) {
583232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_start_renegotiation",
583332b31808SJens Wiklander ret);
583432b31808SJens Wiklander return ret;
583532b31808SJens Wiklander }
583632b31808SJens Wiklander } else
583732b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
583832b31808SJens Wiklander {
583932b31808SJens Wiklander /*
584032b31808SJens Wiklander * Refuse renegotiation
584132b31808SJens Wiklander */
584232b31808SJens Wiklander
584332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(3, ("refusing renegotiation, sending alert"));
584432b31808SJens Wiklander
584532b31808SJens Wiklander if ((ret = mbedtls_ssl_send_alert_message(ssl,
584632b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_WARNING,
584732b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION)) != 0) {
584832b31808SJens Wiklander return ret;
584932b31808SJens Wiklander }
585032b31808SJens Wiklander }
585132b31808SJens Wiklander
585232b31808SJens Wiklander return 0;
585332b31808SJens Wiklander }
585432b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
585532b31808SJens Wiklander
585632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_handle_hs_message_post_handshake(mbedtls_ssl_context * ssl)585732b31808SJens Wiklander static int ssl_handle_hs_message_post_handshake(mbedtls_ssl_context *ssl)
585832b31808SJens Wiklander {
585932b31808SJens Wiklander /* Check protocol version and dispatch accordingly. */
586032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
586132b31808SJens Wiklander if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
586232b31808SJens Wiklander return ssl_tls13_handle_hs_message_post_handshake(ssl);
586332b31808SJens Wiklander }
586432b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
586532b31808SJens Wiklander
586632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
586732b31808SJens Wiklander if (ssl->tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) {
586832b31808SJens Wiklander return ssl_tls12_handle_hs_message_post_handshake(ssl);
586932b31808SJens Wiklander }
587032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
587132b31808SJens Wiklander
587232b31808SJens Wiklander /* Should never happen */
587332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
587432b31808SJens Wiklander }
587532b31808SJens Wiklander
587611fa71b9SJerome Forissier /*
5877b0563631STom Van Eyck * brief Read at most 'len' application data bytes from the input
5878b0563631STom Van Eyck * buffer.
5879b0563631STom Van Eyck *
5880b0563631STom Van Eyck * param ssl SSL context:
5881b0563631STom Van Eyck * - First byte of application data not read yet in the input
5882b0563631STom Van Eyck * buffer located at address `in_offt`.
5883b0563631STom Van Eyck * - The number of bytes of data not read yet is `in_msglen`.
5884b0563631STom Van Eyck * param buf buffer that will hold the data
5885b0563631STom Van Eyck * param len maximum number of bytes to read
5886b0563631STom Van Eyck *
5887b0563631STom Van Eyck * note The function updates the fields `in_offt` and `in_msglen`
5888b0563631STom Van Eyck * according to the number of bytes read.
5889b0563631STom Van Eyck *
5890b0563631STom Van Eyck * return The number of bytes read.
5891b0563631STom Van Eyck */
ssl_read_application_data(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)5892b0563631STom Van Eyck static int ssl_read_application_data(
5893b0563631STom Van Eyck mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
5894b0563631STom Van Eyck {
5895b0563631STom Van Eyck size_t n = (len < ssl->in_msglen) ? len : ssl->in_msglen;
5896b0563631STom Van Eyck
5897b0563631STom Van Eyck if (len != 0) {
5898b0563631STom Van Eyck memcpy(buf, ssl->in_offt, n);
5899b0563631STom Van Eyck ssl->in_msglen -= n;
5900b0563631STom Van Eyck }
5901b0563631STom Van Eyck
5902b0563631STom Van Eyck /* Zeroising the plaintext buffer to erase unused application data
5903b0563631STom Van Eyck from the memory. */
5904b0563631STom Van Eyck mbedtls_platform_zeroize(ssl->in_offt, n);
5905b0563631STom Van Eyck
5906b0563631STom Van Eyck if (ssl->in_msglen == 0) {
5907b0563631STom Van Eyck /* all bytes consumed */
5908b0563631STom Van Eyck ssl->in_offt = NULL;
5909b0563631STom Van Eyck ssl->keep_current_message = 0;
5910b0563631STom Van Eyck } else {
5911b0563631STom Van Eyck /* more data available */
5912b0563631STom Van Eyck ssl->in_offt += n;
5913b0563631STom Van Eyck }
5914b0563631STom Van Eyck
5915b0563631STom Van Eyck return (int) n;
5916b0563631STom Van Eyck }
5917b0563631STom Van Eyck
5918b0563631STom Van Eyck /*
591911fa71b9SJerome Forissier * Receive application data decrypted from the SSL layer
592011fa71b9SJerome Forissier */
mbedtls_ssl_read(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)592111fa71b9SJerome Forissier int mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
592211fa71b9SJerome Forissier {
592311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
592411fa71b9SJerome Forissier
592532b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) {
592632b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
592732b31808SJens Wiklander }
592811fa71b9SJerome Forissier
592911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> read"));
593011fa71b9SJerome Forissier
593111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
593232b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
593332b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
593432b31808SJens Wiklander return ret;
593532b31808SJens Wiklander }
593611fa71b9SJerome Forissier
593711fa71b9SJerome Forissier if (ssl->handshake != NULL &&
593832b31808SJens Wiklander ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING) {
593932b31808SJens Wiklander if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
594032b31808SJens Wiklander return ret;
594132b31808SJens Wiklander }
594211fa71b9SJerome Forissier }
594311fa71b9SJerome Forissier }
594411fa71b9SJerome Forissier #endif
594511fa71b9SJerome Forissier
594611fa71b9SJerome Forissier /*
594711fa71b9SJerome Forissier * Check if renegotiation is necessary and/or handshake is
594811fa71b9SJerome Forissier * in process. If yes, perform/continue, and fall through
594911fa71b9SJerome Forissier * if an unexpected packet is received while the client
595011fa71b9SJerome Forissier * is waiting for the ServerHello.
595111fa71b9SJerome Forissier *
595211fa71b9SJerome Forissier * (There is no equivalent to the last condition on
595311fa71b9SJerome Forissier * the server-side as it is not treated as within
595411fa71b9SJerome Forissier * a handshake while waiting for the ClientHello
595511fa71b9SJerome Forissier * after a renegotiation request.)
595611fa71b9SJerome Forissier */
595711fa71b9SJerome Forissier
595811fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
595911fa71b9SJerome Forissier ret = ssl_check_ctr_renegotiate(ssl);
596011fa71b9SJerome Forissier if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
596132b31808SJens Wiklander ret != 0) {
596211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
596332b31808SJens Wiklander return ret;
596411fa71b9SJerome Forissier }
596511fa71b9SJerome Forissier #endif
596611fa71b9SJerome Forissier
596732b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
596811fa71b9SJerome Forissier ret = mbedtls_ssl_handshake(ssl);
596911fa71b9SJerome Forissier if (ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
597032b31808SJens Wiklander ret != 0) {
597111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
597232b31808SJens Wiklander return ret;
597311fa71b9SJerome Forissier }
597411fa71b9SJerome Forissier }
597511fa71b9SJerome Forissier
597611fa71b9SJerome Forissier /* Loop as long as no application data record is available */
597732b31808SJens Wiklander while (ssl->in_offt == NULL) {
597811fa71b9SJerome Forissier /* Start timer if not already running */
597911fa71b9SJerome Forissier if (ssl->f_get_timer != NULL &&
598032b31808SJens Wiklander ssl->f_get_timer(ssl->p_timer) == -1) {
598111fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, ssl->conf->read_timeout);
598211fa71b9SJerome Forissier }
598311fa71b9SJerome Forissier
598432b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
598532b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
598632b31808SJens Wiklander return 0;
598732b31808SJens Wiklander }
598811fa71b9SJerome Forissier
598911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
599032b31808SJens Wiklander return ret;
599111fa71b9SJerome Forissier }
599211fa71b9SJerome Forissier
599311fa71b9SJerome Forissier if (ssl->in_msglen == 0 &&
599432b31808SJens Wiklander ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA) {
599511fa71b9SJerome Forissier /*
599611fa71b9SJerome Forissier * OpenSSL sends empty messages to randomize the IV
599711fa71b9SJerome Forissier */
599832b31808SJens Wiklander if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
599932b31808SJens Wiklander if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
600032b31808SJens Wiklander return 0;
600132b31808SJens Wiklander }
600211fa71b9SJerome Forissier
600311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
600432b31808SJens Wiklander return ret;
600511fa71b9SJerome Forissier }
600611fa71b9SJerome Forissier }
600711fa71b9SJerome Forissier
600832b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) {
600932b31808SJens Wiklander ret = ssl_handle_hs_message_post_handshake(ssl);
601032b31808SJens Wiklander if (ret != 0) {
601132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_handle_hs_message_post_handshake",
601211fa71b9SJerome Forissier ret);
601332b31808SJens Wiklander return ret;
601411fa71b9SJerome Forissier }
601511fa71b9SJerome Forissier
601632b31808SJens Wiklander /* At this point, we don't know whether the renegotiation triggered
601732b31808SJens Wiklander * by the post-handshake message has been completed or not. The cases
601832b31808SJens Wiklander * to consider are the following:
601911fa71b9SJerome Forissier * 1) The renegotiation is complete. In this case, no new record
602011fa71b9SJerome Forissier * has been read yet.
602111fa71b9SJerome Forissier * 2) The renegotiation is incomplete because the client received
602211fa71b9SJerome Forissier * an application data record while awaiting the ServerHello.
602311fa71b9SJerome Forissier * 3) The renegotiation is incomplete because the client received
602411fa71b9SJerome Forissier * a non-handshake, non-application data message while awaiting
602511fa71b9SJerome Forissier * the ServerHello.
602632b31808SJens Wiklander *
602732b31808SJens Wiklander * In each of these cases, looping will be the proper action:
602811fa71b9SJerome Forissier * - For 1), the next iteration will read a new record and check
602911fa71b9SJerome Forissier * if it's application data.
603011fa71b9SJerome Forissier * - For 2), the loop condition isn't satisfied as application data
603111fa71b9SJerome Forissier * is present, hence continue is the same as break
603211fa71b9SJerome Forissier * - For 3), the loop condition is satisfied and read_record
603311fa71b9SJerome Forissier * will re-deliver the message that was held back by the client
603411fa71b9SJerome Forissier * when expecting the ServerHello.
603511fa71b9SJerome Forissier */
603632b31808SJens Wiklander
603711fa71b9SJerome Forissier continue;
603811fa71b9SJerome Forissier }
603911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
604032b31808SJens Wiklander else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
604132b31808SJens Wiklander if (ssl->conf->renego_max_records >= 0) {
604232b31808SJens Wiklander if (++ssl->renego_records_seen > ssl->conf->renego_max_records) {
604311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation requested, "
604411fa71b9SJerome Forissier "but not honored by client"));
604532b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
604611fa71b9SJerome Forissier }
604711fa71b9SJerome Forissier }
604811fa71b9SJerome Forissier }
604911fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_RENEGOTIATION */
605011fa71b9SJerome Forissier
605111fa71b9SJerome Forissier /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
605232b31808SJens Wiklander if (ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT) {
605311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("ignoring non-fatal non-closure alert"));
605432b31808SJens Wiklander return MBEDTLS_ERR_SSL_WANT_READ;
605511fa71b9SJerome Forissier }
605611fa71b9SJerome Forissier
605732b31808SJens Wiklander if (ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA) {
605811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("bad application data message"));
605932b31808SJens Wiklander return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
606011fa71b9SJerome Forissier }
606111fa71b9SJerome Forissier
606211fa71b9SJerome Forissier ssl->in_offt = ssl->in_msg;
606311fa71b9SJerome Forissier
606411fa71b9SJerome Forissier /* We're going to return something now, cancel timer,
606511fa71b9SJerome Forissier * except if handshake (renegotiation) is in progress */
606632b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
606711fa71b9SJerome Forissier mbedtls_ssl_set_timer(ssl, 0);
606832b31808SJens Wiklander }
606911fa71b9SJerome Forissier
607011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
607111fa71b9SJerome Forissier /* If we requested renego but received AppData, resend HelloRequest.
607211fa71b9SJerome Forissier * Do it now, after setting in_offt, to avoid taking this branch
607311fa71b9SJerome Forissier * again if ssl_write_hello_request() returns WANT_WRITE */
607411fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
607511fa71b9SJerome Forissier if (ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
607632b31808SJens Wiklander ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING) {
607732b31808SJens Wiklander if ((ret = mbedtls_ssl_resend_hello_request(ssl)) != 0) {
607811fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_resend_hello_request",
607911fa71b9SJerome Forissier ret);
608032b31808SJens Wiklander return ret;
608111fa71b9SJerome Forissier }
608211fa71b9SJerome Forissier }
608311fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
608411fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
608511fa71b9SJerome Forissier }
608611fa71b9SJerome Forissier
6087b0563631STom Van Eyck ret = ssl_read_application_data(ssl, buf, len);
608811fa71b9SJerome Forissier
608911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= read"));
609011fa71b9SJerome Forissier
6091b0563631STom Van Eyck return ret;
609211fa71b9SJerome Forissier }
609311fa71b9SJerome Forissier
6094b0563631STom Van Eyck #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_EARLY_DATA)
mbedtls_ssl_read_early_data(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)6095b0563631STom Van Eyck int mbedtls_ssl_read_early_data(mbedtls_ssl_context *ssl,
6096b0563631STom Van Eyck unsigned char *buf, size_t len)
6097b0563631STom Van Eyck {
6098b0563631STom Van Eyck if (ssl == NULL || (ssl->conf == NULL)) {
6099b0563631STom Van Eyck return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6100b0563631STom Van Eyck }
6101b0563631STom Van Eyck
6102b0563631STom Van Eyck /*
6103b0563631STom Van Eyck * The server may receive early data only while waiting for the End of
6104b0563631STom Van Eyck * Early Data handshake message.
6105b0563631STom Van Eyck */
6106b0563631STom Van Eyck if ((ssl->state != MBEDTLS_SSL_END_OF_EARLY_DATA) ||
6107b0563631STom Van Eyck (ssl->in_offt == NULL)) {
6108b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA;
6109b0563631STom Van Eyck }
6110b0563631STom Van Eyck
6111b0563631STom Van Eyck return ssl_read_application_data(ssl, buf, len);
6112b0563631STom Van Eyck }
6113b0563631STom Van Eyck #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_EARLY_DATA */
6114b0563631STom Van Eyck
611511fa71b9SJerome Forissier /*
611611fa71b9SJerome Forissier * Send application data to be encrypted by the SSL layer, taking care of max
611711fa71b9SJerome Forissier * fragment length and buffer size.
611811fa71b9SJerome Forissier *
611911fa71b9SJerome Forissier * According to RFC 5246 Section 6.2.1:
612011fa71b9SJerome Forissier *
612111fa71b9SJerome Forissier * Zero-length fragments of Application data MAY be sent as they are
612211fa71b9SJerome Forissier * potentially useful as a traffic analysis countermeasure.
612311fa71b9SJerome Forissier *
612411fa71b9SJerome Forissier * Therefore, it is possible that the input message length is 0 and the
612511fa71b9SJerome Forissier * corresponding return code is 0 on success.
612611fa71b9SJerome Forissier */
6127039e02dfSJerome Forissier MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_real(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)612811fa71b9SJerome Forissier static int ssl_write_real(mbedtls_ssl_context *ssl,
612911fa71b9SJerome Forissier const unsigned char *buf, size_t len)
613011fa71b9SJerome Forissier {
613111fa71b9SJerome Forissier int ret = mbedtls_ssl_get_max_out_record_payload(ssl);
613211fa71b9SJerome Forissier const size_t max_len = (size_t) ret;
613311fa71b9SJerome Forissier
613432b31808SJens Wiklander if (ret < 0) {
613511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_max_out_record_payload", ret);
613632b31808SJens Wiklander return ret;
613711fa71b9SJerome Forissier }
613811fa71b9SJerome Forissier
613932b31808SJens Wiklander if (len > max_len) {
614011fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
614132b31808SJens Wiklander if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
614211fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(1, ("fragment larger than the (negotiated) "
61437901324dSJerome Forissier "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
61447901324dSJerome Forissier " > %" MBEDTLS_PRINTF_SIZET,
614511fa71b9SJerome Forissier len, max_len));
614632b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
614732b31808SJens Wiklander } else
614811fa71b9SJerome Forissier #endif
614911fa71b9SJerome Forissier len = max_len;
615011fa71b9SJerome Forissier }
615111fa71b9SJerome Forissier
615232b31808SJens Wiklander if (ssl->out_left != 0) {
615311fa71b9SJerome Forissier /*
615411fa71b9SJerome Forissier * The user has previously tried to send the data and
615511fa71b9SJerome Forissier * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
615611fa71b9SJerome Forissier * written. In this case, we expect the high-level write function
615711fa71b9SJerome Forissier * (e.g. mbedtls_ssl_write()) to be called with the same parameters
615811fa71b9SJerome Forissier */
615932b31808SJens Wiklander if ((ret = mbedtls_ssl_flush_output(ssl)) != 0) {
616011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
616132b31808SJens Wiklander return ret;
616211fa71b9SJerome Forissier }
616332b31808SJens Wiklander } else {
616411fa71b9SJerome Forissier /*
616511fa71b9SJerome Forissier * The user is trying to send a message the first time, so we need to
616611fa71b9SJerome Forissier * copy the data into the internal buffers and setup the data structure
616711fa71b9SJerome Forissier * to keep track of partial writes
616811fa71b9SJerome Forissier */
616911fa71b9SJerome Forissier ssl->out_msglen = len;
617011fa71b9SJerome Forissier ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
617132b31808SJens Wiklander if (len > 0) {
617211fa71b9SJerome Forissier memcpy(ssl->out_msg, buf, len);
617332b31808SJens Wiklander }
617411fa71b9SJerome Forissier
617532b31808SJens Wiklander if ((ret = mbedtls_ssl_write_record(ssl, SSL_FORCE_FLUSH)) != 0) {
617611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_record", ret);
617732b31808SJens Wiklander return ret;
617811fa71b9SJerome Forissier }
617911fa71b9SJerome Forissier }
618011fa71b9SJerome Forissier
618132b31808SJens Wiklander return (int) len;
618211fa71b9SJerome Forissier }
618311fa71b9SJerome Forissier
618411fa71b9SJerome Forissier /*
618511fa71b9SJerome Forissier * Write application data (public-facing wrapper)
618611fa71b9SJerome Forissier */
mbedtls_ssl_write(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)618711fa71b9SJerome Forissier int mbedtls_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len)
618811fa71b9SJerome Forissier {
618911fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
619011fa71b9SJerome Forissier
619111fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write"));
619211fa71b9SJerome Forissier
619332b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) {
619432b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
619532b31808SJens Wiklander }
619611fa71b9SJerome Forissier
619711fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_RENEGOTIATION)
619832b31808SJens Wiklander if ((ret = ssl_check_ctr_renegotiate(ssl)) != 0) {
619911fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "ssl_check_ctr_renegotiate", ret);
620032b31808SJens Wiklander return ret;
620111fa71b9SJerome Forissier }
620211fa71b9SJerome Forissier #endif
620311fa71b9SJerome Forissier
620432b31808SJens Wiklander if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
620532b31808SJens Wiklander if ((ret = mbedtls_ssl_handshake(ssl)) != 0) {
620611fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
620732b31808SJens Wiklander return ret;
620811fa71b9SJerome Forissier }
620911fa71b9SJerome Forissier }
621011fa71b9SJerome Forissier
621111fa71b9SJerome Forissier ret = ssl_write_real(ssl, buf, len);
621211fa71b9SJerome Forissier
621311fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write"));
621411fa71b9SJerome Forissier
621532b31808SJens Wiklander return ret;
621611fa71b9SJerome Forissier }
621711fa71b9SJerome Forissier
6218b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_CLI_C)
mbedtls_ssl_write_early_data(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)6219b0563631STom Van Eyck int mbedtls_ssl_write_early_data(mbedtls_ssl_context *ssl,
6220b0563631STom Van Eyck const unsigned char *buf, size_t len)
6221b0563631STom Van Eyck {
6222b0563631STom Van Eyck int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
6223b0563631STom Van Eyck const struct mbedtls_ssl_config *conf;
6224b0563631STom Van Eyck uint32_t remaining;
6225b0563631STom Van Eyck
6226b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(2, ("=> write early_data"));
6227b0563631STom Van Eyck
6228b0563631STom Van Eyck if (ssl == NULL || (conf = ssl->conf) == NULL) {
6229b0563631STom Van Eyck return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6230b0563631STom Van Eyck }
6231b0563631STom Van Eyck
6232b0563631STom Van Eyck if (conf->endpoint != MBEDTLS_SSL_IS_CLIENT) {
6233b0563631STom Van Eyck return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
6234b0563631STom Van Eyck }
6235b0563631STom Van Eyck
6236b0563631STom Van Eyck if ((!mbedtls_ssl_conf_is_tls13_enabled(conf)) ||
6237b0563631STom Van Eyck (conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
6238b0563631STom Van Eyck (conf->early_data_enabled != MBEDTLS_SSL_EARLY_DATA_ENABLED)) {
6239b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6240b0563631STom Van Eyck }
6241b0563631STom Van Eyck
6242b0563631STom Van Eyck if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_3) {
6243b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6244b0563631STom Van Eyck }
6245b0563631STom Van Eyck
6246b0563631STom Van Eyck /*
6247b0563631STom Van Eyck * If we are at the beginning of the handshake, the early data state being
6248b0563631STom Van Eyck * equal to MBEDTLS_SSL_EARLY_DATA_STATE_IDLE or
6249b0563631STom Van Eyck * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT advance the handshake just
6250b0563631STom Van Eyck * enough to be able to send early data if possible. That way, we can
6251b0563631STom Van Eyck * guarantee that when starting the handshake with this function we will
6252b0563631STom Van Eyck * send at least one record of early data. Note that when the state is
6253b0563631STom Van Eyck * MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT and not yet
6254b0563631STom Van Eyck * MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE, we cannot send early data
6255b0563631STom Van Eyck * as the early data outbound transform has not been set as we may have to
6256b0563631STom Van Eyck * first send a dummy CCS in clear.
6257b0563631STom Van Eyck */
6258b0563631STom Van Eyck if ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6259b0563631STom Van Eyck (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6260b0563631STom Van Eyck while ((ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IDLE) ||
6261b0563631STom Van Eyck (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT)) {
6262b0563631STom Van Eyck ret = mbedtls_ssl_handshake_step(ssl);
6263b0563631STom Van Eyck if (ret != 0) {
6264b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake_step", ret);
6265b0563631STom Van Eyck return ret;
6266b0563631STom Van Eyck }
6267b0563631STom Van Eyck
6268b0563631STom Van Eyck ret = mbedtls_ssl_flush_output(ssl);
6269b0563631STom Van Eyck if (ret != 0) {
6270b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flush_output", ret);
6271b0563631STom Van Eyck return ret;
6272b0563631STom Van Eyck }
6273b0563631STom Van Eyck }
6274b0563631STom Van Eyck remaining = ssl->session_negotiate->max_early_data_size;
6275b0563631STom Van Eyck } else {
6276b0563631STom Van Eyck /*
6277b0563631STom Van Eyck * If we are past the point where we can send early data or we have
6278b0563631STom Van Eyck * already reached the maximum early data size, return immediatly.
6279b0563631STom Van Eyck * Otherwise, progress the handshake as much as possible to not delay
6280b0563631STom Van Eyck * it too much. If we reach a point where we can still send early data,
6281b0563631STom Van Eyck * then we will send some.
6282b0563631STom Van Eyck */
6283b0563631STom Van Eyck if ((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6284b0563631STom Van Eyck (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED)) {
6285b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6286b0563631STom Van Eyck }
6287b0563631STom Van Eyck
6288b0563631STom Van Eyck remaining = ssl->session_negotiate->max_early_data_size -
6289b0563631STom Van Eyck ssl->total_early_data_size;
6290b0563631STom Van Eyck
6291b0563631STom Van Eyck if (remaining == 0) {
6292b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6293b0563631STom Van Eyck }
6294b0563631STom Van Eyck
6295b0563631STom Van Eyck ret = mbedtls_ssl_handshake(ssl);
6296b0563631STom Van Eyck if ((ret != 0) && (ret != MBEDTLS_ERR_SSL_WANT_READ)) {
6297b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_handshake", ret);
6298b0563631STom Van Eyck return ret;
6299b0563631STom Van Eyck }
6300b0563631STom Van Eyck }
6301b0563631STom Van Eyck
6302b0563631STom Van Eyck if (((ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE) &&
6303b0563631STom Van Eyck (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED))
6304b0563631STom Van Eyck || (remaining == 0)) {
6305b0563631STom Van Eyck return MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA;
6306b0563631STom Van Eyck }
6307b0563631STom Van Eyck
6308b0563631STom Van Eyck if (len > remaining) {
6309b0563631STom Van Eyck len = remaining;
6310b0563631STom Van Eyck }
6311b0563631STom Van Eyck
6312b0563631STom Van Eyck ret = ssl_write_real(ssl, buf, len);
6313b0563631STom Van Eyck if (ret >= 0) {
6314b0563631STom Van Eyck ssl->total_early_data_size += ret;
6315b0563631STom Van Eyck }
6316b0563631STom Van Eyck
6317b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(2, ("<= write early_data, ret=%d", ret));
6318b0563631STom Van Eyck
6319b0563631STom Van Eyck return ret;
6320b0563631STom Van Eyck }
6321b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA && MBEDTLS_SSL_CLI_C */
6322b0563631STom Van Eyck
632311fa71b9SJerome Forissier /*
632411fa71b9SJerome Forissier * Notify the peer that the connection is being closed
632511fa71b9SJerome Forissier */
mbedtls_ssl_close_notify(mbedtls_ssl_context * ssl)632611fa71b9SJerome Forissier int mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
632711fa71b9SJerome Forissier {
632811fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
632911fa71b9SJerome Forissier
633032b31808SJens Wiklander if (ssl == NULL || ssl->conf == NULL) {
633132b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
633232b31808SJens Wiklander }
633311fa71b9SJerome Forissier
633411fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("=> write close notify"));
633511fa71b9SJerome Forissier
633632b31808SJens Wiklander if (mbedtls_ssl_is_handshake_over(ssl) == 1) {
633711fa71b9SJerome Forissier if ((ret = mbedtls_ssl_send_alert_message(ssl,
633811fa71b9SJerome Forissier MBEDTLS_SSL_ALERT_LEVEL_WARNING,
633932b31808SJens Wiklander MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY)) != 0) {
634011fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_send_alert_message", ret);
634132b31808SJens Wiklander return ret;
634211fa71b9SJerome Forissier }
634311fa71b9SJerome Forissier }
634411fa71b9SJerome Forissier
634511fa71b9SJerome Forissier MBEDTLS_SSL_DEBUG_MSG(2, ("<= write close notify"));
634611fa71b9SJerome Forissier
634732b31808SJens Wiklander return 0;
634811fa71b9SJerome Forissier }
634911fa71b9SJerome Forissier
mbedtls_ssl_transform_free(mbedtls_ssl_transform * transform)635011fa71b9SJerome Forissier void mbedtls_ssl_transform_free(mbedtls_ssl_transform *transform)
635111fa71b9SJerome Forissier {
635232b31808SJens Wiklander if (transform == NULL) {
635311fa71b9SJerome Forissier return;
635432b31808SJens Wiklander }
635511fa71b9SJerome Forissier
635632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
635732b31808SJens Wiklander psa_destroy_key(transform->psa_key_enc);
635832b31808SJens Wiklander psa_destroy_key(transform->psa_key_dec);
635932b31808SJens Wiklander #else
636011fa71b9SJerome Forissier mbedtls_cipher_free(&transform->cipher_ctx_enc);
636111fa71b9SJerome Forissier mbedtls_cipher_free(&transform->cipher_ctx_dec);
636232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
636311fa71b9SJerome Forissier
636432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
636532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
636632b31808SJens Wiklander psa_destroy_key(transform->psa_mac_enc);
636732b31808SJens Wiklander psa_destroy_key(transform->psa_mac_dec);
636832b31808SJens Wiklander #else
636911fa71b9SJerome Forissier mbedtls_md_free(&transform->md_ctx_enc);
637011fa71b9SJerome Forissier mbedtls_md_free(&transform->md_ctx_dec);
637132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
637211fa71b9SJerome Forissier #endif
637311fa71b9SJerome Forissier
637411fa71b9SJerome Forissier mbedtls_platform_zeroize(transform, sizeof(mbedtls_ssl_transform));
637511fa71b9SJerome Forissier }
637611fa71b9SJerome Forissier
mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context * ssl,mbedtls_ssl_transform * transform)637732b31808SJens Wiklander void mbedtls_ssl_set_inbound_transform(mbedtls_ssl_context *ssl,
637832b31808SJens Wiklander mbedtls_ssl_transform *transform)
637932b31808SJens Wiklander {
638032b31808SJens Wiklander ssl->transform_in = transform;
638132b31808SJens Wiklander memset(ssl->in_ctr, 0, MBEDTLS_SSL_SEQUENCE_NUMBER_LEN);
638232b31808SJens Wiklander }
638332b31808SJens Wiklander
mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context * ssl,mbedtls_ssl_transform * transform)638432b31808SJens Wiklander void mbedtls_ssl_set_outbound_transform(mbedtls_ssl_context *ssl,
638532b31808SJens Wiklander mbedtls_ssl_transform *transform)
638632b31808SJens Wiklander {
638732b31808SJens Wiklander ssl->transform_out = transform;
638832b31808SJens Wiklander memset(ssl->cur_out_ctr, 0, sizeof(ssl->cur_out_ctr));
638932b31808SJens Wiklander }
639032b31808SJens Wiklander
639111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
639211fa71b9SJerome Forissier
mbedtls_ssl_buffering_free(mbedtls_ssl_context * ssl)639311fa71b9SJerome Forissier void mbedtls_ssl_buffering_free(mbedtls_ssl_context *ssl)
639411fa71b9SJerome Forissier {
639511fa71b9SJerome Forissier unsigned offset;
639611fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
639711fa71b9SJerome Forissier
639832b31808SJens Wiklander if (hs == NULL) {
639911fa71b9SJerome Forissier return;
640032b31808SJens Wiklander }
640111fa71b9SJerome Forissier
640211fa71b9SJerome Forissier ssl_free_buffered_record(ssl);
640311fa71b9SJerome Forissier
640432b31808SJens Wiklander for (offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++) {
640511fa71b9SJerome Forissier ssl_buffering_free_slot(ssl, offset);
640611fa71b9SJerome Forissier }
640732b31808SJens Wiklander }
640811fa71b9SJerome Forissier
ssl_buffering_free_slot(mbedtls_ssl_context * ssl,uint8_t slot)640911fa71b9SJerome Forissier static void ssl_buffering_free_slot(mbedtls_ssl_context *ssl,
641011fa71b9SJerome Forissier uint8_t slot)
641111fa71b9SJerome Forissier {
641211fa71b9SJerome Forissier mbedtls_ssl_handshake_params * const hs = ssl->handshake;
641311fa71b9SJerome Forissier mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
641411fa71b9SJerome Forissier
641532b31808SJens Wiklander if (slot >= MBEDTLS_SSL_MAX_BUFFERED_HS) {
641611fa71b9SJerome Forissier return;
641732b31808SJens Wiklander }
641811fa71b9SJerome Forissier
641932b31808SJens Wiklander if (hs_buf->is_valid == 1) {
642011fa71b9SJerome Forissier hs->buffering.total_bytes_buffered -= hs_buf->data_len;
6421b0563631STom Van Eyck mbedtls_zeroize_and_free(hs_buf->data, hs_buf->data_len);
642211fa71b9SJerome Forissier memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer));
642311fa71b9SJerome Forissier }
642411fa71b9SJerome Forissier }
642511fa71b9SJerome Forissier
642611fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_PROTO_DTLS */
642711fa71b9SJerome Forissier
642811fa71b9SJerome Forissier /*
642911fa71b9SJerome Forissier * Convert version numbers to/from wire format
643011fa71b9SJerome Forissier * and, for DTLS, to/from TLS equivalent.
643111fa71b9SJerome Forissier *
643211fa71b9SJerome Forissier * For TLS this is the identity.
643332b31808SJens Wiklander * For DTLS, map as follows, then use 1's complement (v -> ~v):
643411fa71b9SJerome Forissier * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
643532b31808SJens Wiklander * DTLS 1.0 is stored as TLS 1.1 internally
643611fa71b9SJerome Forissier */
mbedtls_ssl_write_version(unsigned char version[2],int transport,mbedtls_ssl_protocol_version tls_version)643732b31808SJens Wiklander void mbedtls_ssl_write_version(unsigned char version[2], int transport,
643832b31808SJens Wiklander mbedtls_ssl_protocol_version tls_version)
643911fa71b9SJerome Forissier {
6440b0563631STom Van Eyck uint16_t tls_version_formatted;
644111fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
644232b31808SJens Wiklander if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
6443b0563631STom Van Eyck tls_version_formatted =
644432b31808SJens Wiklander ~(tls_version - (tls_version == 0x0302 ? 0x0202 : 0x0201));
6445b0563631STom Van Eyck } else
644611fa71b9SJerome Forissier #else
644711fa71b9SJerome Forissier ((void) transport);
644811fa71b9SJerome Forissier #endif
6449b0563631STom Van Eyck {
6450b0563631STom Van Eyck tls_version_formatted = (uint16_t) tls_version;
6451b0563631STom Van Eyck }
6452b0563631STom Van Eyck MBEDTLS_PUT_UINT16_BE(tls_version_formatted, version, 0);
645311fa71b9SJerome Forissier }
645411fa71b9SJerome Forissier
mbedtls_ssl_read_version(const unsigned char version[2],int transport)645532b31808SJens Wiklander uint16_t mbedtls_ssl_read_version(const unsigned char version[2],
645632b31808SJens Wiklander int transport)
645711fa71b9SJerome Forissier {
645832b31808SJens Wiklander uint16_t tls_version = MBEDTLS_GET_UINT16_BE(version, 0);
645911fa71b9SJerome Forissier #if defined(MBEDTLS_SSL_PROTO_DTLS)
646032b31808SJens Wiklander if (transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
646132b31808SJens Wiklander tls_version =
646232b31808SJens Wiklander ~(tls_version - (tls_version == 0xfeff ? 0x0202 : 0x0201));
646311fa71b9SJerome Forissier }
646411fa71b9SJerome Forissier #else
646511fa71b9SJerome Forissier ((void) transport);
646611fa71b9SJerome Forissier #endif
646732b31808SJens Wiklander return tls_version;
646811fa71b9SJerome Forissier }
646932b31808SJens Wiklander
647032b31808SJens Wiklander /*
647132b31808SJens Wiklander * Send pending fatal alert.
647232b31808SJens Wiklander * 0, No alert message.
647332b31808SJens Wiklander * !0, if mbedtls_ssl_send_alert_message() returned in error, the error code it
647432b31808SJens Wiklander * returned, ssl->alert_reason otherwise.
647532b31808SJens Wiklander */
mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context * ssl)647632b31808SJens Wiklander int mbedtls_ssl_handle_pending_alert(mbedtls_ssl_context *ssl)
647732b31808SJens Wiklander {
647832b31808SJens Wiklander int ret;
647932b31808SJens Wiklander
648032b31808SJens Wiklander /* No pending alert, return success*/
648132b31808SJens Wiklander if (ssl->send_alert == 0) {
648232b31808SJens Wiklander return 0;
648332b31808SJens Wiklander }
648432b31808SJens Wiklander
648532b31808SJens Wiklander ret = mbedtls_ssl_send_alert_message(ssl,
648632b31808SJens Wiklander MBEDTLS_SSL_ALERT_LEVEL_FATAL,
648732b31808SJens Wiklander ssl->alert_type);
648832b31808SJens Wiklander
648932b31808SJens Wiklander /* If mbedtls_ssl_send_alert_message() returned with MBEDTLS_ERR_SSL_WANT_WRITE,
649032b31808SJens Wiklander * do not clear the alert to be able to send it later.
649132b31808SJens Wiklander */
649232b31808SJens Wiklander if (ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
649332b31808SJens Wiklander ssl->send_alert = 0;
649432b31808SJens Wiklander }
649532b31808SJens Wiklander
649632b31808SJens Wiklander if (ret != 0) {
649732b31808SJens Wiklander return ret;
649832b31808SJens Wiklander }
649932b31808SJens Wiklander
650032b31808SJens Wiklander return ssl->alert_reason;
650132b31808SJens Wiklander }
650232b31808SJens Wiklander
650332b31808SJens Wiklander /*
650432b31808SJens Wiklander * Set pending fatal alert flag.
650532b31808SJens Wiklander */
mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context * ssl,unsigned char alert_type,int alert_reason)650632b31808SJens Wiklander void mbedtls_ssl_pend_fatal_alert(mbedtls_ssl_context *ssl,
650732b31808SJens Wiklander unsigned char alert_type,
650832b31808SJens Wiklander int alert_reason)
650932b31808SJens Wiklander {
651032b31808SJens Wiklander ssl->send_alert = 1;
651132b31808SJens Wiklander ssl->alert_type = alert_type;
651232b31808SJens Wiklander ssl->alert_reason = alert_reason;
651311fa71b9SJerome Forissier }
651411fa71b9SJerome Forissier
651511fa71b9SJerome Forissier #endif /* MBEDTLS_SSL_TLS_C */
6516