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