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