1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * TLS 1.3 key schedule 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "common.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3) 11a8e1175bSopenharmony_ci 12a8e1175bSopenharmony_ci#include <stdint.h> 13a8e1175bSopenharmony_ci#include <string.h> 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ci#include "mbedtls/hkdf.h" 16a8e1175bSopenharmony_ci#include "debug_internal.h" 17a8e1175bSopenharmony_ci#include "mbedtls/error.h" 18a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 19a8e1175bSopenharmony_ci 20a8e1175bSopenharmony_ci#include "ssl_misc.h" 21a8e1175bSopenharmony_ci#include "ssl_tls13_keys.h" 22a8e1175bSopenharmony_ci#include "ssl_tls13_invasive.h" 23a8e1175bSopenharmony_ci 24a8e1175bSopenharmony_ci#include "psa/crypto.h" 25a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h" 26a8e1175bSopenharmony_ci 27a8e1175bSopenharmony_ci/* Define a local translating function to save code size by not using too many 28a8e1175bSopenharmony_ci * arguments in each translating place. */ 29a8e1175bSopenharmony_cistatic int local_err_translation(psa_status_t status) 30a8e1175bSopenharmony_ci{ 31a8e1175bSopenharmony_ci return psa_status_to_mbedtls(status, psa_to_ssl_errors, 32a8e1175bSopenharmony_ci ARRAY_LENGTH(psa_to_ssl_errors), 33a8e1175bSopenharmony_ci psa_generic_status_to_mbedtls); 34a8e1175bSopenharmony_ci} 35a8e1175bSopenharmony_ci#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) 36a8e1175bSopenharmony_ci 37a8e1175bSopenharmony_ci#define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ 38a8e1175bSopenharmony_ci .name = string, 39a8e1175bSopenharmony_ci 40a8e1175bSopenharmony_cistruct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels = 41a8e1175bSopenharmony_ci{ 42a8e1175bSopenharmony_ci /* This seems to work in C, despite the string literal being one 43a8e1175bSopenharmony_ci * character too long due to the 0-termination. */ 44a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LABEL_LIST 45a8e1175bSopenharmony_ci}; 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci#undef MBEDTLS_SSL_TLS1_3_LABEL 48a8e1175bSopenharmony_ci 49a8e1175bSopenharmony_ci/* 50a8e1175bSopenharmony_ci * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule. 51a8e1175bSopenharmony_ci * 52a8e1175bSopenharmony_ci * The HkdfLabel is specified in RFC 8446 as follows: 53a8e1175bSopenharmony_ci * 54a8e1175bSopenharmony_ci * struct HkdfLabel { 55a8e1175bSopenharmony_ci * uint16 length; // Length of expanded key material 56a8e1175bSopenharmony_ci * opaque label<7..255>; // Always prefixed by "tls13 " 57a8e1175bSopenharmony_ci * opaque context<0..255>; // Usually a communication transcript hash 58a8e1175bSopenharmony_ci * }; 59a8e1175bSopenharmony_ci * 60a8e1175bSopenharmony_ci * Parameters: 61a8e1175bSopenharmony_ci * - desired_length: Length of expanded key material 62a8e1175bSopenharmony_ci * Even though the standard allows expansion to up to 63a8e1175bSopenharmony_ci * 2**16 Bytes, TLS 1.3 never uses expansion to more than 64a8e1175bSopenharmony_ci * 255 Bytes, so we require `desired_length` to be at most 65a8e1175bSopenharmony_ci * 255. This allows us to save a few Bytes of code by 66a8e1175bSopenharmony_ci * hardcoding the writing of the high bytes. 67a8e1175bSopenharmony_ci * - (label, label_len): label + label length, without "tls13 " prefix 68a8e1175bSopenharmony_ci * The label length MUST be less than or equal to 69a8e1175bSopenharmony_ci * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN 70a8e1175bSopenharmony_ci * It is the caller's responsibility to ensure this. 71a8e1175bSopenharmony_ci * All (label, label length) pairs used in TLS 1.3 72a8e1175bSopenharmony_ci * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). 73a8e1175bSopenharmony_ci * - (ctx, ctx_len): context + context length 74a8e1175bSopenharmony_ci * The context length MUST be less than or equal to 75a8e1175bSopenharmony_ci * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN 76a8e1175bSopenharmony_ci * It is the caller's responsibility to ensure this. 77a8e1175bSopenharmony_ci * - dst: Target buffer for HkdfLabel structure, 78a8e1175bSopenharmony_ci * This MUST be a writable buffer of size 79a8e1175bSopenharmony_ci * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes. 80a8e1175bSopenharmony_ci * - dst_len: Pointer at which to store the actual length of 81a8e1175bSopenharmony_ci * the HkdfLabel structure on success. 82a8e1175bSopenharmony_ci */ 83a8e1175bSopenharmony_ci 84a8e1175bSopenharmony_cistatic const char tls13_label_prefix[6] = "tls13 "; 85a8e1175bSopenharmony_ci 86a8e1175bSopenharmony_ci#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \ 87a8e1175bSopenharmony_ci (2 /* expansion length */ \ 88a8e1175bSopenharmony_ci + 1 /* label length */ \ 89a8e1175bSopenharmony_ci + label_len \ 90a8e1175bSopenharmony_ci + 1 /* context length */ \ 91a8e1175bSopenharmony_ci + context_len) 92a8e1175bSopenharmony_ci 93a8e1175bSopenharmony_ci#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ 94a8e1175bSopenharmony_ci SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ 95a8e1175bSopenharmony_ci sizeof(tls13_label_prefix) + \ 96a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \ 97a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) 98a8e1175bSopenharmony_ci 99a8e1175bSopenharmony_cistatic void ssl_tls13_hkdf_encode_label( 100a8e1175bSopenharmony_ci size_t desired_length, 101a8e1175bSopenharmony_ci const unsigned char *label, size_t label_len, 102a8e1175bSopenharmony_ci const unsigned char *ctx, size_t ctx_len, 103a8e1175bSopenharmony_ci unsigned char *dst, size_t *dst_len) 104a8e1175bSopenharmony_ci{ 105a8e1175bSopenharmony_ci size_t total_label_len = 106a8e1175bSopenharmony_ci sizeof(tls13_label_prefix) + label_len; 107a8e1175bSopenharmony_ci size_t total_hkdf_lbl_len = 108a8e1175bSopenharmony_ci SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(total_label_len, ctx_len); 109a8e1175bSopenharmony_ci 110a8e1175bSopenharmony_ci unsigned char *p = dst; 111a8e1175bSopenharmony_ci 112a8e1175bSopenharmony_ci /* Add the size of the expanded key material. 113a8e1175bSopenharmony_ci * We're hardcoding the high byte to 0 here assuming that we never use 114a8e1175bSopenharmony_ci * TLS 1.3 HKDF key expansion to more than 255 Bytes. */ 115a8e1175bSopenharmony_ci#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255 116a8e1175bSopenharmony_ci#error "The implementation of ssl_tls13_hkdf_encode_label() is not fit for the \ 117a8e1175bSopenharmony_ci value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN" 118a8e1175bSopenharmony_ci#endif 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci *p++ = 0; 121a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(desired_length); 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_ci /* Add label incl. prefix */ 124a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(total_label_len); 125a8e1175bSopenharmony_ci memcpy(p, tls13_label_prefix, sizeof(tls13_label_prefix)); 126a8e1175bSopenharmony_ci p += sizeof(tls13_label_prefix); 127a8e1175bSopenharmony_ci memcpy(p, label, label_len); 128a8e1175bSopenharmony_ci p += label_len; 129a8e1175bSopenharmony_ci 130a8e1175bSopenharmony_ci /* Add context value */ 131a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(ctx_len); 132a8e1175bSopenharmony_ci if (ctx_len != 0) { 133a8e1175bSopenharmony_ci memcpy(p, ctx, ctx_len); 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci 136a8e1175bSopenharmony_ci /* Return total length to the caller. */ 137a8e1175bSopenharmony_ci *dst_len = total_hkdf_lbl_len; 138a8e1175bSopenharmony_ci} 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_hkdf_expand_label( 141a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 142a8e1175bSopenharmony_ci const unsigned char *secret, size_t secret_len, 143a8e1175bSopenharmony_ci const unsigned char *label, size_t label_len, 144a8e1175bSopenharmony_ci const unsigned char *ctx, size_t ctx_len, 145a8e1175bSopenharmony_ci unsigned char *buf, size_t buf_len) 146a8e1175bSopenharmony_ci{ 147a8e1175bSopenharmony_ci unsigned char hkdf_label[SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN]; 148a8e1175bSopenharmony_ci size_t hkdf_label_len = 0; 149a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 150a8e1175bSopenharmony_ci psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; 151a8e1175bSopenharmony_ci psa_key_derivation_operation_t operation = 152a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_OPERATION_INIT; 153a8e1175bSopenharmony_ci 154a8e1175bSopenharmony_ci if (label_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN) { 155a8e1175bSopenharmony_ci /* Should never happen since this is an internal 156a8e1175bSopenharmony_ci * function, and we know statically which labels 157a8e1175bSopenharmony_ci * are allowed. */ 158a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 159a8e1175bSopenharmony_ci } 160a8e1175bSopenharmony_ci 161a8e1175bSopenharmony_ci if (ctx_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) { 162a8e1175bSopenharmony_ci /* Should not happen, as above. */ 163a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 164a8e1175bSopenharmony_ci } 165a8e1175bSopenharmony_ci 166a8e1175bSopenharmony_ci if (buf_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN) { 167a8e1175bSopenharmony_ci /* Should not happen, as above. */ 168a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 169a8e1175bSopenharmony_ci } 170a8e1175bSopenharmony_ci 171a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 172a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 173a8e1175bSopenharmony_ci } 174a8e1175bSopenharmony_ci 175a8e1175bSopenharmony_ci ssl_tls13_hkdf_encode_label(buf_len, 176a8e1175bSopenharmony_ci label, label_len, 177a8e1175bSopenharmony_ci ctx, ctx_len, 178a8e1175bSopenharmony_ci hkdf_label, 179a8e1175bSopenharmony_ci &hkdf_label_len); 180a8e1175bSopenharmony_ci 181a8e1175bSopenharmony_ci status = psa_key_derivation_setup(&operation, PSA_ALG_HKDF_EXPAND(hash_alg)); 182a8e1175bSopenharmony_ci 183a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 184a8e1175bSopenharmony_ci goto cleanup; 185a8e1175bSopenharmony_ci } 186a8e1175bSopenharmony_ci 187a8e1175bSopenharmony_ci status = psa_key_derivation_input_bytes(&operation, 188a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_INPUT_SECRET, 189a8e1175bSopenharmony_ci secret, 190a8e1175bSopenharmony_ci secret_len); 191a8e1175bSopenharmony_ci 192a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 193a8e1175bSopenharmony_ci goto cleanup; 194a8e1175bSopenharmony_ci } 195a8e1175bSopenharmony_ci 196a8e1175bSopenharmony_ci status = psa_key_derivation_input_bytes(&operation, 197a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_INPUT_INFO, 198a8e1175bSopenharmony_ci hkdf_label, 199a8e1175bSopenharmony_ci hkdf_label_len); 200a8e1175bSopenharmony_ci 201a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 202a8e1175bSopenharmony_ci goto cleanup; 203a8e1175bSopenharmony_ci } 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci status = psa_key_derivation_output_bytes(&operation, 206a8e1175bSopenharmony_ci buf, 207a8e1175bSopenharmony_ci buf_len); 208a8e1175bSopenharmony_ci 209a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 210a8e1175bSopenharmony_ci goto cleanup; 211a8e1175bSopenharmony_ci } 212a8e1175bSopenharmony_ci 213a8e1175bSopenharmony_cicleanup: 214a8e1175bSopenharmony_ci abort_status = psa_key_derivation_abort(&operation); 215a8e1175bSopenharmony_ci status = (status == PSA_SUCCESS ? abort_status : status); 216a8e1175bSopenharmony_ci mbedtls_platform_zeroize(hkdf_label, hkdf_label_len); 217a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 218a8e1175bSopenharmony_ci} 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 221a8e1175bSopenharmony_cistatic int ssl_tls13_make_traffic_key( 222a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 223a8e1175bSopenharmony_ci const unsigned char *secret, size_t secret_len, 224a8e1175bSopenharmony_ci unsigned char *key, size_t key_len, 225a8e1175bSopenharmony_ci unsigned char *iv, size_t iv_len) 226a8e1175bSopenharmony_ci{ 227a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 228a8e1175bSopenharmony_ci 229a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_hkdf_expand_label( 230a8e1175bSopenharmony_ci hash_alg, 231a8e1175bSopenharmony_ci secret, secret_len, 232a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key), 233a8e1175bSopenharmony_ci NULL, 0, 234a8e1175bSopenharmony_ci key, key_len); 235a8e1175bSopenharmony_ci if (ret != 0) { 236a8e1175bSopenharmony_ci return ret; 237a8e1175bSopenharmony_ci } 238a8e1175bSopenharmony_ci 239a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_hkdf_expand_label( 240a8e1175bSopenharmony_ci hash_alg, 241a8e1175bSopenharmony_ci secret, secret_len, 242a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv), 243a8e1175bSopenharmony_ci NULL, 0, 244a8e1175bSopenharmony_ci iv, iv_len); 245a8e1175bSopenharmony_ci return ret; 246a8e1175bSopenharmony_ci} 247a8e1175bSopenharmony_ci 248a8e1175bSopenharmony_ci/* 249a8e1175bSopenharmony_ci * The traffic keying material is generated from the following inputs: 250a8e1175bSopenharmony_ci * 251a8e1175bSopenharmony_ci * - One secret value per sender. 252a8e1175bSopenharmony_ci * - A purpose value indicating the specific value being generated 253a8e1175bSopenharmony_ci * - The desired lengths of key and IV. 254a8e1175bSopenharmony_ci * 255a8e1175bSopenharmony_ci * The expansion itself is based on HKDF: 256a8e1175bSopenharmony_ci * 257a8e1175bSopenharmony_ci * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length ) 258a8e1175bSopenharmony_ci * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length ) 259a8e1175bSopenharmony_ci * 260a8e1175bSopenharmony_ci * [sender] denotes the sending side and the Secret value is provided 261a8e1175bSopenharmony_ci * by the function caller. Note that we generate server and client side 262a8e1175bSopenharmony_ci * keys in a single function call. 263a8e1175bSopenharmony_ci */ 264a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_make_traffic_keys( 265a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 266a8e1175bSopenharmony_ci const unsigned char *client_secret, 267a8e1175bSopenharmony_ci const unsigned char *server_secret, size_t secret_len, 268a8e1175bSopenharmony_ci size_t key_len, size_t iv_len, 269a8e1175bSopenharmony_ci mbedtls_ssl_key_set *keys) 270a8e1175bSopenharmony_ci{ 271a8e1175bSopenharmony_ci int ret = 0; 272a8e1175bSopenharmony_ci 273a8e1175bSopenharmony_ci ret = ssl_tls13_make_traffic_key( 274a8e1175bSopenharmony_ci hash_alg, client_secret, secret_len, 275a8e1175bSopenharmony_ci keys->client_write_key, key_len, 276a8e1175bSopenharmony_ci keys->client_write_iv, iv_len); 277a8e1175bSopenharmony_ci if (ret != 0) { 278a8e1175bSopenharmony_ci return ret; 279a8e1175bSopenharmony_ci } 280a8e1175bSopenharmony_ci 281a8e1175bSopenharmony_ci ret = ssl_tls13_make_traffic_key( 282a8e1175bSopenharmony_ci hash_alg, server_secret, secret_len, 283a8e1175bSopenharmony_ci keys->server_write_key, key_len, 284a8e1175bSopenharmony_ci keys->server_write_iv, iv_len); 285a8e1175bSopenharmony_ci if (ret != 0) { 286a8e1175bSopenharmony_ci return ret; 287a8e1175bSopenharmony_ci } 288a8e1175bSopenharmony_ci 289a8e1175bSopenharmony_ci keys->key_len = key_len; 290a8e1175bSopenharmony_ci keys->iv_len = iv_len; 291a8e1175bSopenharmony_ci 292a8e1175bSopenharmony_ci return 0; 293a8e1175bSopenharmony_ci} 294a8e1175bSopenharmony_ci 295a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_derive_secret( 296a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 297a8e1175bSopenharmony_ci const unsigned char *secret, size_t secret_len, 298a8e1175bSopenharmony_ci const unsigned char *label, size_t label_len, 299a8e1175bSopenharmony_ci const unsigned char *ctx, size_t ctx_len, 300a8e1175bSopenharmony_ci int ctx_hashed, 301a8e1175bSopenharmony_ci unsigned char *dstbuf, size_t dstbuf_len) 302a8e1175bSopenharmony_ci{ 303a8e1175bSopenharmony_ci int ret; 304a8e1175bSopenharmony_ci unsigned char hashed_context[PSA_HASH_MAX_SIZE]; 305a8e1175bSopenharmony_ci if (ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED) { 306a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 307a8e1175bSopenharmony_ci 308a8e1175bSopenharmony_ci status = psa_hash_compute(hash_alg, ctx, ctx_len, hashed_context, 309a8e1175bSopenharmony_ci PSA_HASH_LENGTH(hash_alg), &ctx_len); 310a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 311a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 312a8e1175bSopenharmony_ci return ret; 313a8e1175bSopenharmony_ci } 314a8e1175bSopenharmony_ci } else { 315a8e1175bSopenharmony_ci if (ctx_len > sizeof(hashed_context)) { 316a8e1175bSopenharmony_ci /* This should never happen since this function is internal 317a8e1175bSopenharmony_ci * and the code sets `ctx_hashed` correctly. 318a8e1175bSopenharmony_ci * Let's double-check nonetheless to not run at the risk 319a8e1175bSopenharmony_ci * of getting a stack overflow. */ 320a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 321a8e1175bSopenharmony_ci } 322a8e1175bSopenharmony_ci 323a8e1175bSopenharmony_ci memcpy(hashed_context, ctx, ctx_len); 324a8e1175bSopenharmony_ci } 325a8e1175bSopenharmony_ci 326a8e1175bSopenharmony_ci return mbedtls_ssl_tls13_hkdf_expand_label(hash_alg, 327a8e1175bSopenharmony_ci secret, secret_len, 328a8e1175bSopenharmony_ci label, label_len, 329a8e1175bSopenharmony_ci hashed_context, ctx_len, 330a8e1175bSopenharmony_ci dstbuf, dstbuf_len); 331a8e1175bSopenharmony_ci 332a8e1175bSopenharmony_ci} 333a8e1175bSopenharmony_ci 334a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_evolve_secret( 335a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 336a8e1175bSopenharmony_ci const unsigned char *secret_old, 337a8e1175bSopenharmony_ci const unsigned char *input, size_t input_len, 338a8e1175bSopenharmony_ci unsigned char *secret_new) 339a8e1175bSopenharmony_ci{ 340a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; 341a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 342a8e1175bSopenharmony_ci psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; 343a8e1175bSopenharmony_ci size_t hlen; 344a8e1175bSopenharmony_ci unsigned char tmp_secret[PSA_MAC_MAX_SIZE] = { 0 }; 345a8e1175bSopenharmony_ci const unsigned char all_zeroes_input[MBEDTLS_TLS1_3_MD_MAX_SIZE] = { 0 }; 346a8e1175bSopenharmony_ci const unsigned char *l_input = NULL; 347a8e1175bSopenharmony_ci size_t l_input_len; 348a8e1175bSopenharmony_ci 349a8e1175bSopenharmony_ci psa_key_derivation_operation_t operation = 350a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_OPERATION_INIT; 351a8e1175bSopenharmony_ci 352a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 353a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 354a8e1175bSopenharmony_ci } 355a8e1175bSopenharmony_ci 356a8e1175bSopenharmony_ci hlen = PSA_HASH_LENGTH(hash_alg); 357a8e1175bSopenharmony_ci 358a8e1175bSopenharmony_ci /* For non-initial runs, call Derive-Secret( ., "derived", "") 359a8e1175bSopenharmony_ci * on the old secret. */ 360a8e1175bSopenharmony_ci if (secret_old != NULL) { 361a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 362a8e1175bSopenharmony_ci hash_alg, 363a8e1175bSopenharmony_ci secret_old, hlen, 364a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(derived), 365a8e1175bSopenharmony_ci NULL, 0, /* context */ 366a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, 367a8e1175bSopenharmony_ci tmp_secret, hlen); 368a8e1175bSopenharmony_ci if (ret != 0) { 369a8e1175bSopenharmony_ci goto cleanup; 370a8e1175bSopenharmony_ci } 371a8e1175bSopenharmony_ci } 372a8e1175bSopenharmony_ci 373a8e1175bSopenharmony_ci ret = 0; 374a8e1175bSopenharmony_ci 375a8e1175bSopenharmony_ci if (input != NULL && input_len != 0) { 376a8e1175bSopenharmony_ci l_input = input; 377a8e1175bSopenharmony_ci l_input_len = input_len; 378a8e1175bSopenharmony_ci } else { 379a8e1175bSopenharmony_ci l_input = all_zeroes_input; 380a8e1175bSopenharmony_ci l_input_len = hlen; 381a8e1175bSopenharmony_ci } 382a8e1175bSopenharmony_ci 383a8e1175bSopenharmony_ci status = psa_key_derivation_setup(&operation, 384a8e1175bSopenharmony_ci PSA_ALG_HKDF_EXTRACT(hash_alg)); 385a8e1175bSopenharmony_ci 386a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 387a8e1175bSopenharmony_ci goto cleanup; 388a8e1175bSopenharmony_ci } 389a8e1175bSopenharmony_ci 390a8e1175bSopenharmony_ci status = psa_key_derivation_input_bytes(&operation, 391a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_INPUT_SALT, 392a8e1175bSopenharmony_ci tmp_secret, 393a8e1175bSopenharmony_ci hlen); 394a8e1175bSopenharmony_ci 395a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 396a8e1175bSopenharmony_ci goto cleanup; 397a8e1175bSopenharmony_ci } 398a8e1175bSopenharmony_ci 399a8e1175bSopenharmony_ci status = psa_key_derivation_input_bytes(&operation, 400a8e1175bSopenharmony_ci PSA_KEY_DERIVATION_INPUT_SECRET, 401a8e1175bSopenharmony_ci l_input, l_input_len); 402a8e1175bSopenharmony_ci 403a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 404a8e1175bSopenharmony_ci goto cleanup; 405a8e1175bSopenharmony_ci } 406a8e1175bSopenharmony_ci 407a8e1175bSopenharmony_ci status = psa_key_derivation_output_bytes(&operation, 408a8e1175bSopenharmony_ci secret_new, 409a8e1175bSopenharmony_ci PSA_HASH_LENGTH(hash_alg)); 410a8e1175bSopenharmony_ci 411a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 412a8e1175bSopenharmony_ci goto cleanup; 413a8e1175bSopenharmony_ci } 414a8e1175bSopenharmony_ci 415a8e1175bSopenharmony_cicleanup: 416a8e1175bSopenharmony_ci abort_status = psa_key_derivation_abort(&operation); 417a8e1175bSopenharmony_ci status = (status == PSA_SUCCESS ? abort_status : status); 418a8e1175bSopenharmony_ci ret = (ret == 0 ? PSA_TO_MBEDTLS_ERR(status) : ret); 419a8e1175bSopenharmony_ci mbedtls_platform_zeroize(tmp_secret, sizeof(tmp_secret)); 420a8e1175bSopenharmony_ci return ret; 421a8e1175bSopenharmony_ci} 422a8e1175bSopenharmony_ci 423a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_derive_early_secrets( 424a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 425a8e1175bSopenharmony_ci unsigned char const *early_secret, 426a8e1175bSopenharmony_ci unsigned char const *transcript, size_t transcript_len, 427a8e1175bSopenharmony_ci mbedtls_ssl_tls13_early_secrets *derived) 428a8e1175bSopenharmony_ci{ 429a8e1175bSopenharmony_ci int ret; 430a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 431a8e1175bSopenharmony_ci 432a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 433a8e1175bSopenharmony_ci * but add an assertion anyway. */ 434a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 435a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 436a8e1175bSopenharmony_ci } 437a8e1175bSopenharmony_ci 438a8e1175bSopenharmony_ci /* 439a8e1175bSopenharmony_ci * 0 440a8e1175bSopenharmony_ci * | 441a8e1175bSopenharmony_ci * v 442a8e1175bSopenharmony_ci * PSK -> HKDF-Extract = Early Secret 443a8e1175bSopenharmony_ci * | 444a8e1175bSopenharmony_ci * +-----> Derive-Secret(., "c e traffic", ClientHello) 445a8e1175bSopenharmony_ci * | = client_early_traffic_secret 446a8e1175bSopenharmony_ci * | 447a8e1175bSopenharmony_ci * +-----> Derive-Secret(., "e exp master", ClientHello) 448a8e1175bSopenharmony_ci * | = early_exporter_master_secret 449a8e1175bSopenharmony_ci * v 450a8e1175bSopenharmony_ci */ 451a8e1175bSopenharmony_ci 452a8e1175bSopenharmony_ci /* Create client_early_traffic_secret */ 453a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 454a8e1175bSopenharmony_ci hash_alg, 455a8e1175bSopenharmony_ci early_secret, hash_len, 456a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic), 457a8e1175bSopenharmony_ci transcript, transcript_len, 458a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 459a8e1175bSopenharmony_ci derived->client_early_traffic_secret, 460a8e1175bSopenharmony_ci hash_len); 461a8e1175bSopenharmony_ci if (ret != 0) { 462a8e1175bSopenharmony_ci return ret; 463a8e1175bSopenharmony_ci } 464a8e1175bSopenharmony_ci 465a8e1175bSopenharmony_ci /* Create early exporter */ 466a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 467a8e1175bSopenharmony_ci hash_alg, 468a8e1175bSopenharmony_ci early_secret, hash_len, 469a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master), 470a8e1175bSopenharmony_ci transcript, transcript_len, 471a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 472a8e1175bSopenharmony_ci derived->early_exporter_master_secret, 473a8e1175bSopenharmony_ci hash_len); 474a8e1175bSopenharmony_ci if (ret != 0) { 475a8e1175bSopenharmony_ci return ret; 476a8e1175bSopenharmony_ci } 477a8e1175bSopenharmony_ci 478a8e1175bSopenharmony_ci return 0; 479a8e1175bSopenharmony_ci} 480a8e1175bSopenharmony_ci 481a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_derive_handshake_secrets( 482a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 483a8e1175bSopenharmony_ci unsigned char const *handshake_secret, 484a8e1175bSopenharmony_ci unsigned char const *transcript, size_t transcript_len, 485a8e1175bSopenharmony_ci mbedtls_ssl_tls13_handshake_secrets *derived) 486a8e1175bSopenharmony_ci{ 487a8e1175bSopenharmony_ci int ret; 488a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 489a8e1175bSopenharmony_ci 490a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 491a8e1175bSopenharmony_ci * but add an assertion anyway. */ 492a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 493a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 494a8e1175bSopenharmony_ci } 495a8e1175bSopenharmony_ci 496a8e1175bSopenharmony_ci /* 497a8e1175bSopenharmony_ci * 498a8e1175bSopenharmony_ci * Handshake Secret 499a8e1175bSopenharmony_ci * | 500a8e1175bSopenharmony_ci * +-----> Derive-Secret( ., "c hs traffic", 501a8e1175bSopenharmony_ci * | ClientHello...ServerHello ) 502a8e1175bSopenharmony_ci * | = client_handshake_traffic_secret 503a8e1175bSopenharmony_ci * | 504a8e1175bSopenharmony_ci * +-----> Derive-Secret( ., "s hs traffic", 505a8e1175bSopenharmony_ci * | ClientHello...ServerHello ) 506a8e1175bSopenharmony_ci * | = server_handshake_traffic_secret 507a8e1175bSopenharmony_ci * 508a8e1175bSopenharmony_ci */ 509a8e1175bSopenharmony_ci 510a8e1175bSopenharmony_ci /* 511a8e1175bSopenharmony_ci * Compute client_handshake_traffic_secret with 512a8e1175bSopenharmony_ci * Derive-Secret( ., "c hs traffic", ClientHello...ServerHello ) 513a8e1175bSopenharmony_ci */ 514a8e1175bSopenharmony_ci 515a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 516a8e1175bSopenharmony_ci hash_alg, 517a8e1175bSopenharmony_ci handshake_secret, hash_len, 518a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic), 519a8e1175bSopenharmony_ci transcript, transcript_len, 520a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 521a8e1175bSopenharmony_ci derived->client_handshake_traffic_secret, 522a8e1175bSopenharmony_ci hash_len); 523a8e1175bSopenharmony_ci if (ret != 0) { 524a8e1175bSopenharmony_ci return ret; 525a8e1175bSopenharmony_ci } 526a8e1175bSopenharmony_ci 527a8e1175bSopenharmony_ci /* 528a8e1175bSopenharmony_ci * Compute server_handshake_traffic_secret with 529a8e1175bSopenharmony_ci * Derive-Secret( ., "s hs traffic", ClientHello...ServerHello ) 530a8e1175bSopenharmony_ci */ 531a8e1175bSopenharmony_ci 532a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 533a8e1175bSopenharmony_ci hash_alg, 534a8e1175bSopenharmony_ci handshake_secret, hash_len, 535a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic), 536a8e1175bSopenharmony_ci transcript, transcript_len, 537a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 538a8e1175bSopenharmony_ci derived->server_handshake_traffic_secret, 539a8e1175bSopenharmony_ci hash_len); 540a8e1175bSopenharmony_ci if (ret != 0) { 541a8e1175bSopenharmony_ci return ret; 542a8e1175bSopenharmony_ci } 543a8e1175bSopenharmony_ci 544a8e1175bSopenharmony_ci return 0; 545a8e1175bSopenharmony_ci} 546a8e1175bSopenharmony_ci 547a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_derive_application_secrets( 548a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 549a8e1175bSopenharmony_ci unsigned char const *application_secret, 550a8e1175bSopenharmony_ci unsigned char const *transcript, size_t transcript_len, 551a8e1175bSopenharmony_ci mbedtls_ssl_tls13_application_secrets *derived) 552a8e1175bSopenharmony_ci{ 553a8e1175bSopenharmony_ci int ret; 554a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 555a8e1175bSopenharmony_ci 556a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 557a8e1175bSopenharmony_ci * but add an assertion anyway. */ 558a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 559a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 560a8e1175bSopenharmony_ci } 561a8e1175bSopenharmony_ci 562a8e1175bSopenharmony_ci /* Generate {client,server}_application_traffic_secret_0 563a8e1175bSopenharmony_ci * 564a8e1175bSopenharmony_ci * Master Secret 565a8e1175bSopenharmony_ci * | 566a8e1175bSopenharmony_ci * +-----> Derive-Secret( ., "c ap traffic", 567a8e1175bSopenharmony_ci * | ClientHello...server Finished ) 568a8e1175bSopenharmony_ci * | = client_application_traffic_secret_0 569a8e1175bSopenharmony_ci * | 570a8e1175bSopenharmony_ci * +-----> Derive-Secret( ., "s ap traffic", 571a8e1175bSopenharmony_ci * | ClientHello...Server Finished ) 572a8e1175bSopenharmony_ci * | = server_application_traffic_secret_0 573a8e1175bSopenharmony_ci * | 574a8e1175bSopenharmony_ci * +-----> Derive-Secret( ., "exp master", 575a8e1175bSopenharmony_ci * | ClientHello...server Finished) 576a8e1175bSopenharmony_ci * | = exporter_master_secret 577a8e1175bSopenharmony_ci * 578a8e1175bSopenharmony_ci */ 579a8e1175bSopenharmony_ci 580a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 581a8e1175bSopenharmony_ci hash_alg, 582a8e1175bSopenharmony_ci application_secret, hash_len, 583a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic), 584a8e1175bSopenharmony_ci transcript, transcript_len, 585a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 586a8e1175bSopenharmony_ci derived->client_application_traffic_secret_N, 587a8e1175bSopenharmony_ci hash_len); 588a8e1175bSopenharmony_ci if (ret != 0) { 589a8e1175bSopenharmony_ci return ret; 590a8e1175bSopenharmony_ci } 591a8e1175bSopenharmony_ci 592a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 593a8e1175bSopenharmony_ci hash_alg, 594a8e1175bSopenharmony_ci application_secret, hash_len, 595a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic), 596a8e1175bSopenharmony_ci transcript, transcript_len, 597a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 598a8e1175bSopenharmony_ci derived->server_application_traffic_secret_N, 599a8e1175bSopenharmony_ci hash_len); 600a8e1175bSopenharmony_ci if (ret != 0) { 601a8e1175bSopenharmony_ci return ret; 602a8e1175bSopenharmony_ci } 603a8e1175bSopenharmony_ci 604a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 605a8e1175bSopenharmony_ci hash_alg, 606a8e1175bSopenharmony_ci application_secret, hash_len, 607a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master), 608a8e1175bSopenharmony_ci transcript, transcript_len, 609a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 610a8e1175bSopenharmony_ci derived->exporter_master_secret, 611a8e1175bSopenharmony_ci hash_len); 612a8e1175bSopenharmony_ci if (ret != 0) { 613a8e1175bSopenharmony_ci return ret; 614a8e1175bSopenharmony_ci } 615a8e1175bSopenharmony_ci 616a8e1175bSopenharmony_ci return 0; 617a8e1175bSopenharmony_ci} 618a8e1175bSopenharmony_ci 619a8e1175bSopenharmony_ci/* Generate resumption_master_secret for use with the ticket exchange. 620a8e1175bSopenharmony_ci * 621a8e1175bSopenharmony_ci * This is not integrated with mbedtls_ssl_tls13_derive_application_secrets() 622a8e1175bSopenharmony_ci * because it uses the transcript hash up to and including ClientFinished. */ 623a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_derive_resumption_master_secret( 624a8e1175bSopenharmony_ci psa_algorithm_t hash_alg, 625a8e1175bSopenharmony_ci unsigned char const *application_secret, 626a8e1175bSopenharmony_ci unsigned char const *transcript, size_t transcript_len, 627a8e1175bSopenharmony_ci mbedtls_ssl_tls13_application_secrets *derived) 628a8e1175bSopenharmony_ci{ 629a8e1175bSopenharmony_ci int ret; 630a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 631a8e1175bSopenharmony_ci 632a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 633a8e1175bSopenharmony_ci * but add an assertion anyway. */ 634a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 635a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 636a8e1175bSopenharmony_ci } 637a8e1175bSopenharmony_ci 638a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 639a8e1175bSopenharmony_ci hash_alg, 640a8e1175bSopenharmony_ci application_secret, hash_len, 641a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master), 642a8e1175bSopenharmony_ci transcript, transcript_len, 643a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED, 644a8e1175bSopenharmony_ci derived->resumption_master_secret, 645a8e1175bSopenharmony_ci hash_len); 646a8e1175bSopenharmony_ci 647a8e1175bSopenharmony_ci if (ret != 0) { 648a8e1175bSopenharmony_ci return ret; 649a8e1175bSopenharmony_ci } 650a8e1175bSopenharmony_ci 651a8e1175bSopenharmony_ci return 0; 652a8e1175bSopenharmony_ci} 653a8e1175bSopenharmony_ci 654a8e1175bSopenharmony_ci/** 655a8e1175bSopenharmony_ci * \brief Transition into application stage of TLS 1.3 key schedule. 656a8e1175bSopenharmony_ci * 657a8e1175bSopenharmony_ci * The TLS 1.3 key schedule can be viewed as a simple state machine 658a8e1175bSopenharmony_ci * with states Initial -> Early -> Handshake -> Application, and 659a8e1175bSopenharmony_ci * this function represents the Handshake -> Application transition. 660a8e1175bSopenharmony_ci * 661a8e1175bSopenharmony_ci * In the handshake stage, ssl_tls13_generate_application_keys() 662a8e1175bSopenharmony_ci * can be used to derive the handshake traffic keys. 663a8e1175bSopenharmony_ci * 664a8e1175bSopenharmony_ci * \param ssl The SSL context to operate on. This must be in key schedule 665a8e1175bSopenharmony_ci * stage \c Handshake. 666a8e1175bSopenharmony_ci * 667a8e1175bSopenharmony_ci * \returns \c 0 on success. 668a8e1175bSopenharmony_ci * \returns A negative error code on failure. 669a8e1175bSopenharmony_ci */ 670a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 671a8e1175bSopenharmony_cistatic int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl) 672a8e1175bSopenharmony_ci{ 673a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 674a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 675a8e1175bSopenharmony_ci psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type( 676a8e1175bSopenharmony_ci (mbedtls_md_type_t) handshake->ciphersuite_info->mac); 677a8e1175bSopenharmony_ci 678a8e1175bSopenharmony_ci /* 679a8e1175bSopenharmony_ci * Compute MasterSecret 680a8e1175bSopenharmony_ci */ 681a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_evolve_secret( 682a8e1175bSopenharmony_ci hash_alg, 683a8e1175bSopenharmony_ci handshake->tls13_master_secrets.handshake, 684a8e1175bSopenharmony_ci NULL, 0, 685a8e1175bSopenharmony_ci handshake->tls13_master_secrets.app); 686a8e1175bSopenharmony_ci if (ret != 0) { 687a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); 688a8e1175bSopenharmony_ci return ret; 689a8e1175bSopenharmony_ci } 690a8e1175bSopenharmony_ci 691a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF( 692a8e1175bSopenharmony_ci 4, "Master secret", 693a8e1175bSopenharmony_ci handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg)); 694a8e1175bSopenharmony_ci 695a8e1175bSopenharmony_ci return 0; 696a8e1175bSopenharmony_ci} 697a8e1175bSopenharmony_ci 698a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 699a8e1175bSopenharmony_cistatic int ssl_tls13_calc_finished_core(psa_algorithm_t hash_alg, 700a8e1175bSopenharmony_ci unsigned char const *base_key, 701a8e1175bSopenharmony_ci unsigned char const *transcript, 702a8e1175bSopenharmony_ci unsigned char *dst, 703a8e1175bSopenharmony_ci size_t *dst_len) 704a8e1175bSopenharmony_ci{ 705a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; 706a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 707a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 708a8e1175bSopenharmony_ci size_t hash_len = PSA_HASH_LENGTH(hash_alg); 709a8e1175bSopenharmony_ci unsigned char finished_key[PSA_MAC_MAX_SIZE]; 710a8e1175bSopenharmony_ci int ret; 711a8e1175bSopenharmony_ci psa_algorithm_t alg; 712a8e1175bSopenharmony_ci 713a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 714a8e1175bSopenharmony_ci * but add an assertion anyway. */ 715a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 716a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 717a8e1175bSopenharmony_ci } 718a8e1175bSopenharmony_ci 719a8e1175bSopenharmony_ci /* TLS 1.3 Finished message 720a8e1175bSopenharmony_ci * 721a8e1175bSopenharmony_ci * struct { 722a8e1175bSopenharmony_ci * opaque verify_data[Hash.length]; 723a8e1175bSopenharmony_ci * } Finished; 724a8e1175bSopenharmony_ci * 725a8e1175bSopenharmony_ci * verify_data = 726a8e1175bSopenharmony_ci * HMAC( finished_key, 727a8e1175bSopenharmony_ci * Hash( Handshake Context + 728a8e1175bSopenharmony_ci * Certificate* + 729a8e1175bSopenharmony_ci * CertificateVerify* ) 730a8e1175bSopenharmony_ci * ) 731a8e1175bSopenharmony_ci * 732a8e1175bSopenharmony_ci * finished_key = 733a8e1175bSopenharmony_ci * HKDF-Expand-Label( BaseKey, "finished", "", Hash.length ) 734a8e1175bSopenharmony_ci */ 735a8e1175bSopenharmony_ci 736a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_hkdf_expand_label( 737a8e1175bSopenharmony_ci hash_alg, base_key, hash_len, 738a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(finished), 739a8e1175bSopenharmony_ci NULL, 0, 740a8e1175bSopenharmony_ci finished_key, hash_len); 741a8e1175bSopenharmony_ci if (ret != 0) { 742a8e1175bSopenharmony_ci goto exit; 743a8e1175bSopenharmony_ci } 744a8e1175bSopenharmony_ci 745a8e1175bSopenharmony_ci alg = PSA_ALG_HMAC(hash_alg); 746a8e1175bSopenharmony_ci psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE); 747a8e1175bSopenharmony_ci psa_set_key_algorithm(&attributes, alg); 748a8e1175bSopenharmony_ci psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC); 749a8e1175bSopenharmony_ci 750a8e1175bSopenharmony_ci status = psa_import_key(&attributes, finished_key, hash_len, &key); 751a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 752a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 753a8e1175bSopenharmony_ci goto exit; 754a8e1175bSopenharmony_ci } 755a8e1175bSopenharmony_ci 756a8e1175bSopenharmony_ci status = psa_mac_compute(key, alg, transcript, hash_len, 757a8e1175bSopenharmony_ci dst, hash_len, dst_len); 758a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 759a8e1175bSopenharmony_ci 760a8e1175bSopenharmony_ciexit: 761a8e1175bSopenharmony_ci 762a8e1175bSopenharmony_ci status = psa_destroy_key(key); 763a8e1175bSopenharmony_ci if (ret == 0) { 764a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 765a8e1175bSopenharmony_ci } 766a8e1175bSopenharmony_ci 767a8e1175bSopenharmony_ci mbedtls_platform_zeroize(finished_key, sizeof(finished_key)); 768a8e1175bSopenharmony_ci 769a8e1175bSopenharmony_ci return ret; 770a8e1175bSopenharmony_ci} 771a8e1175bSopenharmony_ci 772a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl, 773a8e1175bSopenharmony_ci unsigned char *dst, 774a8e1175bSopenharmony_ci size_t dst_len, 775a8e1175bSopenharmony_ci size_t *actual_len, 776a8e1175bSopenharmony_ci int from) 777a8e1175bSopenharmony_ci{ 778a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 779a8e1175bSopenharmony_ci 780a8e1175bSopenharmony_ci unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; 781a8e1175bSopenharmony_ci size_t transcript_len; 782a8e1175bSopenharmony_ci 783a8e1175bSopenharmony_ci unsigned char *base_key = NULL; 784a8e1175bSopenharmony_ci size_t base_key_len = 0; 785a8e1175bSopenharmony_ci mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = 786a8e1175bSopenharmony_ci &ssl->handshake->tls13_hs_secrets; 787a8e1175bSopenharmony_ci 788a8e1175bSopenharmony_ci mbedtls_md_type_t const md_type = (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac; 789a8e1175bSopenharmony_ci 790a8e1175bSopenharmony_ci psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type( 791a8e1175bSopenharmony_ci (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac); 792a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 793a8e1175bSopenharmony_ci 794a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_tls13_calculate_verify_data")); 795a8e1175bSopenharmony_ci 796a8e1175bSopenharmony_ci if (from == MBEDTLS_SSL_IS_CLIENT) { 797a8e1175bSopenharmony_ci base_key = tls13_hs_secrets->client_handshake_traffic_secret; 798a8e1175bSopenharmony_ci base_key_len = sizeof(tls13_hs_secrets->client_handshake_traffic_secret); 799a8e1175bSopenharmony_ci } else { 800a8e1175bSopenharmony_ci base_key = tls13_hs_secrets->server_handshake_traffic_secret; 801a8e1175bSopenharmony_ci base_key_len = sizeof(tls13_hs_secrets->server_handshake_traffic_secret); 802a8e1175bSopenharmony_ci } 803a8e1175bSopenharmony_ci 804a8e1175bSopenharmony_ci if (dst_len < hash_len) { 805a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 806a8e1175bSopenharmony_ci goto exit; 807a8e1175bSopenharmony_ci } 808a8e1175bSopenharmony_ci 809a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, 810a8e1175bSopenharmony_ci transcript, sizeof(transcript), 811a8e1175bSopenharmony_ci &transcript_len); 812a8e1175bSopenharmony_ci if (ret != 0) { 813a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret); 814a8e1175bSopenharmony_ci goto exit; 815a8e1175bSopenharmony_ci } 816a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "handshake hash", transcript, transcript_len); 817a8e1175bSopenharmony_ci 818a8e1175bSopenharmony_ci ret = ssl_tls13_calc_finished_core(hash_alg, base_key, 819a8e1175bSopenharmony_ci transcript, dst, actual_len); 820a8e1175bSopenharmony_ci if (ret != 0) { 821a8e1175bSopenharmony_ci goto exit; 822a8e1175bSopenharmony_ci } 823a8e1175bSopenharmony_ci 824a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "verify_data for finished message", dst, hash_len); 825a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_tls13_calculate_verify_data")); 826a8e1175bSopenharmony_ci 827a8e1175bSopenharmony_ciexit: 828a8e1175bSopenharmony_ci /* Erase handshake secrets */ 829a8e1175bSopenharmony_ci mbedtls_platform_zeroize(base_key, base_key_len); 830a8e1175bSopenharmony_ci mbedtls_platform_zeroize(transcript, sizeof(transcript)); 831a8e1175bSopenharmony_ci return ret; 832a8e1175bSopenharmony_ci} 833a8e1175bSopenharmony_ci 834a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl, 835a8e1175bSopenharmony_ci const psa_algorithm_t hash_alg, 836a8e1175bSopenharmony_ci unsigned char const *psk, size_t psk_len, 837a8e1175bSopenharmony_ci int psk_type, 838a8e1175bSopenharmony_ci unsigned char const *transcript, 839a8e1175bSopenharmony_ci unsigned char *result) 840a8e1175bSopenharmony_ci{ 841a8e1175bSopenharmony_ci int ret = 0; 842a8e1175bSopenharmony_ci unsigned char binder_key[PSA_MAC_MAX_SIZE]; 843a8e1175bSopenharmony_ci unsigned char early_secret[PSA_MAC_MAX_SIZE]; 844a8e1175bSopenharmony_ci size_t const hash_len = PSA_HASH_LENGTH(hash_alg); 845a8e1175bSopenharmony_ci size_t actual_len; 846a8e1175bSopenharmony_ci 847a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEBUG_C) 848a8e1175bSopenharmony_ci ssl = NULL; /* make sure we don't use it except for debug */ 849a8e1175bSopenharmony_ci ((void) ssl); 850a8e1175bSopenharmony_ci#endif 851a8e1175bSopenharmony_ci 852a8e1175bSopenharmony_ci /* We should never call this function with an unknown hash, 853a8e1175bSopenharmony_ci * but add an assertion anyway. */ 854a8e1175bSopenharmony_ci if (!PSA_ALG_IS_HASH(hash_alg)) { 855a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 856a8e1175bSopenharmony_ci } 857a8e1175bSopenharmony_ci 858a8e1175bSopenharmony_ci /* 859a8e1175bSopenharmony_ci * 0 860a8e1175bSopenharmony_ci * | 861a8e1175bSopenharmony_ci * v 862a8e1175bSopenharmony_ci * PSK -> HKDF-Extract = Early Secret 863a8e1175bSopenharmony_ci * | 864a8e1175bSopenharmony_ci * +-----> Derive-Secret(., "ext binder" | "res binder", "") 865a8e1175bSopenharmony_ci * | = binder_key 866a8e1175bSopenharmony_ci * v 867a8e1175bSopenharmony_ci */ 868a8e1175bSopenharmony_ci 869a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, 870a8e1175bSopenharmony_ci NULL, /* Old secret */ 871a8e1175bSopenharmony_ci psk, psk_len, /* Input */ 872a8e1175bSopenharmony_ci early_secret); 873a8e1175bSopenharmony_ci if (ret != 0) { 874a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); 875a8e1175bSopenharmony_ci goto exit; 876a8e1175bSopenharmony_ci } 877a8e1175bSopenharmony_ci 878a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_create_psk_binder", 879a8e1175bSopenharmony_ci early_secret, hash_len); 880a8e1175bSopenharmony_ci 881a8e1175bSopenharmony_ci if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) { 882a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 883a8e1175bSopenharmony_ci hash_alg, 884a8e1175bSopenharmony_ci early_secret, hash_len, 885a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder), 886a8e1175bSopenharmony_ci NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, 887a8e1175bSopenharmony_ci binder_key, hash_len); 888a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'res binder'")); 889a8e1175bSopenharmony_ci } else { 890a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_secret( 891a8e1175bSopenharmony_ci hash_alg, 892a8e1175bSopenharmony_ci early_secret, hash_len, 893a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder), 894a8e1175bSopenharmony_ci NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, 895a8e1175bSopenharmony_ci binder_key, hash_len); 896a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'ext binder'")); 897a8e1175bSopenharmony_ci } 898a8e1175bSopenharmony_ci 899a8e1175bSopenharmony_ci if (ret != 0) { 900a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_secret", ret); 901a8e1175bSopenharmony_ci goto exit; 902a8e1175bSopenharmony_ci } 903a8e1175bSopenharmony_ci 904a8e1175bSopenharmony_ci /* 905a8e1175bSopenharmony_ci * The binding_value is computed in the same way as the Finished message 906a8e1175bSopenharmony_ci * but with the BaseKey being the binder_key. 907a8e1175bSopenharmony_ci */ 908a8e1175bSopenharmony_ci 909a8e1175bSopenharmony_ci ret = ssl_tls13_calc_finished_core(hash_alg, binder_key, transcript, 910a8e1175bSopenharmony_ci result, &actual_len); 911a8e1175bSopenharmony_ci if (ret != 0) { 912a8e1175bSopenharmony_ci goto exit; 913a8e1175bSopenharmony_ci } 914a8e1175bSopenharmony_ci 915a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "psk binder", result, actual_len); 916a8e1175bSopenharmony_ci 917a8e1175bSopenharmony_ciexit: 918a8e1175bSopenharmony_ci 919a8e1175bSopenharmony_ci mbedtls_platform_zeroize(early_secret, sizeof(early_secret)); 920a8e1175bSopenharmony_ci mbedtls_platform_zeroize(binder_key, sizeof(binder_key)); 921a8e1175bSopenharmony_ci return ret; 922a8e1175bSopenharmony_ci} 923a8e1175bSopenharmony_ci 924a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_populate_transform( 925a8e1175bSopenharmony_ci mbedtls_ssl_transform *transform, 926a8e1175bSopenharmony_ci int endpoint, int ciphersuite, 927a8e1175bSopenharmony_ci mbedtls_ssl_key_set const *traffic_keys, 928a8e1175bSopenharmony_ci mbedtls_ssl_context *ssl /* DEBUG ONLY */) 929a8e1175bSopenharmony_ci{ 930a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 931a8e1175bSopenharmony_ci int ret; 932a8e1175bSopenharmony_ci mbedtls_cipher_info_t const *cipher_info; 933a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 934a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info; 935a8e1175bSopenharmony_ci unsigned char const *key_enc; 936a8e1175bSopenharmony_ci unsigned char const *iv_enc; 937a8e1175bSopenharmony_ci unsigned char const *key_dec; 938a8e1175bSopenharmony_ci unsigned char const *iv_dec; 939a8e1175bSopenharmony_ci 940a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 941a8e1175bSopenharmony_ci psa_key_type_t key_type; 942a8e1175bSopenharmony_ci psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; 943a8e1175bSopenharmony_ci psa_algorithm_t alg; 944a8e1175bSopenharmony_ci size_t key_bits; 945a8e1175bSopenharmony_ci psa_status_t status = PSA_SUCCESS; 946a8e1175bSopenharmony_ci#endif 947a8e1175bSopenharmony_ci 948a8e1175bSopenharmony_ci#if !defined(MBEDTLS_DEBUG_C) 949a8e1175bSopenharmony_ci ssl = NULL; /* make sure we don't use it except for those cases */ 950a8e1175bSopenharmony_ci (void) ssl; 951a8e1175bSopenharmony_ci#endif 952a8e1175bSopenharmony_ci 953a8e1175bSopenharmony_ci ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite); 954a8e1175bSopenharmony_ci if (ciphersuite_info == NULL) { 955a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found", 956a8e1175bSopenharmony_ci ciphersuite)); 957a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 958a8e1175bSopenharmony_ci } 959a8e1175bSopenharmony_ci 960a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 961a8e1175bSopenharmony_ci cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher); 962a8e1175bSopenharmony_ci if (cipher_info == NULL) { 963a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found", 964a8e1175bSopenharmony_ci ciphersuite_info->cipher)); 965a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 966a8e1175bSopenharmony_ci } 967a8e1175bSopenharmony_ci 968a8e1175bSopenharmony_ci /* 969a8e1175bSopenharmony_ci * Setup cipher contexts in target transform 970a8e1175bSopenharmony_ci */ 971a8e1175bSopenharmony_ci if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc, 972a8e1175bSopenharmony_ci cipher_info)) != 0) { 973a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); 974a8e1175bSopenharmony_ci return ret; 975a8e1175bSopenharmony_ci } 976a8e1175bSopenharmony_ci 977a8e1175bSopenharmony_ci if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec, 978a8e1175bSopenharmony_ci cipher_info)) != 0) { 979a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret); 980a8e1175bSopenharmony_ci return ret; 981a8e1175bSopenharmony_ci } 982a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 983a8e1175bSopenharmony_ci 984a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C) 985a8e1175bSopenharmony_ci if (endpoint == MBEDTLS_SSL_IS_SERVER) { 986a8e1175bSopenharmony_ci key_enc = traffic_keys->server_write_key; 987a8e1175bSopenharmony_ci key_dec = traffic_keys->client_write_key; 988a8e1175bSopenharmony_ci iv_enc = traffic_keys->server_write_iv; 989a8e1175bSopenharmony_ci iv_dec = traffic_keys->client_write_iv; 990a8e1175bSopenharmony_ci } else 991a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C */ 992a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CLI_C) 993a8e1175bSopenharmony_ci if (endpoint == MBEDTLS_SSL_IS_CLIENT) { 994a8e1175bSopenharmony_ci key_enc = traffic_keys->client_write_key; 995a8e1175bSopenharmony_ci key_dec = traffic_keys->server_write_key; 996a8e1175bSopenharmony_ci iv_enc = traffic_keys->client_write_iv; 997a8e1175bSopenharmony_ci iv_dec = traffic_keys->server_write_iv; 998a8e1175bSopenharmony_ci } else 999a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CLI_C */ 1000a8e1175bSopenharmony_ci { 1001a8e1175bSopenharmony_ci /* should not happen */ 1002a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1003a8e1175bSopenharmony_ci } 1004a8e1175bSopenharmony_ci 1005a8e1175bSopenharmony_ci memcpy(transform->iv_enc, iv_enc, traffic_keys->iv_len); 1006a8e1175bSopenharmony_ci memcpy(transform->iv_dec, iv_dec, traffic_keys->iv_len); 1007a8e1175bSopenharmony_ci 1008a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 1009a8e1175bSopenharmony_ci if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc, 1010a8e1175bSopenharmony_ci key_enc, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), 1011a8e1175bSopenharmony_ci MBEDTLS_ENCRYPT)) != 0) { 1012a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); 1013a8e1175bSopenharmony_ci return ret; 1014a8e1175bSopenharmony_ci } 1015a8e1175bSopenharmony_ci 1016a8e1175bSopenharmony_ci if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec, 1017a8e1175bSopenharmony_ci key_dec, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info), 1018a8e1175bSopenharmony_ci MBEDTLS_DECRYPT)) != 0) { 1019a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret); 1020a8e1175bSopenharmony_ci return ret; 1021a8e1175bSopenharmony_ci } 1022a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 1023a8e1175bSopenharmony_ci 1024a8e1175bSopenharmony_ci /* 1025a8e1175bSopenharmony_ci * Setup other fields in SSL transform 1026a8e1175bSopenharmony_ci */ 1027a8e1175bSopenharmony_ci 1028a8e1175bSopenharmony_ci if ((ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) != 0) { 1029a8e1175bSopenharmony_ci transform->taglen = 8; 1030a8e1175bSopenharmony_ci } else { 1031a8e1175bSopenharmony_ci transform->taglen = 16; 1032a8e1175bSopenharmony_ci } 1033a8e1175bSopenharmony_ci 1034a8e1175bSopenharmony_ci transform->ivlen = traffic_keys->iv_len; 1035a8e1175bSopenharmony_ci transform->maclen = 0; 1036a8e1175bSopenharmony_ci transform->fixed_ivlen = transform->ivlen; 1037a8e1175bSopenharmony_ci transform->tls_version = MBEDTLS_SSL_VERSION_TLS1_3; 1038a8e1175bSopenharmony_ci 1039a8e1175bSopenharmony_ci /* We add the true record content type (1 Byte) to the plaintext and 1040a8e1175bSopenharmony_ci * then pad to the configured granularity. The minimum length of the 1041a8e1175bSopenharmony_ci * type-extended and padded plaintext is therefore the padding 1042a8e1175bSopenharmony_ci * granularity. */ 1043a8e1175bSopenharmony_ci transform->minlen = 1044a8e1175bSopenharmony_ci transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY; 1045a8e1175bSopenharmony_ci 1046a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1047a8e1175bSopenharmony_ci /* 1048a8e1175bSopenharmony_ci * Setup psa keys and alg 1049a8e1175bSopenharmony_ci */ 1050a8e1175bSopenharmony_ci if ((status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, 1051a8e1175bSopenharmony_ci transform->taglen, 1052a8e1175bSopenharmony_ci &alg, 1053a8e1175bSopenharmony_ci &key_type, 1054a8e1175bSopenharmony_ci &key_bits)) != PSA_SUCCESS) { 1055a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET( 1056a8e1175bSopenharmony_ci 1, "mbedtls_ssl_cipher_to_psa", PSA_TO_MBEDTLS_ERR(status)); 1057a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1058a8e1175bSopenharmony_ci } 1059a8e1175bSopenharmony_ci 1060a8e1175bSopenharmony_ci transform->psa_alg = alg; 1061a8e1175bSopenharmony_ci 1062a8e1175bSopenharmony_ci if (alg != MBEDTLS_SSL_NULL_CIPHER) { 1063a8e1175bSopenharmony_ci psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT); 1064a8e1175bSopenharmony_ci psa_set_key_algorithm(&attributes, alg); 1065a8e1175bSopenharmony_ci psa_set_key_type(&attributes, key_type); 1066a8e1175bSopenharmony_ci 1067a8e1175bSopenharmony_ci if ((status = psa_import_key(&attributes, 1068a8e1175bSopenharmony_ci key_enc, 1069a8e1175bSopenharmony_ci PSA_BITS_TO_BYTES(key_bits), 1070a8e1175bSopenharmony_ci &transform->psa_key_enc)) != PSA_SUCCESS) { 1071a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET( 1072a8e1175bSopenharmony_ci 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status)); 1073a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1074a8e1175bSopenharmony_ci } 1075a8e1175bSopenharmony_ci 1076a8e1175bSopenharmony_ci psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); 1077a8e1175bSopenharmony_ci 1078a8e1175bSopenharmony_ci if ((status = psa_import_key(&attributes, 1079a8e1175bSopenharmony_ci key_dec, 1080a8e1175bSopenharmony_ci PSA_BITS_TO_BYTES(key_bits), 1081a8e1175bSopenharmony_ci &transform->psa_key_dec)) != PSA_SUCCESS) { 1082a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET( 1083a8e1175bSopenharmony_ci 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status)); 1084a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1085a8e1175bSopenharmony_ci } 1086a8e1175bSopenharmony_ci } 1087a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 1088a8e1175bSopenharmony_ci 1089a8e1175bSopenharmony_ci return 0; 1090a8e1175bSopenharmony_ci} 1091a8e1175bSopenharmony_ci 1092a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1093a8e1175bSopenharmony_cistatic int ssl_tls13_get_cipher_key_info( 1094a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info, 1095a8e1175bSopenharmony_ci size_t *key_len, size_t *iv_len) 1096a8e1175bSopenharmony_ci{ 1097a8e1175bSopenharmony_ci psa_key_type_t key_type; 1098a8e1175bSopenharmony_ci psa_algorithm_t alg; 1099a8e1175bSopenharmony_ci size_t taglen; 1100a8e1175bSopenharmony_ci size_t key_bits; 1101a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1102a8e1175bSopenharmony_ci 1103a8e1175bSopenharmony_ci if (ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) { 1104a8e1175bSopenharmony_ci taglen = 8; 1105a8e1175bSopenharmony_ci } else { 1106a8e1175bSopenharmony_ci taglen = 16; 1107a8e1175bSopenharmony_ci } 1108a8e1175bSopenharmony_ci 1109a8e1175bSopenharmony_ci status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, taglen, 1110a8e1175bSopenharmony_ci &alg, &key_type, &key_bits); 1111a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1112a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1113a8e1175bSopenharmony_ci } 1114a8e1175bSopenharmony_ci 1115a8e1175bSopenharmony_ci *key_len = PSA_BITS_TO_BYTES(key_bits); 1116a8e1175bSopenharmony_ci 1117a8e1175bSopenharmony_ci /* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */ 1118a8e1175bSopenharmony_ci *iv_len = 12; 1119a8e1175bSopenharmony_ci 1120a8e1175bSopenharmony_ci return 0; 1121a8e1175bSopenharmony_ci} 1122a8e1175bSopenharmony_ci 1123a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA) 1124a8e1175bSopenharmony_ci/* 1125a8e1175bSopenharmony_ci * ssl_tls13_generate_early_key() generates the key necessary for protecting 1126a8e1175bSopenharmony_ci * the early application data and handshake messages as described in section 7 1127a8e1175bSopenharmony_ci * of RFC 8446. 1128a8e1175bSopenharmony_ci * 1129a8e1175bSopenharmony_ci * NOTE: Only one key is generated, the key for the traffic from the client to 1130a8e1175bSopenharmony_ci * the server. The TLS 1.3 specification does not define a secret and thus 1131a8e1175bSopenharmony_ci * a key for server early traffic. 1132a8e1175bSopenharmony_ci */ 1133a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1134a8e1175bSopenharmony_cistatic int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl, 1135a8e1175bSopenharmony_ci mbedtls_ssl_key_set *traffic_keys) 1136a8e1175bSopenharmony_ci{ 1137a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1138a8e1175bSopenharmony_ci mbedtls_md_type_t md_type; 1139a8e1175bSopenharmony_ci psa_algorithm_t hash_alg; 1140a8e1175bSopenharmony_ci size_t hash_len; 1141a8e1175bSopenharmony_ci unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; 1142a8e1175bSopenharmony_ci size_t transcript_len; 1143a8e1175bSopenharmony_ci size_t key_len = 0; 1144a8e1175bSopenharmony_ci size_t iv_len = 0; 1145a8e1175bSopenharmony_ci mbedtls_ssl_tls13_early_secrets tls13_early_secrets; 1146a8e1175bSopenharmony_ci 1147a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1148a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 1149a8e1175bSopenharmony_ci handshake->ciphersuite_info; 1150a8e1175bSopenharmony_ci 1151a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key")); 1152a8e1175bSopenharmony_ci 1153a8e1175bSopenharmony_ci ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len); 1154a8e1175bSopenharmony_ci if (ret != 0) { 1155a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); 1156a8e1175bSopenharmony_ci goto cleanup; 1157a8e1175bSopenharmony_ci } 1158a8e1175bSopenharmony_ci 1159a8e1175bSopenharmony_ci md_type = (mbedtls_md_type_t) ciphersuite_info->mac; 1160a8e1175bSopenharmony_ci 1161a8e1175bSopenharmony_ci hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); 1162a8e1175bSopenharmony_ci hash_len = PSA_HASH_LENGTH(hash_alg); 1163a8e1175bSopenharmony_ci 1164a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, 1165a8e1175bSopenharmony_ci transcript, 1166a8e1175bSopenharmony_ci sizeof(transcript), 1167a8e1175bSopenharmony_ci &transcript_len); 1168a8e1175bSopenharmony_ci if (ret != 0) { 1169a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 1170a8e1175bSopenharmony_ci "mbedtls_ssl_get_handshake_transcript", 1171a8e1175bSopenharmony_ci ret); 1172a8e1175bSopenharmony_ci goto cleanup; 1173a8e1175bSopenharmony_ci } 1174a8e1175bSopenharmony_ci 1175a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_early_secrets( 1176a8e1175bSopenharmony_ci hash_alg, handshake->tls13_master_secrets.early, 1177a8e1175bSopenharmony_ci transcript, transcript_len, &tls13_early_secrets); 1178a8e1175bSopenharmony_ci if (ret != 0) { 1179a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET( 1180a8e1175bSopenharmony_ci 1, "mbedtls_ssl_tls13_derive_early_secrets", ret); 1181a8e1175bSopenharmony_ci goto cleanup; 1182a8e1175bSopenharmony_ci } 1183a8e1175bSopenharmony_ci 1184a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF( 1185a8e1175bSopenharmony_ci 4, "Client early traffic secret", 1186a8e1175bSopenharmony_ci tls13_early_secrets.client_early_traffic_secret, hash_len); 1187a8e1175bSopenharmony_ci 1188a8e1175bSopenharmony_ci /* 1189a8e1175bSopenharmony_ci * Export client handshake traffic secret 1190a8e1175bSopenharmony_ci */ 1191a8e1175bSopenharmony_ci if (ssl->f_export_keys != NULL) { 1192a8e1175bSopenharmony_ci ssl->f_export_keys( 1193a8e1175bSopenharmony_ci ssl->p_export_keys, 1194a8e1175bSopenharmony_ci MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET, 1195a8e1175bSopenharmony_ci tls13_early_secrets.client_early_traffic_secret, 1196a8e1175bSopenharmony_ci hash_len, 1197a8e1175bSopenharmony_ci handshake->randbytes, 1198a8e1175bSopenharmony_ci handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, 1199a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); 1200a8e1175bSopenharmony_ci } 1201a8e1175bSopenharmony_ci 1202a8e1175bSopenharmony_ci ret = ssl_tls13_make_traffic_key( 1203a8e1175bSopenharmony_ci hash_alg, 1204a8e1175bSopenharmony_ci tls13_early_secrets.client_early_traffic_secret, 1205a8e1175bSopenharmony_ci hash_len, traffic_keys->client_write_key, key_len, 1206a8e1175bSopenharmony_ci traffic_keys->client_write_iv, iv_len); 1207a8e1175bSopenharmony_ci if (ret != 0) { 1208a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_make_traffic_key", ret); 1209a8e1175bSopenharmony_ci goto cleanup; 1210a8e1175bSopenharmony_ci } 1211a8e1175bSopenharmony_ci traffic_keys->key_len = key_len; 1212a8e1175bSopenharmony_ci traffic_keys->iv_len = iv_len; 1213a8e1175bSopenharmony_ci 1214a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client early write_key", 1215a8e1175bSopenharmony_ci traffic_keys->client_write_key, 1216a8e1175bSopenharmony_ci traffic_keys->key_len); 1217a8e1175bSopenharmony_ci 1218a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client early write_iv", 1219a8e1175bSopenharmony_ci traffic_keys->client_write_iv, 1220a8e1175bSopenharmony_ci traffic_keys->iv_len); 1221a8e1175bSopenharmony_ci 1222a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_early_key")); 1223a8e1175bSopenharmony_ci 1224a8e1175bSopenharmony_cicleanup: 1225a8e1175bSopenharmony_ci /* Erase early secrets and transcript */ 1226a8e1175bSopenharmony_ci mbedtls_platform_zeroize( 1227a8e1175bSopenharmony_ci &tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets)); 1228a8e1175bSopenharmony_ci mbedtls_platform_zeroize(transcript, sizeof(transcript)); 1229a8e1175bSopenharmony_ci return ret; 1230a8e1175bSopenharmony_ci} 1231a8e1175bSopenharmony_ci 1232a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl) 1233a8e1175bSopenharmony_ci{ 1234a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1235a8e1175bSopenharmony_ci mbedtls_ssl_key_set traffic_keys; 1236a8e1175bSopenharmony_ci mbedtls_ssl_transform *transform_earlydata = NULL; 1237a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1238a8e1175bSopenharmony_ci 1239a8e1175bSopenharmony_ci /* Next evolution in key schedule: Establish early_data secret and 1240a8e1175bSopenharmony_ci * key material. */ 1241a8e1175bSopenharmony_ci ret = ssl_tls13_generate_early_key(ssl, &traffic_keys); 1242a8e1175bSopenharmony_ci if (ret != 0) { 1243a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_early_key", 1244a8e1175bSopenharmony_ci ret); 1245a8e1175bSopenharmony_ci goto cleanup; 1246a8e1175bSopenharmony_ci } 1247a8e1175bSopenharmony_ci 1248a8e1175bSopenharmony_ci transform_earlydata = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); 1249a8e1175bSopenharmony_ci if (transform_earlydata == NULL) { 1250a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 1251a8e1175bSopenharmony_ci goto cleanup; 1252a8e1175bSopenharmony_ci } 1253a8e1175bSopenharmony_ci 1254a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_populate_transform( 1255a8e1175bSopenharmony_ci transform_earlydata, 1256a8e1175bSopenharmony_ci ssl->conf->endpoint, 1257a8e1175bSopenharmony_ci handshake->ciphersuite_info->id, 1258a8e1175bSopenharmony_ci &traffic_keys, 1259a8e1175bSopenharmony_ci ssl); 1260a8e1175bSopenharmony_ci if (ret != 0) { 1261a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); 1262a8e1175bSopenharmony_ci goto cleanup; 1263a8e1175bSopenharmony_ci } 1264a8e1175bSopenharmony_ci handshake->transform_earlydata = transform_earlydata; 1265a8e1175bSopenharmony_ci 1266a8e1175bSopenharmony_cicleanup: 1267a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); 1268a8e1175bSopenharmony_ci if (ret != 0) { 1269a8e1175bSopenharmony_ci mbedtls_free(transform_earlydata); 1270a8e1175bSopenharmony_ci } 1271a8e1175bSopenharmony_ci 1272a8e1175bSopenharmony_ci return ret; 1273a8e1175bSopenharmony_ci} 1274a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */ 1275a8e1175bSopenharmony_ci 1276a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl) 1277a8e1175bSopenharmony_ci{ 1278a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1279a8e1175bSopenharmony_ci psa_algorithm_t hash_alg; 1280a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1281a8e1175bSopenharmony_ci unsigned char *psk = NULL; 1282a8e1175bSopenharmony_ci size_t psk_len = 0; 1283a8e1175bSopenharmony_ci 1284a8e1175bSopenharmony_ci if (handshake->ciphersuite_info == NULL) { 1285a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("cipher suite info not found")); 1286a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1287a8e1175bSopenharmony_ci } 1288a8e1175bSopenharmony_ci 1289a8e1175bSopenharmony_ci hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac); 1290a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) 1291a8e1175bSopenharmony_ci if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { 1292a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len); 1293a8e1175bSopenharmony_ci if (ret != 0) { 1294a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_export_handshake_psk", 1295a8e1175bSopenharmony_ci ret); 1296a8e1175bSopenharmony_ci return ret; 1297a8e1175bSopenharmony_ci } 1298a8e1175bSopenharmony_ci } 1299a8e1175bSopenharmony_ci#endif 1300a8e1175bSopenharmony_ci 1301a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, NULL, psk, psk_len, 1302a8e1175bSopenharmony_ci handshake->tls13_master_secrets.early); 1303a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ 1304a8e1175bSopenharmony_ci defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) 1305a8e1175bSopenharmony_ci mbedtls_free((void *) psk); 1306a8e1175bSopenharmony_ci#endif 1307a8e1175bSopenharmony_ci if (ret != 0) { 1308a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); 1309a8e1175bSopenharmony_ci return ret; 1310a8e1175bSopenharmony_ci } 1311a8e1175bSopenharmony_ci 1312a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_key_schedule_stage_early", 1313a8e1175bSopenharmony_ci handshake->tls13_master_secrets.early, 1314a8e1175bSopenharmony_ci PSA_HASH_LENGTH(hash_alg)); 1315a8e1175bSopenharmony_ci return 0; 1316a8e1175bSopenharmony_ci} 1317a8e1175bSopenharmony_ci 1318a8e1175bSopenharmony_ci/** 1319a8e1175bSopenharmony_ci * \brief Compute TLS 1.3 handshake traffic keys. 1320a8e1175bSopenharmony_ci * 1321a8e1175bSopenharmony_ci * ssl_tls13_generate_handshake_keys() generates keys necessary for 1322a8e1175bSopenharmony_ci * protecting the handshake messages, as described in Section 7 of 1323a8e1175bSopenharmony_ci * RFC 8446. 1324a8e1175bSopenharmony_ci * 1325a8e1175bSopenharmony_ci * \param ssl The SSL context to operate on. This must be in 1326a8e1175bSopenharmony_ci * key schedule stage \c Handshake, see 1327a8e1175bSopenharmony_ci * ssl_tls13_key_schedule_stage_handshake(). 1328a8e1175bSopenharmony_ci * \param traffic_keys The address at which to store the handshake traffic 1329a8e1175bSopenharmony_ci * keys. This must be writable but may be uninitialized. 1330a8e1175bSopenharmony_ci * 1331a8e1175bSopenharmony_ci * \returns \c 0 on success. 1332a8e1175bSopenharmony_ci * \returns A negative error code on failure. 1333a8e1175bSopenharmony_ci */ 1334a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1335a8e1175bSopenharmony_cistatic int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl, 1336a8e1175bSopenharmony_ci mbedtls_ssl_key_set *traffic_keys) 1337a8e1175bSopenharmony_ci{ 1338a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1339a8e1175bSopenharmony_ci mbedtls_md_type_t md_type; 1340a8e1175bSopenharmony_ci psa_algorithm_t hash_alg; 1341a8e1175bSopenharmony_ci size_t hash_len; 1342a8e1175bSopenharmony_ci unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; 1343a8e1175bSopenharmony_ci size_t transcript_len; 1344a8e1175bSopenharmony_ci size_t key_len = 0; 1345a8e1175bSopenharmony_ci size_t iv_len = 0; 1346a8e1175bSopenharmony_ci 1347a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1348a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 1349a8e1175bSopenharmony_ci handshake->ciphersuite_info; 1350a8e1175bSopenharmony_ci mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = 1351a8e1175bSopenharmony_ci &handshake->tls13_hs_secrets; 1352a8e1175bSopenharmony_ci 1353a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys")); 1354a8e1175bSopenharmony_ci 1355a8e1175bSopenharmony_ci ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len); 1356a8e1175bSopenharmony_ci if (ret != 0) { 1357a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); 1358a8e1175bSopenharmony_ci return ret; 1359a8e1175bSopenharmony_ci } 1360a8e1175bSopenharmony_ci 1361a8e1175bSopenharmony_ci md_type = (mbedtls_md_type_t) ciphersuite_info->mac; 1362a8e1175bSopenharmony_ci 1363a8e1175bSopenharmony_ci hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac); 1364a8e1175bSopenharmony_ci hash_len = PSA_HASH_LENGTH(hash_alg); 1365a8e1175bSopenharmony_ci 1366a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, 1367a8e1175bSopenharmony_ci transcript, 1368a8e1175bSopenharmony_ci sizeof(transcript), 1369a8e1175bSopenharmony_ci &transcript_len); 1370a8e1175bSopenharmony_ci if (ret != 0) { 1371a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 1372a8e1175bSopenharmony_ci "mbedtls_ssl_get_handshake_transcript", 1373a8e1175bSopenharmony_ci ret); 1374a8e1175bSopenharmony_ci return ret; 1375a8e1175bSopenharmony_ci } 1376a8e1175bSopenharmony_ci 1377a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_handshake_secrets( 1378a8e1175bSopenharmony_ci hash_alg, handshake->tls13_master_secrets.handshake, 1379a8e1175bSopenharmony_ci transcript, transcript_len, tls13_hs_secrets); 1380a8e1175bSopenharmony_ci if (ret != 0) { 1381a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_handshake_secrets", 1382a8e1175bSopenharmony_ci ret); 1383a8e1175bSopenharmony_ci return ret; 1384a8e1175bSopenharmony_ci } 1385a8e1175bSopenharmony_ci 1386a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "Client handshake traffic secret", 1387a8e1175bSopenharmony_ci tls13_hs_secrets->client_handshake_traffic_secret, 1388a8e1175bSopenharmony_ci hash_len); 1389a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "Server handshake traffic secret", 1390a8e1175bSopenharmony_ci tls13_hs_secrets->server_handshake_traffic_secret, 1391a8e1175bSopenharmony_ci hash_len); 1392a8e1175bSopenharmony_ci 1393a8e1175bSopenharmony_ci /* 1394a8e1175bSopenharmony_ci * Export client handshake traffic secret 1395a8e1175bSopenharmony_ci */ 1396a8e1175bSopenharmony_ci if (ssl->f_export_keys != NULL) { 1397a8e1175bSopenharmony_ci ssl->f_export_keys( 1398a8e1175bSopenharmony_ci ssl->p_export_keys, 1399a8e1175bSopenharmony_ci MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET, 1400a8e1175bSopenharmony_ci tls13_hs_secrets->client_handshake_traffic_secret, 1401a8e1175bSopenharmony_ci hash_len, 1402a8e1175bSopenharmony_ci handshake->randbytes, 1403a8e1175bSopenharmony_ci handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, 1404a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); 1405a8e1175bSopenharmony_ci 1406a8e1175bSopenharmony_ci ssl->f_export_keys( 1407a8e1175bSopenharmony_ci ssl->p_export_keys, 1408a8e1175bSopenharmony_ci MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET, 1409a8e1175bSopenharmony_ci tls13_hs_secrets->server_handshake_traffic_secret, 1410a8e1175bSopenharmony_ci hash_len, 1411a8e1175bSopenharmony_ci handshake->randbytes, 1412a8e1175bSopenharmony_ci handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, 1413a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */); 1414a8e1175bSopenharmony_ci } 1415a8e1175bSopenharmony_ci 1416a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_make_traffic_keys( 1417a8e1175bSopenharmony_ci hash_alg, 1418a8e1175bSopenharmony_ci tls13_hs_secrets->client_handshake_traffic_secret, 1419a8e1175bSopenharmony_ci tls13_hs_secrets->server_handshake_traffic_secret, 1420a8e1175bSopenharmony_ci hash_len, key_len, iv_len, traffic_keys); 1421a8e1175bSopenharmony_ci if (ret != 0) { 1422a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret); 1423a8e1175bSopenharmony_ci goto exit; 1424a8e1175bSopenharmony_ci } 1425a8e1175bSopenharmony_ci 1426a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_key", 1427a8e1175bSopenharmony_ci traffic_keys->client_write_key, 1428a8e1175bSopenharmony_ci traffic_keys->key_len); 1429a8e1175bSopenharmony_ci 1430a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_key", 1431a8e1175bSopenharmony_ci traffic_keys->server_write_key, 1432a8e1175bSopenharmony_ci traffic_keys->key_len); 1433a8e1175bSopenharmony_ci 1434a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_iv", 1435a8e1175bSopenharmony_ci traffic_keys->client_write_iv, 1436a8e1175bSopenharmony_ci traffic_keys->iv_len); 1437a8e1175bSopenharmony_ci 1438a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_iv", 1439a8e1175bSopenharmony_ci traffic_keys->server_write_iv, 1440a8e1175bSopenharmony_ci traffic_keys->iv_len); 1441a8e1175bSopenharmony_ci 1442a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_handshake_keys")); 1443a8e1175bSopenharmony_ci 1444a8e1175bSopenharmony_ciexit: 1445a8e1175bSopenharmony_ci 1446a8e1175bSopenharmony_ci return ret; 1447a8e1175bSopenharmony_ci} 1448a8e1175bSopenharmony_ci 1449a8e1175bSopenharmony_ci/** 1450a8e1175bSopenharmony_ci * \brief Transition into handshake stage of TLS 1.3 key schedule. 1451a8e1175bSopenharmony_ci * 1452a8e1175bSopenharmony_ci * The TLS 1.3 key schedule can be viewed as a simple state machine 1453a8e1175bSopenharmony_ci * with states Initial -> Early -> Handshake -> Application, and 1454a8e1175bSopenharmony_ci * this function represents the Early -> Handshake transition. 1455a8e1175bSopenharmony_ci * 1456a8e1175bSopenharmony_ci * In the handshake stage, ssl_tls13_generate_handshake_keys() 1457a8e1175bSopenharmony_ci * can be used to derive the handshake traffic keys. 1458a8e1175bSopenharmony_ci * 1459a8e1175bSopenharmony_ci * \param ssl The SSL context to operate on. This must be in key schedule 1460a8e1175bSopenharmony_ci * stage \c Early. 1461a8e1175bSopenharmony_ci * 1462a8e1175bSopenharmony_ci * \returns \c 0 on success. 1463a8e1175bSopenharmony_ci * \returns A negative error code on failure. 1464a8e1175bSopenharmony_ci */ 1465a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1466a8e1175bSopenharmony_cistatic int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl) 1467a8e1175bSopenharmony_ci{ 1468a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1469a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1470a8e1175bSopenharmony_ci psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type( 1471a8e1175bSopenharmony_ci (mbedtls_md_type_t) handshake->ciphersuite_info->mac); 1472a8e1175bSopenharmony_ci unsigned char *shared_secret = NULL; 1473a8e1175bSopenharmony_ci size_t shared_secret_len = 0; 1474a8e1175bSopenharmony_ci 1475a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) 1476a8e1175bSopenharmony_ci /* 1477a8e1175bSopenharmony_ci * Compute ECDHE secret used to compute the handshake secret from which 1478a8e1175bSopenharmony_ci * client_handshake_traffic_secret and server_handshake_traffic_secret 1479a8e1175bSopenharmony_ci * are derived in the handshake secret derivation stage. 1480a8e1175bSopenharmony_ci */ 1481a8e1175bSopenharmony_ci if (mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) { 1482a8e1175bSopenharmony_ci if (mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) || 1483a8e1175bSopenharmony_ci mbedtls_ssl_tls13_named_group_is_ffdh(handshake->offered_group_id)) { 1484a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) 1485a8e1175bSopenharmony_ci psa_algorithm_t alg = 1486a8e1175bSopenharmony_ci mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) ? 1487a8e1175bSopenharmony_ci PSA_ALG_ECDH : PSA_ALG_FFDH; 1488a8e1175bSopenharmony_ci 1489a8e1175bSopenharmony_ci /* Compute ECDH shared secret. */ 1490a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_GENERIC_ERROR; 1491a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; 1492a8e1175bSopenharmony_ci 1493a8e1175bSopenharmony_ci status = psa_get_key_attributes(handshake->xxdh_psa_privkey, 1494a8e1175bSopenharmony_ci &key_attributes); 1495a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1496a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 1497a8e1175bSopenharmony_ci } 1498a8e1175bSopenharmony_ci 1499a8e1175bSopenharmony_ci shared_secret_len = PSA_BITS_TO_BYTES( 1500a8e1175bSopenharmony_ci psa_get_key_bits(&key_attributes)); 1501a8e1175bSopenharmony_ci shared_secret = mbedtls_calloc(1, shared_secret_len); 1502a8e1175bSopenharmony_ci if (shared_secret == NULL) { 1503a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 1504a8e1175bSopenharmony_ci } 1505a8e1175bSopenharmony_ci 1506a8e1175bSopenharmony_ci status = psa_raw_key_agreement( 1507a8e1175bSopenharmony_ci alg, handshake->xxdh_psa_privkey, 1508a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len, 1509a8e1175bSopenharmony_ci shared_secret, shared_secret_len, &shared_secret_len); 1510a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1511a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 1512a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret); 1513a8e1175bSopenharmony_ci goto cleanup; 1514a8e1175bSopenharmony_ci } 1515a8e1175bSopenharmony_ci 1516a8e1175bSopenharmony_ci status = psa_destroy_key(handshake->xxdh_psa_privkey); 1517a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1518a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 1519a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret); 1520a8e1175bSopenharmony_ci goto cleanup; 1521a8e1175bSopenharmony_ci } 1522a8e1175bSopenharmony_ci 1523a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 1524a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */ 1525a8e1175bSopenharmony_ci } else { 1526a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Group not supported.")); 1527a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1528a8e1175bSopenharmony_ci } 1529a8e1175bSopenharmony_ci } 1530a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */ 1531a8e1175bSopenharmony_ci 1532a8e1175bSopenharmony_ci /* 1533a8e1175bSopenharmony_ci * Compute the Handshake Secret 1534a8e1175bSopenharmony_ci */ 1535a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_evolve_secret( 1536a8e1175bSopenharmony_ci hash_alg, handshake->tls13_master_secrets.early, 1537a8e1175bSopenharmony_ci shared_secret, shared_secret_len, 1538a8e1175bSopenharmony_ci handshake->tls13_master_secrets.handshake); 1539a8e1175bSopenharmony_ci if (ret != 0) { 1540a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret); 1541a8e1175bSopenharmony_ci goto cleanup; 1542a8e1175bSopenharmony_ci } 1543a8e1175bSopenharmony_ci 1544a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "Handshake secret", 1545a8e1175bSopenharmony_ci handshake->tls13_master_secrets.handshake, 1546a8e1175bSopenharmony_ci PSA_HASH_LENGTH(hash_alg)); 1547a8e1175bSopenharmony_ci 1548a8e1175bSopenharmony_cicleanup: 1549a8e1175bSopenharmony_ci if (shared_secret != NULL) { 1550a8e1175bSopenharmony_ci mbedtls_zeroize_and_free(shared_secret, shared_secret_len); 1551a8e1175bSopenharmony_ci } 1552a8e1175bSopenharmony_ci 1553a8e1175bSopenharmony_ci return ret; 1554a8e1175bSopenharmony_ci} 1555a8e1175bSopenharmony_ci 1556a8e1175bSopenharmony_ci/** 1557a8e1175bSopenharmony_ci * \brief Compute TLS 1.3 application traffic keys. 1558a8e1175bSopenharmony_ci * 1559a8e1175bSopenharmony_ci * ssl_tls13_generate_application_keys() generates application traffic 1560a8e1175bSopenharmony_ci * keys, since any record following a 1-RTT Finished message MUST be 1561a8e1175bSopenharmony_ci * encrypted under the application traffic key. 1562a8e1175bSopenharmony_ci * 1563a8e1175bSopenharmony_ci * \param ssl The SSL context to operate on. This must be in 1564a8e1175bSopenharmony_ci * key schedule stage \c Application, see 1565a8e1175bSopenharmony_ci * ssl_tls13_key_schedule_stage_application(). 1566a8e1175bSopenharmony_ci * \param traffic_keys The address at which to store the application traffic 1567a8e1175bSopenharmony_ci * keys. This must be writable but may be uninitialized. 1568a8e1175bSopenharmony_ci * 1569a8e1175bSopenharmony_ci * \returns \c 0 on success. 1570a8e1175bSopenharmony_ci * \returns A negative error code on failure. 1571a8e1175bSopenharmony_ci */ 1572a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1573a8e1175bSopenharmony_cistatic int ssl_tls13_generate_application_keys( 1574a8e1175bSopenharmony_ci mbedtls_ssl_context *ssl, 1575a8e1175bSopenharmony_ci mbedtls_ssl_key_set *traffic_keys) 1576a8e1175bSopenharmony_ci{ 1577a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1578a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1579a8e1175bSopenharmony_ci 1580a8e1175bSopenharmony_ci /* Address at which to store the application secrets */ 1581a8e1175bSopenharmony_ci mbedtls_ssl_tls13_application_secrets * const app_secrets = 1582a8e1175bSopenharmony_ci &ssl->session_negotiate->app_secrets; 1583a8e1175bSopenharmony_ci 1584a8e1175bSopenharmony_ci /* Holding the transcript up to and including the ServerFinished */ 1585a8e1175bSopenharmony_ci unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; 1586a8e1175bSopenharmony_ci size_t transcript_len; 1587a8e1175bSopenharmony_ci 1588a8e1175bSopenharmony_ci /* Variables relating to the hash for the chosen ciphersuite. */ 1589a8e1175bSopenharmony_ci mbedtls_md_type_t md_type; 1590a8e1175bSopenharmony_ci 1591a8e1175bSopenharmony_ci psa_algorithm_t hash_alg; 1592a8e1175bSopenharmony_ci size_t hash_len; 1593a8e1175bSopenharmony_ci 1594a8e1175bSopenharmony_ci /* Variables relating to the cipher for the chosen ciphersuite. */ 1595a8e1175bSopenharmony_ci size_t key_len = 0, iv_len = 0; 1596a8e1175bSopenharmony_ci 1597a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive application traffic keys")); 1598a8e1175bSopenharmony_ci 1599a8e1175bSopenharmony_ci /* Extract basic information about hash and ciphersuite */ 1600a8e1175bSopenharmony_ci 1601a8e1175bSopenharmony_ci ret = ssl_tls13_get_cipher_key_info(handshake->ciphersuite_info, 1602a8e1175bSopenharmony_ci &key_len, &iv_len); 1603a8e1175bSopenharmony_ci if (ret != 0) { 1604a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret); 1605a8e1175bSopenharmony_ci goto cleanup; 1606a8e1175bSopenharmony_ci } 1607a8e1175bSopenharmony_ci 1608a8e1175bSopenharmony_ci md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac; 1609a8e1175bSopenharmony_ci 1610a8e1175bSopenharmony_ci hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac); 1611a8e1175bSopenharmony_ci hash_len = PSA_HASH_LENGTH(hash_alg); 1612a8e1175bSopenharmony_ci 1613a8e1175bSopenharmony_ci /* Compute current handshake transcript. It's the caller's responsibility 1614a8e1175bSopenharmony_ci * to call this at the right time, that is, after the ServerFinished. */ 1615a8e1175bSopenharmony_ci 1616a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, 1617a8e1175bSopenharmony_ci transcript, sizeof(transcript), 1618a8e1175bSopenharmony_ci &transcript_len); 1619a8e1175bSopenharmony_ci if (ret != 0) { 1620a8e1175bSopenharmony_ci goto cleanup; 1621a8e1175bSopenharmony_ci } 1622a8e1175bSopenharmony_ci 1623a8e1175bSopenharmony_ci /* Compute application secrets from master secret and transcript hash. */ 1624a8e1175bSopenharmony_ci 1625a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_application_secrets( 1626a8e1175bSopenharmony_ci hash_alg, handshake->tls13_master_secrets.app, 1627a8e1175bSopenharmony_ci transcript, transcript_len, app_secrets); 1628a8e1175bSopenharmony_ci if (ret != 0) { 1629a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET( 1630a8e1175bSopenharmony_ci 1, "mbedtls_ssl_tls13_derive_application_secrets", ret); 1631a8e1175bSopenharmony_ci goto cleanup; 1632a8e1175bSopenharmony_ci } 1633a8e1175bSopenharmony_ci 1634a8e1175bSopenharmony_ci /* Derive first epoch of IV + Key for application traffic. */ 1635a8e1175bSopenharmony_ci 1636a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_make_traffic_keys( 1637a8e1175bSopenharmony_ci hash_alg, 1638a8e1175bSopenharmony_ci app_secrets->client_application_traffic_secret_N, 1639a8e1175bSopenharmony_ci app_secrets->server_application_traffic_secret_N, 1640a8e1175bSopenharmony_ci hash_len, key_len, iv_len, traffic_keys); 1641a8e1175bSopenharmony_ci if (ret != 0) { 1642a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret); 1643a8e1175bSopenharmony_ci goto cleanup; 1644a8e1175bSopenharmony_ci } 1645a8e1175bSopenharmony_ci 1646a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "Client application traffic secret", 1647a8e1175bSopenharmony_ci app_secrets->client_application_traffic_secret_N, 1648a8e1175bSopenharmony_ci hash_len); 1649a8e1175bSopenharmony_ci 1650a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "Server application traffic secret", 1651a8e1175bSopenharmony_ci app_secrets->server_application_traffic_secret_N, 1652a8e1175bSopenharmony_ci hash_len); 1653a8e1175bSopenharmony_ci 1654a8e1175bSopenharmony_ci /* 1655a8e1175bSopenharmony_ci * Export client/server application traffic secret 0 1656a8e1175bSopenharmony_ci */ 1657a8e1175bSopenharmony_ci if (ssl->f_export_keys != NULL) { 1658a8e1175bSopenharmony_ci ssl->f_export_keys( 1659a8e1175bSopenharmony_ci ssl->p_export_keys, 1660a8e1175bSopenharmony_ci MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET, 1661a8e1175bSopenharmony_ci app_secrets->client_application_traffic_secret_N, hash_len, 1662a8e1175bSopenharmony_ci handshake->randbytes, 1663a8e1175bSopenharmony_ci handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, 1664a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by 1665a8e1175bSopenharmony_ci a new constant for TLS 1.3! */); 1666a8e1175bSopenharmony_ci 1667a8e1175bSopenharmony_ci ssl->f_export_keys( 1668a8e1175bSopenharmony_ci ssl->p_export_keys, 1669a8e1175bSopenharmony_ci MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET, 1670a8e1175bSopenharmony_ci app_secrets->server_application_traffic_secret_N, hash_len, 1671a8e1175bSopenharmony_ci handshake->randbytes, 1672a8e1175bSopenharmony_ci handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN, 1673a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by 1674a8e1175bSopenharmony_ci a new constant for TLS 1.3! */); 1675a8e1175bSopenharmony_ci } 1676a8e1175bSopenharmony_ci 1677a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client application_write_key:", 1678a8e1175bSopenharmony_ci traffic_keys->client_write_key, key_len); 1679a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "server application write key", 1680a8e1175bSopenharmony_ci traffic_keys->server_write_key, key_len); 1681a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "client application write IV", 1682a8e1175bSopenharmony_ci traffic_keys->client_write_iv, iv_len); 1683a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "server application write IV", 1684a8e1175bSopenharmony_ci traffic_keys->server_write_iv, iv_len); 1685a8e1175bSopenharmony_ci 1686a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive application traffic keys")); 1687a8e1175bSopenharmony_ci 1688a8e1175bSopenharmony_cicleanup: 1689a8e1175bSopenharmony_ci /* randbytes is not used again */ 1690a8e1175bSopenharmony_ci mbedtls_platform_zeroize(ssl->handshake->randbytes, 1691a8e1175bSopenharmony_ci sizeof(ssl->handshake->randbytes)); 1692a8e1175bSopenharmony_ci 1693a8e1175bSopenharmony_ci mbedtls_platform_zeroize(transcript, sizeof(transcript)); 1694a8e1175bSopenharmony_ci return ret; 1695a8e1175bSopenharmony_ci} 1696a8e1175bSopenharmony_ci 1697a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl) 1698a8e1175bSopenharmony_ci{ 1699a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1700a8e1175bSopenharmony_ci mbedtls_ssl_key_set traffic_keys; 1701a8e1175bSopenharmony_ci mbedtls_ssl_transform *transform_handshake = NULL; 1702a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1703a8e1175bSopenharmony_ci 1704a8e1175bSopenharmony_ci /* Compute handshake secret */ 1705a8e1175bSopenharmony_ci ret = ssl_tls13_key_schedule_stage_handshake(ssl); 1706a8e1175bSopenharmony_ci if (ret != 0) { 1707a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_master_secret", ret); 1708a8e1175bSopenharmony_ci goto cleanup; 1709a8e1175bSopenharmony_ci } 1710a8e1175bSopenharmony_ci 1711a8e1175bSopenharmony_ci /* Next evolution in key schedule: Establish handshake secret and 1712a8e1175bSopenharmony_ci * key material. */ 1713a8e1175bSopenharmony_ci ret = ssl_tls13_generate_handshake_keys(ssl, &traffic_keys); 1714a8e1175bSopenharmony_ci if (ret != 0) { 1715a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_handshake_keys", 1716a8e1175bSopenharmony_ci ret); 1717a8e1175bSopenharmony_ci goto cleanup; 1718a8e1175bSopenharmony_ci } 1719a8e1175bSopenharmony_ci 1720a8e1175bSopenharmony_ci transform_handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); 1721a8e1175bSopenharmony_ci if (transform_handshake == NULL) { 1722a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 1723a8e1175bSopenharmony_ci goto cleanup; 1724a8e1175bSopenharmony_ci } 1725a8e1175bSopenharmony_ci 1726a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_populate_transform( 1727a8e1175bSopenharmony_ci transform_handshake, 1728a8e1175bSopenharmony_ci ssl->conf->endpoint, 1729a8e1175bSopenharmony_ci handshake->ciphersuite_info->id, 1730a8e1175bSopenharmony_ci &traffic_keys, 1731a8e1175bSopenharmony_ci ssl); 1732a8e1175bSopenharmony_ci if (ret != 0) { 1733a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); 1734a8e1175bSopenharmony_ci goto cleanup; 1735a8e1175bSopenharmony_ci } 1736a8e1175bSopenharmony_ci handshake->transform_handshake = transform_handshake; 1737a8e1175bSopenharmony_ci 1738a8e1175bSopenharmony_cicleanup: 1739a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); 1740a8e1175bSopenharmony_ci if (ret != 0) { 1741a8e1175bSopenharmony_ci mbedtls_free(transform_handshake); 1742a8e1175bSopenharmony_ci } 1743a8e1175bSopenharmony_ci 1744a8e1175bSopenharmony_ci return ret; 1745a8e1175bSopenharmony_ci} 1746a8e1175bSopenharmony_ci 1747a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl) 1748a8e1175bSopenharmony_ci{ 1749a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1750a8e1175bSopenharmony_ci mbedtls_md_type_t md_type; 1751a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1752a8e1175bSopenharmony_ci unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE]; 1753a8e1175bSopenharmony_ci size_t transcript_len; 1754a8e1175bSopenharmony_ci 1755a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG( 1756a8e1175bSopenharmony_ci 2, ("=> mbedtls_ssl_tls13_compute_resumption_master_secret")); 1757a8e1175bSopenharmony_ci 1758a8e1175bSopenharmony_ci md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac; 1759a8e1175bSopenharmony_ci 1760a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type, 1761a8e1175bSopenharmony_ci transcript, sizeof(transcript), 1762a8e1175bSopenharmony_ci &transcript_len); 1763a8e1175bSopenharmony_ci if (ret != 0) { 1764a8e1175bSopenharmony_ci return ret; 1765a8e1175bSopenharmony_ci } 1766a8e1175bSopenharmony_ci 1767a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_derive_resumption_master_secret( 1768a8e1175bSopenharmony_ci mbedtls_md_psa_alg_from_type(md_type), 1769a8e1175bSopenharmony_ci handshake->tls13_master_secrets.app, 1770a8e1175bSopenharmony_ci transcript, transcript_len, 1771a8e1175bSopenharmony_ci &ssl->session_negotiate->app_secrets); 1772a8e1175bSopenharmony_ci if (ret != 0) { 1773a8e1175bSopenharmony_ci return ret; 1774a8e1175bSopenharmony_ci } 1775a8e1175bSopenharmony_ci 1776a8e1175bSopenharmony_ci /* Erase master secrets */ 1777a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&handshake->tls13_master_secrets, 1778a8e1175bSopenharmony_ci sizeof(handshake->tls13_master_secrets)); 1779a8e1175bSopenharmony_ci 1780a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF( 1781a8e1175bSopenharmony_ci 4, "Resumption master secret", 1782a8e1175bSopenharmony_ci ssl->session_negotiate->app_secrets.resumption_master_secret, 1783a8e1175bSopenharmony_ci PSA_HASH_LENGTH(mbedtls_md_psa_alg_from_type(md_type))); 1784a8e1175bSopenharmony_ci 1785a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG( 1786a8e1175bSopenharmony_ci 2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret")); 1787a8e1175bSopenharmony_ci return 0; 1788a8e1175bSopenharmony_ci} 1789a8e1175bSopenharmony_ci 1790a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl) 1791a8e1175bSopenharmony_ci{ 1792a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1793a8e1175bSopenharmony_ci mbedtls_ssl_key_set traffic_keys; 1794a8e1175bSopenharmony_ci mbedtls_ssl_transform *transform_application = NULL; 1795a8e1175bSopenharmony_ci 1796a8e1175bSopenharmony_ci ret = ssl_tls13_key_schedule_stage_application(ssl); 1797a8e1175bSopenharmony_ci if (ret != 0) { 1798a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 1799a8e1175bSopenharmony_ci "ssl_tls13_key_schedule_stage_application", ret); 1800a8e1175bSopenharmony_ci goto cleanup; 1801a8e1175bSopenharmony_ci } 1802a8e1175bSopenharmony_ci 1803a8e1175bSopenharmony_ci ret = ssl_tls13_generate_application_keys(ssl, &traffic_keys); 1804a8e1175bSopenharmony_ci if (ret != 0) { 1805a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 1806a8e1175bSopenharmony_ci "ssl_tls13_generate_application_keys", ret); 1807a8e1175bSopenharmony_ci goto cleanup; 1808a8e1175bSopenharmony_ci } 1809a8e1175bSopenharmony_ci 1810a8e1175bSopenharmony_ci transform_application = 1811a8e1175bSopenharmony_ci mbedtls_calloc(1, sizeof(mbedtls_ssl_transform)); 1812a8e1175bSopenharmony_ci if (transform_application == NULL) { 1813a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_ALLOC_FAILED; 1814a8e1175bSopenharmony_ci goto cleanup; 1815a8e1175bSopenharmony_ci } 1816a8e1175bSopenharmony_ci 1817a8e1175bSopenharmony_ci ret = mbedtls_ssl_tls13_populate_transform( 1818a8e1175bSopenharmony_ci transform_application, 1819a8e1175bSopenharmony_ci ssl->conf->endpoint, 1820a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info->id, 1821a8e1175bSopenharmony_ci &traffic_keys, 1822a8e1175bSopenharmony_ci ssl); 1823a8e1175bSopenharmony_ci if (ret != 0) { 1824a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret); 1825a8e1175bSopenharmony_ci goto cleanup; 1826a8e1175bSopenharmony_ci } 1827a8e1175bSopenharmony_ci 1828a8e1175bSopenharmony_ci ssl->transform_application = transform_application; 1829a8e1175bSopenharmony_ci 1830a8e1175bSopenharmony_cicleanup: 1831a8e1175bSopenharmony_ci 1832a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys)); 1833a8e1175bSopenharmony_ci if (ret != 0) { 1834a8e1175bSopenharmony_ci mbedtls_free(transform_application); 1835a8e1175bSopenharmony_ci } 1836a8e1175bSopenharmony_ci return ret; 1837a8e1175bSopenharmony_ci} 1838a8e1175bSopenharmony_ci 1839a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) 1840a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl, 1841a8e1175bSopenharmony_ci unsigned char **psk, 1842a8e1175bSopenharmony_ci size_t *psk_len) 1843a8e1175bSopenharmony_ci{ 1844a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1845a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; 1846a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 1847a8e1175bSopenharmony_ci 1848a8e1175bSopenharmony_ci *psk_len = 0; 1849a8e1175bSopenharmony_ci *psk = NULL; 1850a8e1175bSopenharmony_ci 1851a8e1175bSopenharmony_ci if (mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) { 1852a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1853a8e1175bSopenharmony_ci } 1854a8e1175bSopenharmony_ci 1855a8e1175bSopenharmony_ci status = psa_get_key_attributes(ssl->handshake->psk_opaque, &key_attributes); 1856a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1857a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1858a8e1175bSopenharmony_ci } 1859a8e1175bSopenharmony_ci 1860a8e1175bSopenharmony_ci *psk_len = PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attributes)); 1861a8e1175bSopenharmony_ci *psk = mbedtls_calloc(1, *psk_len); 1862a8e1175bSopenharmony_ci if (*psk == NULL) { 1863a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 1864a8e1175bSopenharmony_ci } 1865a8e1175bSopenharmony_ci 1866a8e1175bSopenharmony_ci status = psa_export_key(ssl->handshake->psk_opaque, 1867a8e1175bSopenharmony_ci (uint8_t *) *psk, *psk_len, psk_len); 1868a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 1869a8e1175bSopenharmony_ci mbedtls_free((void *) *psk); 1870a8e1175bSopenharmony_ci *psk = NULL; 1871a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 1872a8e1175bSopenharmony_ci } 1873a8e1175bSopenharmony_ci return 0; 1874a8e1175bSopenharmony_ci#else 1875a8e1175bSopenharmony_ci *psk = ssl->handshake->psk; 1876a8e1175bSopenharmony_ci *psk_len = ssl->handshake->psk_len; 1877a8e1175bSopenharmony_ci if (*psk == NULL) { 1878a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1879a8e1175bSopenharmony_ci } 1880a8e1175bSopenharmony_ci return 0; 1881a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */ 1882a8e1175bSopenharmony_ci} 1883a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ 1884a8e1175bSopenharmony_ci 1885a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ 1886