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