17901324dSJerome Forissier /*
27901324dSJerome Forissier * TLS 1.3 key schedule
37901324dSJerome Forissier *
47901324dSJerome Forissier * Copyright The Mbed TLS Contributors
5b0563631STom Van Eyck * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
67901324dSJerome Forissier */
77901324dSJerome Forissier
87901324dSJerome Forissier #include "common.h"
97901324dSJerome Forissier
1032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
117901324dSJerome Forissier
127901324dSJerome Forissier #include <stdint.h>
137901324dSJerome Forissier #include <string.h>
147901324dSJerome Forissier
1532b31808SJens Wiklander #include "mbedtls/hkdf.h"
16b0563631STom Van Eyck #include "debug_internal.h"
1732b31808SJens Wiklander #include "mbedtls/error.h"
1832b31808SJens Wiklander #include "mbedtls/platform.h"
1932b31808SJens Wiklander
2032b31808SJens Wiklander #include "ssl_misc.h"
2132b31808SJens Wiklander #include "ssl_tls13_keys.h"
2232b31808SJens Wiklander #include "ssl_tls13_invasive.h"
2332b31808SJens Wiklander
2432b31808SJens Wiklander #include "psa/crypto.h"
25b0563631STom Van Eyck #include "mbedtls/psa_util.h"
2632b31808SJens Wiklander
27b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many
28b0563631STom Van Eyck * arguments in each translating place. */
local_err_translation(psa_status_t status)29b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
30b0563631STom Van Eyck {
31b0563631STom Van Eyck return psa_status_to_mbedtls(status, psa_to_ssl_errors,
32b0563631STom Van Eyck ARRAY_LENGTH(psa_to_ssl_errors),
33b0563631STom Van Eyck psa_generic_status_to_mbedtls);
34b0563631STom Van Eyck }
35b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
3632b31808SJens Wiklander
377901324dSJerome Forissier #define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \
387901324dSJerome Forissier .name = string,
397901324dSJerome Forissier
4032b31808SJens Wiklander struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels =
417901324dSJerome Forissier {
427901324dSJerome Forissier /* This seems to work in C, despite the string literal being one
437901324dSJerome Forissier * character too long due to the 0-termination. */
447901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LABEL_LIST
457901324dSJerome Forissier };
467901324dSJerome Forissier
477901324dSJerome Forissier #undef MBEDTLS_SSL_TLS1_3_LABEL
487901324dSJerome Forissier
497901324dSJerome Forissier /*
507901324dSJerome Forissier * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
517901324dSJerome Forissier *
527901324dSJerome Forissier * The HkdfLabel is specified in RFC 8446 as follows:
537901324dSJerome Forissier *
547901324dSJerome Forissier * struct HkdfLabel {
557901324dSJerome Forissier * uint16 length; // Length of expanded key material
567901324dSJerome Forissier * opaque label<7..255>; // Always prefixed by "tls13 "
577901324dSJerome Forissier * opaque context<0..255>; // Usually a communication transcript hash
587901324dSJerome Forissier * };
597901324dSJerome Forissier *
607901324dSJerome Forissier * Parameters:
61*273a583eSThomas Bourgoin * - desired_length: Length of expanded key material.
62*273a583eSThomas Bourgoin * The length field can hold numbers up to 2**16, but HKDF
63*273a583eSThomas Bourgoin * can only generate outputs of up to 255 * HASH_LEN bytes.
64*273a583eSThomas Bourgoin * It is the caller's responsibility to ensure that this
65*273a583eSThomas Bourgoin * limit is not exceeded. In TLS 1.3, SHA256 is the hash
66*273a583eSThomas Bourgoin * function with the smallest block size, so a length
67*273a583eSThomas Bourgoin * <= 255 * 32 = 8160 is always safe.
6832b31808SJens Wiklander * - (label, label_len): label + label length, without "tls13 " prefix
697901324dSJerome Forissier * The label length MUST be less than or equal to
70*273a583eSThomas Bourgoin * MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN.
717901324dSJerome Forissier * It is the caller's responsibility to ensure this.
727901324dSJerome Forissier * All (label, label length) pairs used in TLS 1.3
737901324dSJerome Forissier * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
7432b31808SJens Wiklander * - (ctx, ctx_len): context + context length
757901324dSJerome Forissier * The context length MUST be less than or equal to
767901324dSJerome Forissier * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
777901324dSJerome Forissier * It is the caller's responsibility to ensure this.
787901324dSJerome Forissier * - dst: Target buffer for HkdfLabel structure,
797901324dSJerome Forissier * This MUST be a writable buffer of size
807901324dSJerome Forissier * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
8132b31808SJens Wiklander * - dst_len: Pointer at which to store the actual length of
827901324dSJerome Forissier * the HkdfLabel structure on success.
837901324dSJerome Forissier */
847901324dSJerome Forissier
85*273a583eSThomas Bourgoin /* We need to tell the compiler that we meant to leave out the null character. */
86*273a583eSThomas Bourgoin static const char tls13_label_prefix[6] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "tls13 ";
877901324dSJerome Forissier
887901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \
897901324dSJerome Forissier (2 /* expansion length */ \
907901324dSJerome Forissier + 1 /* label length */ \
917901324dSJerome Forissier + label_len \
927901324dSJerome Forissier + 1 /* context length */ \
937901324dSJerome Forissier + context_len)
947901324dSJerome Forissier
957901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
967901324dSJerome Forissier SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
9732b31808SJens Wiklander sizeof(tls13_label_prefix) + \
98*273a583eSThomas Bourgoin MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN, \
997901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN)
1007901324dSJerome Forissier
ssl_tls13_hkdf_encode_label(size_t desired_length,const unsigned char * label,size_t label_len,const unsigned char * ctx,size_t ctx_len,unsigned char * dst,size_t * dst_len)10132b31808SJens Wiklander static void ssl_tls13_hkdf_encode_label(
1027901324dSJerome Forissier size_t desired_length,
10332b31808SJens Wiklander const unsigned char *label, size_t label_len,
10432b31808SJens Wiklander const unsigned char *ctx, size_t ctx_len,
10532b31808SJens Wiklander unsigned char *dst, size_t *dst_len)
1067901324dSJerome Forissier {
1077901324dSJerome Forissier size_t total_label_len =
10832b31808SJens Wiklander sizeof(tls13_label_prefix) + label_len;
1097901324dSJerome Forissier size_t total_hkdf_lbl_len =
11032b31808SJens Wiklander SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(total_label_len, ctx_len);
1117901324dSJerome Forissier
1127901324dSJerome Forissier unsigned char *p = dst;
1137901324dSJerome Forissier
114*273a583eSThomas Bourgoin /* Add the size of the expanded key material. */
115*273a583eSThomas Bourgoin #if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > UINT16_MAX
116*273a583eSThomas Bourgoin #error "The desired key length must fit into an uint16 but \
117*273a583eSThomas Bourgoin MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN is greater than UINT16_MAX"
1187901324dSJerome Forissier #endif
1197901324dSJerome Forissier
120*273a583eSThomas Bourgoin *p++ = MBEDTLS_BYTE_1(desired_length);
121039e02dfSJerome Forissier *p++ = MBEDTLS_BYTE_0(desired_length);
1227901324dSJerome Forissier
1237901324dSJerome Forissier /* Add label incl. prefix */
124039e02dfSJerome Forissier *p++ = MBEDTLS_BYTE_0(total_label_len);
12532b31808SJens Wiklander memcpy(p, tls13_label_prefix, sizeof(tls13_label_prefix));
12632b31808SJens Wiklander p += sizeof(tls13_label_prefix);
12732b31808SJens Wiklander memcpy(p, label, label_len);
12832b31808SJens Wiklander p += label_len;
1297901324dSJerome Forissier
1307901324dSJerome Forissier /* Add context value */
13132b31808SJens Wiklander *p++ = MBEDTLS_BYTE_0(ctx_len);
13232b31808SJens Wiklander if (ctx_len != 0) {
13332b31808SJens Wiklander memcpy(p, ctx, ctx_len);
1347901324dSJerome Forissier }
1357901324dSJerome Forissier
13632b31808SJens Wiklander /* Return total length to the caller. */
13732b31808SJens Wiklander *dst_len = total_hkdf_lbl_len;
13832b31808SJens Wiklander }
1397901324dSJerome Forissier
mbedtls_ssl_tls13_hkdf_expand_label(psa_algorithm_t hash_alg,const unsigned char * secret,size_t secret_len,const unsigned char * label,size_t label_len,const unsigned char * ctx,size_t ctx_len,unsigned char * buf,size_t buf_len)14032b31808SJens Wiklander int mbedtls_ssl_tls13_hkdf_expand_label(
14132b31808SJens Wiklander psa_algorithm_t hash_alg,
14232b31808SJens Wiklander const unsigned char *secret, size_t secret_len,
14332b31808SJens Wiklander const unsigned char *label, size_t label_len,
14432b31808SJens Wiklander const unsigned char *ctx, size_t ctx_len,
14532b31808SJens Wiklander unsigned char *buf, size_t buf_len)
1467901324dSJerome Forissier {
14732b31808SJens Wiklander unsigned char hkdf_label[SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN];
14832b31808SJens Wiklander size_t hkdf_label_len = 0;
14932b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
15032b31808SJens Wiklander psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
15132b31808SJens Wiklander psa_key_derivation_operation_t operation =
15232b31808SJens Wiklander PSA_KEY_DERIVATION_OPERATION_INIT;
15332b31808SJens Wiklander
154*273a583eSThomas Bourgoin if (label_len > MBEDTLS_SSL_TLS1_3_HKDF_LABEL_MAX_LABEL_LEN) {
1557901324dSJerome Forissier /* Should never happen since this is an internal
1567901324dSJerome Forissier * function, and we know statically which labels
1577901324dSJerome Forissier * are allowed. */
15832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1597901324dSJerome Forissier }
1607901324dSJerome Forissier
16132b31808SJens Wiklander if (ctx_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) {
1627901324dSJerome Forissier /* Should not happen, as above. */
16332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1647901324dSJerome Forissier }
1657901324dSJerome Forissier
16632b31808SJens Wiklander if (buf_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN) {
1677901324dSJerome Forissier /* Should not happen, as above. */
16832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1697901324dSJerome Forissier }
1707901324dSJerome Forissier
17132b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
17232b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
17332b31808SJens Wiklander }
1747901324dSJerome Forissier
17532b31808SJens Wiklander ssl_tls13_hkdf_encode_label(buf_len,
17632b31808SJens Wiklander label, label_len,
17732b31808SJens Wiklander ctx, ctx_len,
1787901324dSJerome Forissier hkdf_label,
1797901324dSJerome Forissier &hkdf_label_len);
1807901324dSJerome Forissier
18132b31808SJens Wiklander status = psa_key_derivation_setup(&operation, PSA_ALG_HKDF_EXPAND(hash_alg));
18232b31808SJens Wiklander
18332b31808SJens Wiklander if (status != PSA_SUCCESS) {
18432b31808SJens Wiklander goto cleanup;
18532b31808SJens Wiklander }
18632b31808SJens Wiklander
18732b31808SJens Wiklander status = psa_key_derivation_input_bytes(&operation,
18832b31808SJens Wiklander PSA_KEY_DERIVATION_INPUT_SECRET,
18932b31808SJens Wiklander secret,
19032b31808SJens Wiklander secret_len);
19132b31808SJens Wiklander
19232b31808SJens Wiklander if (status != PSA_SUCCESS) {
19332b31808SJens Wiklander goto cleanup;
19432b31808SJens Wiklander }
19532b31808SJens Wiklander
19632b31808SJens Wiklander status = psa_key_derivation_input_bytes(&operation,
19732b31808SJens Wiklander PSA_KEY_DERIVATION_INPUT_INFO,
19832b31808SJens Wiklander hkdf_label,
19932b31808SJens Wiklander hkdf_label_len);
20032b31808SJens Wiklander
20132b31808SJens Wiklander if (status != PSA_SUCCESS) {
20232b31808SJens Wiklander goto cleanup;
20332b31808SJens Wiklander }
20432b31808SJens Wiklander
20532b31808SJens Wiklander status = psa_key_derivation_output_bytes(&operation,
20632b31808SJens Wiklander buf,
20732b31808SJens Wiklander buf_len);
20832b31808SJens Wiklander
20932b31808SJens Wiklander if (status != PSA_SUCCESS) {
21032b31808SJens Wiklander goto cleanup;
21132b31808SJens Wiklander }
21232b31808SJens Wiklander
21332b31808SJens Wiklander cleanup:
21432b31808SJens Wiklander abort_status = psa_key_derivation_abort(&operation);
21532b31808SJens Wiklander status = (status == PSA_SUCCESS ? abort_status : status);
21632b31808SJens Wiklander mbedtls_platform_zeroize(hkdf_label, hkdf_label_len);
21732b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
21832b31808SJens Wiklander }
21932b31808SJens Wiklander
22032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_make_traffic_key(psa_algorithm_t hash_alg,const unsigned char * secret,size_t secret_len,unsigned char * key,size_t key_len,unsigned char * iv,size_t iv_len)22132b31808SJens Wiklander static int ssl_tls13_make_traffic_key(
22232b31808SJens Wiklander psa_algorithm_t hash_alg,
22332b31808SJens Wiklander const unsigned char *secret, size_t secret_len,
22432b31808SJens Wiklander unsigned char *key, size_t key_len,
22532b31808SJens Wiklander unsigned char *iv, size_t iv_len)
22632b31808SJens Wiklander {
22732b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
22832b31808SJens Wiklander
22932b31808SJens Wiklander ret = mbedtls_ssl_tls13_hkdf_expand_label(
23032b31808SJens Wiklander hash_alg,
23132b31808SJens Wiklander secret, secret_len,
23232b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key),
23332b31808SJens Wiklander NULL, 0,
23432b31808SJens Wiklander key, key_len);
23532b31808SJens Wiklander if (ret != 0) {
23632b31808SJens Wiklander return ret;
23732b31808SJens Wiklander }
23832b31808SJens Wiklander
23932b31808SJens Wiklander ret = mbedtls_ssl_tls13_hkdf_expand_label(
24032b31808SJens Wiklander hash_alg,
24132b31808SJens Wiklander secret, secret_len,
24232b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv),
24332b31808SJens Wiklander NULL, 0,
24432b31808SJens Wiklander iv, iv_len);
24532b31808SJens Wiklander return ret;
2467901324dSJerome Forissier }
2477901324dSJerome Forissier
2487901324dSJerome Forissier /*
2497901324dSJerome Forissier * The traffic keying material is generated from the following inputs:
2507901324dSJerome Forissier *
2517901324dSJerome Forissier * - One secret value per sender.
2527901324dSJerome Forissier * - A purpose value indicating the specific value being generated
2537901324dSJerome Forissier * - The desired lengths of key and IV.
2547901324dSJerome Forissier *
2557901324dSJerome Forissier * The expansion itself is based on HKDF:
2567901324dSJerome Forissier *
2577901324dSJerome Forissier * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
2587901324dSJerome Forissier * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
2597901324dSJerome Forissier *
2607901324dSJerome Forissier * [sender] denotes the sending side and the Secret value is provided
2617901324dSJerome Forissier * by the function caller. Note that we generate server and client side
2627901324dSJerome Forissier * keys in a single function call.
2637901324dSJerome Forissier */
mbedtls_ssl_tls13_make_traffic_keys(psa_algorithm_t hash_alg,const unsigned char * client_secret,const unsigned char * server_secret,size_t secret_len,size_t key_len,size_t iv_len,mbedtls_ssl_key_set * keys)26432b31808SJens Wiklander int mbedtls_ssl_tls13_make_traffic_keys(
26532b31808SJens Wiklander psa_algorithm_t hash_alg,
2667901324dSJerome Forissier const unsigned char *client_secret,
26732b31808SJens Wiklander const unsigned char *server_secret, size_t secret_len,
26832b31808SJens Wiklander size_t key_len, size_t iv_len,
2697901324dSJerome Forissier mbedtls_ssl_key_set *keys)
2707901324dSJerome Forissier {
2717901324dSJerome Forissier int ret = 0;
2727901324dSJerome Forissier
27332b31808SJens Wiklander ret = ssl_tls13_make_traffic_key(
27432b31808SJens Wiklander hash_alg, client_secret, secret_len,
27532b31808SJens Wiklander keys->client_write_key, key_len,
2767901324dSJerome Forissier keys->client_write_iv, iv_len);
27732b31808SJens Wiklander if (ret != 0) {
27832b31808SJens Wiklander return ret;
27932b31808SJens Wiklander }
2807901324dSJerome Forissier
28132b31808SJens Wiklander ret = ssl_tls13_make_traffic_key(
28232b31808SJens Wiklander hash_alg, server_secret, secret_len,
28332b31808SJens Wiklander keys->server_write_key, key_len,
2847901324dSJerome Forissier keys->server_write_iv, iv_len);
28532b31808SJens Wiklander if (ret != 0) {
28632b31808SJens Wiklander return ret;
28732b31808SJens Wiklander }
2887901324dSJerome Forissier
2897901324dSJerome Forissier keys->key_len = key_len;
2907901324dSJerome Forissier keys->iv_len = iv_len;
2917901324dSJerome Forissier
29232b31808SJens Wiklander return 0;
2937901324dSJerome Forissier }
2947901324dSJerome Forissier
mbedtls_ssl_tls13_derive_secret(psa_algorithm_t hash_alg,const unsigned char * secret,size_t secret_len,const unsigned char * label,size_t label_len,const unsigned char * ctx,size_t ctx_len,int ctx_hashed,unsigned char * dstbuf,size_t dstbuf_len)29532b31808SJens Wiklander int mbedtls_ssl_tls13_derive_secret(
29632b31808SJens Wiklander psa_algorithm_t hash_alg,
29732b31808SJens Wiklander const unsigned char *secret, size_t secret_len,
29832b31808SJens Wiklander const unsigned char *label, size_t label_len,
29932b31808SJens Wiklander const unsigned char *ctx, size_t ctx_len,
3007901324dSJerome Forissier int ctx_hashed,
30132b31808SJens Wiklander unsigned char *dstbuf, size_t dstbuf_len)
3027901324dSJerome Forissier {
3037901324dSJerome Forissier int ret;
30432b31808SJens Wiklander unsigned char hashed_context[PSA_HASH_MAX_SIZE];
30532b31808SJens Wiklander if (ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED) {
30632b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3077901324dSJerome Forissier
30832b31808SJens Wiklander status = psa_hash_compute(hash_alg, ctx, ctx_len, hashed_context,
30932b31808SJens Wiklander PSA_HASH_LENGTH(hash_alg), &ctx_len);
31032b31808SJens Wiklander if (status != PSA_SUCCESS) {
31132b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
31232b31808SJens Wiklander return ret;
3137901324dSJerome Forissier }
31432b31808SJens Wiklander } else {
31532b31808SJens Wiklander if (ctx_len > sizeof(hashed_context)) {
3167901324dSJerome Forissier /* This should never happen since this function is internal
3177901324dSJerome Forissier * and the code sets `ctx_hashed` correctly.
3187901324dSJerome Forissier * Let's double-check nonetheless to not run at the risk
3197901324dSJerome Forissier * of getting a stack overflow. */
32032b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3217901324dSJerome Forissier }
3227901324dSJerome Forissier
32332b31808SJens Wiklander memcpy(hashed_context, ctx, ctx_len);
3247901324dSJerome Forissier }
3257901324dSJerome Forissier
32632b31808SJens Wiklander return mbedtls_ssl_tls13_hkdf_expand_label(hash_alg,
32732b31808SJens Wiklander secret, secret_len,
32832b31808SJens Wiklander label, label_len,
32932b31808SJens Wiklander hashed_context, ctx_len,
33032b31808SJens Wiklander dstbuf, dstbuf_len);
33132b31808SJens Wiklander
3327901324dSJerome Forissier }
3337901324dSJerome Forissier
mbedtls_ssl_tls13_evolve_secret(psa_algorithm_t hash_alg,const unsigned char * secret_old,const unsigned char * input,size_t input_len,unsigned char * secret_new)33432b31808SJens Wiklander int mbedtls_ssl_tls13_evolve_secret(
33532b31808SJens Wiklander psa_algorithm_t hash_alg,
3367901324dSJerome Forissier const unsigned char *secret_old,
3377901324dSJerome Forissier const unsigned char *input, size_t input_len,
3387901324dSJerome Forissier unsigned char *secret_new)
3397901324dSJerome Forissier {
3407901324dSJerome Forissier int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
34132b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
34232b31808SJens Wiklander psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
34332b31808SJens Wiklander size_t hlen;
34432b31808SJens Wiklander unsigned char tmp_secret[PSA_MAC_MAX_SIZE] = { 0 };
34532b31808SJens Wiklander const unsigned char all_zeroes_input[MBEDTLS_TLS1_3_MD_MAX_SIZE] = { 0 };
34632b31808SJens Wiklander const unsigned char *l_input = NULL;
34732b31808SJens Wiklander size_t l_input_len;
3487901324dSJerome Forissier
34932b31808SJens Wiklander psa_key_derivation_operation_t operation =
35032b31808SJens Wiklander PSA_KEY_DERIVATION_OPERATION_INIT;
3517901324dSJerome Forissier
35232b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
35332b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
35432b31808SJens Wiklander }
35532b31808SJens Wiklander
35632b31808SJens Wiklander hlen = PSA_HASH_LENGTH(hash_alg);
3577901324dSJerome Forissier
3587901324dSJerome Forissier /* For non-initial runs, call Derive-Secret( ., "derived", "")
3597901324dSJerome Forissier * on the old secret. */
36032b31808SJens Wiklander if (secret_old != NULL) {
36132b31808SJens Wiklander ret = mbedtls_ssl_tls13_derive_secret(
3627901324dSJerome Forissier hash_alg,
3637901324dSJerome Forissier secret_old, hlen,
3647901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(derived),
3657901324dSJerome Forissier NULL, 0, /* context */
3667901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
3677901324dSJerome Forissier tmp_secret, hlen);
36832b31808SJens Wiklander if (ret != 0) {
3697901324dSJerome Forissier goto cleanup;
3707901324dSJerome Forissier }
3717901324dSJerome Forissier }
3727901324dSJerome Forissier
3737901324dSJerome Forissier ret = 0;
3747901324dSJerome Forissier
37532b31808SJens Wiklander if (input != NULL && input_len != 0) {
37632b31808SJens Wiklander l_input = input;
37732b31808SJens Wiklander l_input_len = input_len;
37832b31808SJens Wiklander } else {
37932b31808SJens Wiklander l_input = all_zeroes_input;
38032b31808SJens Wiklander l_input_len = hlen;
3817901324dSJerome Forissier }
3827901324dSJerome Forissier
38332b31808SJens Wiklander status = psa_key_derivation_setup(&operation,
38432b31808SJens Wiklander PSA_ALG_HKDF_EXTRACT(hash_alg));
38532b31808SJens Wiklander
38632b31808SJens Wiklander if (status != PSA_SUCCESS) {
38732b31808SJens Wiklander goto cleanup;
38832b31808SJens Wiklander }
38932b31808SJens Wiklander
39032b31808SJens Wiklander status = psa_key_derivation_input_bytes(&operation,
39132b31808SJens Wiklander PSA_KEY_DERIVATION_INPUT_SALT,
39232b31808SJens Wiklander tmp_secret,
39332b31808SJens Wiklander hlen);
39432b31808SJens Wiklander
39532b31808SJens Wiklander if (status != PSA_SUCCESS) {
39632b31808SJens Wiklander goto cleanup;
39732b31808SJens Wiklander }
39832b31808SJens Wiklander
39932b31808SJens Wiklander status = psa_key_derivation_input_bytes(&operation,
40032b31808SJens Wiklander PSA_KEY_DERIVATION_INPUT_SECRET,
40132b31808SJens Wiklander l_input, l_input_len);
40232b31808SJens Wiklander
40332b31808SJens Wiklander if (status != PSA_SUCCESS) {
40432b31808SJens Wiklander goto cleanup;
40532b31808SJens Wiklander }
40632b31808SJens Wiklander
40732b31808SJens Wiklander status = psa_key_derivation_output_bytes(&operation,
40832b31808SJens Wiklander secret_new,
40932b31808SJens Wiklander PSA_HASH_LENGTH(hash_alg));
41032b31808SJens Wiklander
41132b31808SJens Wiklander if (status != PSA_SUCCESS) {
41232b31808SJens Wiklander goto cleanup;
41332b31808SJens Wiklander }
41432b31808SJens Wiklander
41532b31808SJens Wiklander cleanup:
41632b31808SJens Wiklander abort_status = psa_key_derivation_abort(&operation);
41732b31808SJens Wiklander status = (status == PSA_SUCCESS ? abort_status : status);
41832b31808SJens Wiklander ret = (ret == 0 ? PSA_TO_MBEDTLS_ERR(status) : ret);
41932b31808SJens Wiklander mbedtls_platform_zeroize(tmp_secret, sizeof(tmp_secret));
42032b31808SJens Wiklander return ret;
42132b31808SJens Wiklander }
42232b31808SJens Wiklander
mbedtls_ssl_tls13_derive_early_secrets(psa_algorithm_t hash_alg,unsigned char const * early_secret,unsigned char const * transcript,size_t transcript_len,mbedtls_ssl_tls13_early_secrets * derived)42332b31808SJens Wiklander int mbedtls_ssl_tls13_derive_early_secrets(
42432b31808SJens Wiklander psa_algorithm_t hash_alg,
42532b31808SJens Wiklander unsigned char const *early_secret,
42632b31808SJens Wiklander unsigned char const *transcript, size_t transcript_len,
42732b31808SJens Wiklander mbedtls_ssl_tls13_early_secrets *derived)
42832b31808SJens Wiklander {
42932b31808SJens Wiklander int ret;
43032b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
43132b31808SJens Wiklander
43232b31808SJens Wiklander /* We should never call this function with an unknown hash,
43332b31808SJens Wiklander * but add an assertion anyway. */
43432b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
43532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
43632b31808SJens Wiklander }
43732b31808SJens Wiklander
43832b31808SJens Wiklander /*
43932b31808SJens Wiklander * 0
44032b31808SJens Wiklander * |
44132b31808SJens Wiklander * v
44232b31808SJens Wiklander * PSK -> HKDF-Extract = Early Secret
44332b31808SJens Wiklander * |
44432b31808SJens Wiklander * +-----> Derive-Secret(., "c e traffic", ClientHello)
44532b31808SJens Wiklander * | = client_early_traffic_secret
44632b31808SJens Wiklander * |
44732b31808SJens Wiklander * +-----> Derive-Secret(., "e exp master", ClientHello)
44832b31808SJens Wiklander * | = early_exporter_master_secret
44932b31808SJens Wiklander * v
45032b31808SJens Wiklander */
45132b31808SJens Wiklander
45232b31808SJens Wiklander /* Create client_early_traffic_secret */
453b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
454b0563631STom Van Eyck hash_alg,
45532b31808SJens Wiklander early_secret, hash_len,
45632b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic),
45732b31808SJens Wiklander transcript, transcript_len,
45832b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
45932b31808SJens Wiklander derived->client_early_traffic_secret,
46032b31808SJens Wiklander hash_len);
46132b31808SJens Wiklander if (ret != 0) {
46232b31808SJens Wiklander return ret;
46332b31808SJens Wiklander }
46432b31808SJens Wiklander
46532b31808SJens Wiklander /* Create early exporter */
466b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
467b0563631STom Van Eyck hash_alg,
46832b31808SJens Wiklander early_secret, hash_len,
46932b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master),
47032b31808SJens Wiklander transcript, transcript_len,
47132b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
47232b31808SJens Wiklander derived->early_exporter_master_secret,
47332b31808SJens Wiklander hash_len);
47432b31808SJens Wiklander if (ret != 0) {
47532b31808SJens Wiklander return ret;
47632b31808SJens Wiklander }
47732b31808SJens Wiklander
47832b31808SJens Wiklander return 0;
47932b31808SJens Wiklander }
48032b31808SJens Wiklander
mbedtls_ssl_tls13_derive_handshake_secrets(psa_algorithm_t hash_alg,unsigned char const * handshake_secret,unsigned char const * transcript,size_t transcript_len,mbedtls_ssl_tls13_handshake_secrets * derived)48132b31808SJens Wiklander int mbedtls_ssl_tls13_derive_handshake_secrets(
48232b31808SJens Wiklander psa_algorithm_t hash_alg,
48332b31808SJens Wiklander unsigned char const *handshake_secret,
48432b31808SJens Wiklander unsigned char const *transcript, size_t transcript_len,
48532b31808SJens Wiklander mbedtls_ssl_tls13_handshake_secrets *derived)
48632b31808SJens Wiklander {
48732b31808SJens Wiklander int ret;
48832b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
48932b31808SJens Wiklander
49032b31808SJens Wiklander /* We should never call this function with an unknown hash,
49132b31808SJens Wiklander * but add an assertion anyway. */
49232b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
49332b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
49432b31808SJens Wiklander }
49532b31808SJens Wiklander
49632b31808SJens Wiklander /*
49732b31808SJens Wiklander *
49832b31808SJens Wiklander * Handshake Secret
49932b31808SJens Wiklander * |
50032b31808SJens Wiklander * +-----> Derive-Secret( ., "c hs traffic",
50132b31808SJens Wiklander * | ClientHello...ServerHello )
50232b31808SJens Wiklander * | = client_handshake_traffic_secret
50332b31808SJens Wiklander * |
50432b31808SJens Wiklander * +-----> Derive-Secret( ., "s hs traffic",
50532b31808SJens Wiklander * | ClientHello...ServerHello )
50632b31808SJens Wiklander * | = server_handshake_traffic_secret
50732b31808SJens Wiklander *
50832b31808SJens Wiklander */
50932b31808SJens Wiklander
51032b31808SJens Wiklander /*
51132b31808SJens Wiklander * Compute client_handshake_traffic_secret with
51232b31808SJens Wiklander * Derive-Secret( ., "c hs traffic", ClientHello...ServerHello )
51332b31808SJens Wiklander */
51432b31808SJens Wiklander
515b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
516b0563631STom Van Eyck hash_alg,
51732b31808SJens Wiklander handshake_secret, hash_len,
51832b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic),
51932b31808SJens Wiklander transcript, transcript_len,
52032b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
52132b31808SJens Wiklander derived->client_handshake_traffic_secret,
52232b31808SJens Wiklander hash_len);
52332b31808SJens Wiklander if (ret != 0) {
52432b31808SJens Wiklander return ret;
52532b31808SJens Wiklander }
52632b31808SJens Wiklander
52732b31808SJens Wiklander /*
52832b31808SJens Wiklander * Compute server_handshake_traffic_secret with
52932b31808SJens Wiklander * Derive-Secret( ., "s hs traffic", ClientHello...ServerHello )
53032b31808SJens Wiklander */
53132b31808SJens Wiklander
532b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
533b0563631STom Van Eyck hash_alg,
53432b31808SJens Wiklander handshake_secret, hash_len,
53532b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic),
53632b31808SJens Wiklander transcript, transcript_len,
53732b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
53832b31808SJens Wiklander derived->server_handshake_traffic_secret,
53932b31808SJens Wiklander hash_len);
54032b31808SJens Wiklander if (ret != 0) {
54132b31808SJens Wiklander return ret;
54232b31808SJens Wiklander }
54332b31808SJens Wiklander
54432b31808SJens Wiklander return 0;
54532b31808SJens Wiklander }
54632b31808SJens Wiklander
mbedtls_ssl_tls13_derive_application_secrets(psa_algorithm_t hash_alg,unsigned char const * application_secret,unsigned char const * transcript,size_t transcript_len,mbedtls_ssl_tls13_application_secrets * derived)54732b31808SJens Wiklander int mbedtls_ssl_tls13_derive_application_secrets(
54832b31808SJens Wiklander psa_algorithm_t hash_alg,
54932b31808SJens Wiklander unsigned char const *application_secret,
55032b31808SJens Wiklander unsigned char const *transcript, size_t transcript_len,
55132b31808SJens Wiklander mbedtls_ssl_tls13_application_secrets *derived)
55232b31808SJens Wiklander {
55332b31808SJens Wiklander int ret;
55432b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
55532b31808SJens Wiklander
55632b31808SJens Wiklander /* We should never call this function with an unknown hash,
55732b31808SJens Wiklander * but add an assertion anyway. */
55832b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
55932b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
56032b31808SJens Wiklander }
56132b31808SJens Wiklander
56232b31808SJens Wiklander /* Generate {client,server}_application_traffic_secret_0
56332b31808SJens Wiklander *
56432b31808SJens Wiklander * Master Secret
56532b31808SJens Wiklander * |
56632b31808SJens Wiklander * +-----> Derive-Secret( ., "c ap traffic",
56732b31808SJens Wiklander * | ClientHello...server Finished )
56832b31808SJens Wiklander * | = client_application_traffic_secret_0
56932b31808SJens Wiklander * |
57032b31808SJens Wiklander * +-----> Derive-Secret( ., "s ap traffic",
57132b31808SJens Wiklander * | ClientHello...Server Finished )
57232b31808SJens Wiklander * | = server_application_traffic_secret_0
57332b31808SJens Wiklander * |
57432b31808SJens Wiklander * +-----> Derive-Secret( ., "exp master",
57532b31808SJens Wiklander * | ClientHello...server Finished)
57632b31808SJens Wiklander * | = exporter_master_secret
57732b31808SJens Wiklander *
57832b31808SJens Wiklander */
57932b31808SJens Wiklander
580b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
581b0563631STom Van Eyck hash_alg,
58232b31808SJens Wiklander application_secret, hash_len,
58332b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic),
58432b31808SJens Wiklander transcript, transcript_len,
58532b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
58632b31808SJens Wiklander derived->client_application_traffic_secret_N,
58732b31808SJens Wiklander hash_len);
58832b31808SJens Wiklander if (ret != 0) {
58932b31808SJens Wiklander return ret;
59032b31808SJens Wiklander }
59132b31808SJens Wiklander
592b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
593b0563631STom Van Eyck hash_alg,
59432b31808SJens Wiklander application_secret, hash_len,
59532b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic),
59632b31808SJens Wiklander transcript, transcript_len,
59732b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
59832b31808SJens Wiklander derived->server_application_traffic_secret_N,
59932b31808SJens Wiklander hash_len);
60032b31808SJens Wiklander if (ret != 0) {
60132b31808SJens Wiklander return ret;
60232b31808SJens Wiklander }
60332b31808SJens Wiklander
604b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
605b0563631STom Van Eyck hash_alg,
60632b31808SJens Wiklander application_secret, hash_len,
60732b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master),
60832b31808SJens Wiklander transcript, transcript_len,
60932b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
61032b31808SJens Wiklander derived->exporter_master_secret,
61132b31808SJens Wiklander hash_len);
61232b31808SJens Wiklander if (ret != 0) {
61332b31808SJens Wiklander return ret;
61432b31808SJens Wiklander }
61532b31808SJens Wiklander
61632b31808SJens Wiklander return 0;
61732b31808SJens Wiklander }
61832b31808SJens Wiklander
61932b31808SJens Wiklander /* Generate resumption_master_secret for use with the ticket exchange.
62032b31808SJens Wiklander *
62132b31808SJens Wiklander * This is not integrated with mbedtls_ssl_tls13_derive_application_secrets()
62232b31808SJens Wiklander * because it uses the transcript hash up to and including ClientFinished. */
mbedtls_ssl_tls13_derive_resumption_master_secret(psa_algorithm_t hash_alg,unsigned char const * application_secret,unsigned char const * transcript,size_t transcript_len,mbedtls_ssl_tls13_application_secrets * derived)62332b31808SJens Wiklander int mbedtls_ssl_tls13_derive_resumption_master_secret(
62432b31808SJens Wiklander psa_algorithm_t hash_alg,
62532b31808SJens Wiklander unsigned char const *application_secret,
62632b31808SJens Wiklander unsigned char const *transcript, size_t transcript_len,
62732b31808SJens Wiklander mbedtls_ssl_tls13_application_secrets *derived)
62832b31808SJens Wiklander {
62932b31808SJens Wiklander int ret;
63032b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
63132b31808SJens Wiklander
63232b31808SJens Wiklander /* We should never call this function with an unknown hash,
63332b31808SJens Wiklander * but add an assertion anyway. */
63432b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
63532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
63632b31808SJens Wiklander }
63732b31808SJens Wiklander
638b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
639b0563631STom Van Eyck hash_alg,
64032b31808SJens Wiklander application_secret, hash_len,
64132b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master),
64232b31808SJens Wiklander transcript, transcript_len,
64332b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
64432b31808SJens Wiklander derived->resumption_master_secret,
64532b31808SJens Wiklander hash_len);
64632b31808SJens Wiklander
64732b31808SJens Wiklander if (ret != 0) {
64832b31808SJens Wiklander return ret;
64932b31808SJens Wiklander }
65032b31808SJens Wiklander
65132b31808SJens Wiklander return 0;
65232b31808SJens Wiklander }
65332b31808SJens Wiklander
65432b31808SJens Wiklander /**
65532b31808SJens Wiklander * \brief Transition into application stage of TLS 1.3 key schedule.
65632b31808SJens Wiklander *
65732b31808SJens Wiklander * The TLS 1.3 key schedule can be viewed as a simple state machine
65832b31808SJens Wiklander * with states Initial -> Early -> Handshake -> Application, and
65932b31808SJens Wiklander * this function represents the Handshake -> Application transition.
66032b31808SJens Wiklander *
66132b31808SJens Wiklander * In the handshake stage, ssl_tls13_generate_application_keys()
66232b31808SJens Wiklander * can be used to derive the handshake traffic keys.
66332b31808SJens Wiklander *
66432b31808SJens Wiklander * \param ssl The SSL context to operate on. This must be in key schedule
66532b31808SJens Wiklander * stage \c Handshake.
66632b31808SJens Wiklander *
66732b31808SJens Wiklander * \returns \c 0 on success.
66832b31808SJens Wiklander * \returns A negative error code on failure.
66932b31808SJens Wiklander */
67032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context * ssl)67132b31808SJens Wiklander static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
67232b31808SJens Wiklander {
67332b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
67432b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
675b0563631STom Van Eyck psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
676b0563631STom Van Eyck (mbedtls_md_type_t) handshake->ciphersuite_info->mac);
67732b31808SJens Wiklander
67832b31808SJens Wiklander /*
67932b31808SJens Wiklander * Compute MasterSecret
68032b31808SJens Wiklander */
681b0563631STom Van Eyck ret = mbedtls_ssl_tls13_evolve_secret(
682b0563631STom Van Eyck hash_alg,
68332b31808SJens Wiklander handshake->tls13_master_secrets.handshake,
68432b31808SJens Wiklander NULL, 0,
68532b31808SJens Wiklander handshake->tls13_master_secrets.app);
68632b31808SJens Wiklander if (ret != 0) {
68732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
68832b31808SJens Wiklander return ret;
68932b31808SJens Wiklander }
69032b31808SJens Wiklander
691b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_BUF(
692b0563631STom Van Eyck 4, "Master secret",
69332b31808SJens Wiklander handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg));
69432b31808SJens Wiklander
69532b31808SJens Wiklander return 0;
69632b31808SJens Wiklander }
69732b31808SJens Wiklander
69832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_calc_finished_core(psa_algorithm_t hash_alg,unsigned char const * base_key,unsigned char const * transcript,unsigned char * dst,size_t * dst_len)69932b31808SJens Wiklander static int ssl_tls13_calc_finished_core(psa_algorithm_t hash_alg,
70032b31808SJens Wiklander unsigned char const *base_key,
70132b31808SJens Wiklander unsigned char const *transcript,
70232b31808SJens Wiklander unsigned char *dst,
70332b31808SJens Wiklander size_t *dst_len)
70432b31808SJens Wiklander {
70532b31808SJens Wiklander mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
70632b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
70732b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
70832b31808SJens Wiklander size_t hash_len = PSA_HASH_LENGTH(hash_alg);
70932b31808SJens Wiklander unsigned char finished_key[PSA_MAC_MAX_SIZE];
71032b31808SJens Wiklander int ret;
71132b31808SJens Wiklander psa_algorithm_t alg;
71232b31808SJens Wiklander
71332b31808SJens Wiklander /* We should never call this function with an unknown hash,
71432b31808SJens Wiklander * but add an assertion anyway. */
71532b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
71632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
71732b31808SJens Wiklander }
71832b31808SJens Wiklander
71932b31808SJens Wiklander /* TLS 1.3 Finished message
72032b31808SJens Wiklander *
72132b31808SJens Wiklander * struct {
72232b31808SJens Wiklander * opaque verify_data[Hash.length];
72332b31808SJens Wiklander * } Finished;
72432b31808SJens Wiklander *
72532b31808SJens Wiklander * verify_data =
72632b31808SJens Wiklander * HMAC( finished_key,
72732b31808SJens Wiklander * Hash( Handshake Context +
72832b31808SJens Wiklander * Certificate* +
72932b31808SJens Wiklander * CertificateVerify* )
73032b31808SJens Wiklander * )
73132b31808SJens Wiklander *
73232b31808SJens Wiklander * finished_key =
73332b31808SJens Wiklander * HKDF-Expand-Label( BaseKey, "finished", "", Hash.length )
73432b31808SJens Wiklander */
73532b31808SJens Wiklander
73632b31808SJens Wiklander ret = mbedtls_ssl_tls13_hkdf_expand_label(
73732b31808SJens Wiklander hash_alg, base_key, hash_len,
73832b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(finished),
73932b31808SJens Wiklander NULL, 0,
74032b31808SJens Wiklander finished_key, hash_len);
74132b31808SJens Wiklander if (ret != 0) {
74232b31808SJens Wiklander goto exit;
74332b31808SJens Wiklander }
74432b31808SJens Wiklander
74532b31808SJens Wiklander alg = PSA_ALG_HMAC(hash_alg);
74632b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
74732b31808SJens Wiklander psa_set_key_algorithm(&attributes, alg);
74832b31808SJens Wiklander psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
74932b31808SJens Wiklander
75032b31808SJens Wiklander status = psa_import_key(&attributes, finished_key, hash_len, &key);
75132b31808SJens Wiklander if (status != PSA_SUCCESS) {
75232b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
75332b31808SJens Wiklander goto exit;
75432b31808SJens Wiklander }
75532b31808SJens Wiklander
75632b31808SJens Wiklander status = psa_mac_compute(key, alg, transcript, hash_len,
75732b31808SJens Wiklander dst, hash_len, dst_len);
75832b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
75932b31808SJens Wiklander
76032b31808SJens Wiklander exit:
76132b31808SJens Wiklander
76232b31808SJens Wiklander status = psa_destroy_key(key);
76332b31808SJens Wiklander if (ret == 0) {
76432b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
76532b31808SJens Wiklander }
76632b31808SJens Wiklander
76732b31808SJens Wiklander mbedtls_platform_zeroize(finished_key, sizeof(finished_key));
76832b31808SJens Wiklander
76932b31808SJens Wiklander return ret;
77032b31808SJens Wiklander }
77132b31808SJens Wiklander
mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context * ssl,unsigned char * dst,size_t dst_len,size_t * actual_len,int from)77232b31808SJens Wiklander int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl,
77332b31808SJens Wiklander unsigned char *dst,
77432b31808SJens Wiklander size_t dst_len,
77532b31808SJens Wiklander size_t *actual_len,
77632b31808SJens Wiklander int from)
77732b31808SJens Wiklander {
77832b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
77932b31808SJens Wiklander
78032b31808SJens Wiklander unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
78132b31808SJens Wiklander size_t transcript_len;
78232b31808SJens Wiklander
78332b31808SJens Wiklander unsigned char *base_key = NULL;
78432b31808SJens Wiklander size_t base_key_len = 0;
78532b31808SJens Wiklander mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets =
78632b31808SJens Wiklander &ssl->handshake->tls13_hs_secrets;
78732b31808SJens Wiklander
788b0563631STom Van Eyck mbedtls_md_type_t const md_type = (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac;
78932b31808SJens Wiklander
790b0563631STom Van Eyck psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(
791b0563631STom Van Eyck (mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac);
79232b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
79332b31808SJens Wiklander
79432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_tls13_calculate_verify_data"));
79532b31808SJens Wiklander
79632b31808SJens Wiklander if (from == MBEDTLS_SSL_IS_CLIENT) {
79732b31808SJens Wiklander base_key = tls13_hs_secrets->client_handshake_traffic_secret;
79832b31808SJens Wiklander base_key_len = sizeof(tls13_hs_secrets->client_handshake_traffic_secret);
79932b31808SJens Wiklander } else {
80032b31808SJens Wiklander base_key = tls13_hs_secrets->server_handshake_traffic_secret;
80132b31808SJens Wiklander base_key_len = sizeof(tls13_hs_secrets->server_handshake_traffic_secret);
80232b31808SJens Wiklander }
80332b31808SJens Wiklander
80432b31808SJens Wiklander if (dst_len < hash_len) {
80532b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
80632b31808SJens Wiklander goto exit;
80732b31808SJens Wiklander }
80832b31808SJens Wiklander
80932b31808SJens Wiklander ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
81032b31808SJens Wiklander transcript, sizeof(transcript),
81132b31808SJens Wiklander &transcript_len);
81232b31808SJens Wiklander if (ret != 0) {
81332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret);
81432b31808SJens Wiklander goto exit;
81532b31808SJens Wiklander }
81632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "handshake hash", transcript, transcript_len);
81732b31808SJens Wiklander
818b0563631STom Van Eyck ret = ssl_tls13_calc_finished_core(hash_alg, base_key,
819b0563631STom Van Eyck transcript, dst, actual_len);
82032b31808SJens Wiklander if (ret != 0) {
82132b31808SJens Wiklander goto exit;
82232b31808SJens Wiklander }
82332b31808SJens Wiklander
82432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "verify_data for finished message", dst, hash_len);
82532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_tls13_calculate_verify_data"));
82632b31808SJens Wiklander
82732b31808SJens Wiklander exit:
82832b31808SJens Wiklander /* Erase handshake secrets */
82932b31808SJens Wiklander mbedtls_platform_zeroize(base_key, base_key_len);
83032b31808SJens Wiklander mbedtls_platform_zeroize(transcript, sizeof(transcript));
83132b31808SJens Wiklander return ret;
83232b31808SJens Wiklander }
83332b31808SJens Wiklander
mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context * ssl,const psa_algorithm_t hash_alg,unsigned char const * psk,size_t psk_len,int psk_type,unsigned char const * transcript,unsigned char * result)83432b31808SJens Wiklander int mbedtls_ssl_tls13_create_psk_binder(mbedtls_ssl_context *ssl,
83532b31808SJens Wiklander const psa_algorithm_t hash_alg,
83632b31808SJens Wiklander unsigned char const *psk, size_t psk_len,
83732b31808SJens Wiklander int psk_type,
83832b31808SJens Wiklander unsigned char const *transcript,
83932b31808SJens Wiklander unsigned char *result)
84032b31808SJens Wiklander {
84132b31808SJens Wiklander int ret = 0;
84232b31808SJens Wiklander unsigned char binder_key[PSA_MAC_MAX_SIZE];
84332b31808SJens Wiklander unsigned char early_secret[PSA_MAC_MAX_SIZE];
84432b31808SJens Wiklander size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
84532b31808SJens Wiklander size_t actual_len;
84632b31808SJens Wiklander
84732b31808SJens Wiklander #if !defined(MBEDTLS_DEBUG_C)
84832b31808SJens Wiklander ssl = NULL; /* make sure we don't use it except for debug */
84932b31808SJens Wiklander ((void) ssl);
85032b31808SJens Wiklander #endif
85132b31808SJens Wiklander
85232b31808SJens Wiklander /* We should never call this function with an unknown hash,
85332b31808SJens Wiklander * but add an assertion anyway. */
85432b31808SJens Wiklander if (!PSA_ALG_IS_HASH(hash_alg)) {
85532b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
85632b31808SJens Wiklander }
85732b31808SJens Wiklander
85832b31808SJens Wiklander /*
85932b31808SJens Wiklander * 0
86032b31808SJens Wiklander * |
86132b31808SJens Wiklander * v
86232b31808SJens Wiklander * PSK -> HKDF-Extract = Early Secret
86332b31808SJens Wiklander * |
86432b31808SJens Wiklander * +-----> Derive-Secret(., "ext binder" | "res binder", "")
86532b31808SJens Wiklander * | = binder_key
86632b31808SJens Wiklander * v
86732b31808SJens Wiklander */
86832b31808SJens Wiklander
86932b31808SJens Wiklander ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
87032b31808SJens Wiklander NULL, /* Old secret */
87132b31808SJens Wiklander psk, psk_len, /* Input */
87232b31808SJens Wiklander early_secret);
87332b31808SJens Wiklander if (ret != 0) {
87432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
87532b31808SJens Wiklander goto exit;
87632b31808SJens Wiklander }
87732b31808SJens Wiklander
87832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_create_psk_binder",
87932b31808SJens Wiklander early_secret, hash_len);
88032b31808SJens Wiklander
88132b31808SJens Wiklander if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
882b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
883b0563631STom Van Eyck hash_alg,
88432b31808SJens Wiklander early_secret, hash_len,
88532b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder),
88632b31808SJens Wiklander NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
88732b31808SJens Wiklander binder_key, hash_len);
88832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'res binder'"));
88932b31808SJens Wiklander } else {
890b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_secret(
891b0563631STom Van Eyck hash_alg,
89232b31808SJens Wiklander early_secret, hash_len,
89332b31808SJens Wiklander MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder),
89432b31808SJens Wiklander NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
89532b31808SJens Wiklander binder_key, hash_len);
89632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'ext binder'"));
89732b31808SJens Wiklander }
89832b31808SJens Wiklander
89932b31808SJens Wiklander if (ret != 0) {
90032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_secret", ret);
90132b31808SJens Wiklander goto exit;
90232b31808SJens Wiklander }
90332b31808SJens Wiklander
90432b31808SJens Wiklander /*
90532b31808SJens Wiklander * The binding_value is computed in the same way as the Finished message
90632b31808SJens Wiklander * but with the BaseKey being the binder_key.
90732b31808SJens Wiklander */
90832b31808SJens Wiklander
90932b31808SJens Wiklander ret = ssl_tls13_calc_finished_core(hash_alg, binder_key, transcript,
91032b31808SJens Wiklander result, &actual_len);
91132b31808SJens Wiklander if (ret != 0) {
91232b31808SJens Wiklander goto exit;
91332b31808SJens Wiklander }
91432b31808SJens Wiklander
91532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(3, "psk binder", result, actual_len);
91632b31808SJens Wiklander
91732b31808SJens Wiklander exit:
91832b31808SJens Wiklander
91932b31808SJens Wiklander mbedtls_platform_zeroize(early_secret, sizeof(early_secret));
92032b31808SJens Wiklander mbedtls_platform_zeroize(binder_key, sizeof(binder_key));
92132b31808SJens Wiklander return ret;
92232b31808SJens Wiklander }
92332b31808SJens Wiklander
mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform * transform,int endpoint,int ciphersuite,mbedtls_ssl_key_set const * traffic_keys,mbedtls_ssl_context * ssl)924b0563631STom Van Eyck int mbedtls_ssl_tls13_populate_transform(
925b0563631STom Van Eyck mbedtls_ssl_transform *transform,
926b0563631STom Van Eyck int endpoint, int ciphersuite,
92732b31808SJens Wiklander mbedtls_ssl_key_set const *traffic_keys,
92832b31808SJens Wiklander mbedtls_ssl_context *ssl /* DEBUG ONLY */)
92932b31808SJens Wiklander {
93032b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
93132b31808SJens Wiklander int ret;
93232b31808SJens Wiklander mbedtls_cipher_info_t const *cipher_info;
93332b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
93432b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
93532b31808SJens Wiklander unsigned char const *key_enc;
93632b31808SJens Wiklander unsigned char const *iv_enc;
93732b31808SJens Wiklander unsigned char const *key_dec;
93832b31808SJens Wiklander unsigned char const *iv_dec;
93932b31808SJens Wiklander
94032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
94132b31808SJens Wiklander psa_key_type_t key_type;
94232b31808SJens Wiklander psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
94332b31808SJens Wiklander psa_algorithm_t alg;
94432b31808SJens Wiklander size_t key_bits;
94532b31808SJens Wiklander psa_status_t status = PSA_SUCCESS;
94632b31808SJens Wiklander #endif
94732b31808SJens Wiklander
94832b31808SJens Wiklander #if !defined(MBEDTLS_DEBUG_C)
94932b31808SJens Wiklander ssl = NULL; /* make sure we don't use it except for those cases */
95032b31808SJens Wiklander (void) ssl;
95132b31808SJens Wiklander #endif
95232b31808SJens Wiklander
95332b31808SJens Wiklander ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
95432b31808SJens Wiklander if (ciphersuite_info == NULL) {
95532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found",
95632b31808SJens Wiklander ciphersuite));
95732b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
95832b31808SJens Wiklander }
95932b31808SJens Wiklander
96032b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
96132b31808SJens Wiklander cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher);
96232b31808SJens Wiklander if (cipher_info == NULL) {
96332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found",
96432b31808SJens Wiklander ciphersuite_info->cipher));
96532b31808SJens Wiklander return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
96632b31808SJens Wiklander }
96732b31808SJens Wiklander
96832b31808SJens Wiklander /*
96932b31808SJens Wiklander * Setup cipher contexts in target transform
97032b31808SJens Wiklander */
97132b31808SJens Wiklander if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc,
97232b31808SJens Wiklander cipher_info)) != 0) {
97332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
97432b31808SJens Wiklander return ret;
97532b31808SJens Wiklander }
97632b31808SJens Wiklander
97732b31808SJens Wiklander if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec,
97832b31808SJens Wiklander cipher_info)) != 0) {
97932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
98032b31808SJens Wiklander return ret;
98132b31808SJens Wiklander }
98232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
98332b31808SJens Wiklander
98432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SRV_C)
98532b31808SJens Wiklander if (endpoint == MBEDTLS_SSL_IS_SERVER) {
98632b31808SJens Wiklander key_enc = traffic_keys->server_write_key;
98732b31808SJens Wiklander key_dec = traffic_keys->client_write_key;
98832b31808SJens Wiklander iv_enc = traffic_keys->server_write_iv;
98932b31808SJens Wiklander iv_dec = traffic_keys->client_write_iv;
99032b31808SJens Wiklander } else
99132b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C */
99232b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C)
99332b31808SJens Wiklander if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
99432b31808SJens Wiklander key_enc = traffic_keys->client_write_key;
99532b31808SJens Wiklander key_dec = traffic_keys->server_write_key;
99632b31808SJens Wiklander iv_enc = traffic_keys->client_write_iv;
99732b31808SJens Wiklander iv_dec = traffic_keys->server_write_iv;
99832b31808SJens Wiklander } else
99932b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C */
100032b31808SJens Wiklander {
100132b31808SJens Wiklander /* should not happen */
100232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
100332b31808SJens Wiklander }
100432b31808SJens Wiklander
100532b31808SJens Wiklander memcpy(transform->iv_enc, iv_enc, traffic_keys->iv_len);
100632b31808SJens Wiklander memcpy(transform->iv_dec, iv_dec, traffic_keys->iv_len);
100732b31808SJens Wiklander
100832b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
100932b31808SJens Wiklander if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc,
1010b0563631STom Van Eyck key_enc, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info),
101132b31808SJens Wiklander MBEDTLS_ENCRYPT)) != 0) {
101232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
101332b31808SJens Wiklander return ret;
101432b31808SJens Wiklander }
101532b31808SJens Wiklander
101632b31808SJens Wiklander if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec,
1017b0563631STom Van Eyck key_dec, (int) mbedtls_cipher_info_get_key_bitlen(cipher_info),
101832b31808SJens Wiklander MBEDTLS_DECRYPT)) != 0) {
101932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
102032b31808SJens Wiklander return ret;
102132b31808SJens Wiklander }
102232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
102332b31808SJens Wiklander
102432b31808SJens Wiklander /*
102532b31808SJens Wiklander * Setup other fields in SSL transform
102632b31808SJens Wiklander */
102732b31808SJens Wiklander
102832b31808SJens Wiklander if ((ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) != 0) {
102932b31808SJens Wiklander transform->taglen = 8;
103032b31808SJens Wiklander } else {
103132b31808SJens Wiklander transform->taglen = 16;
103232b31808SJens Wiklander }
103332b31808SJens Wiklander
103432b31808SJens Wiklander transform->ivlen = traffic_keys->iv_len;
103532b31808SJens Wiklander transform->maclen = 0;
103632b31808SJens Wiklander transform->fixed_ivlen = transform->ivlen;
103732b31808SJens Wiklander transform->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;
103832b31808SJens Wiklander
103932b31808SJens Wiklander /* We add the true record content type (1 Byte) to the plaintext and
104032b31808SJens Wiklander * then pad to the configured granularity. The minimum length of the
104132b31808SJens Wiklander * type-extended and padded plaintext is therefore the padding
104232b31808SJens Wiklander * granularity. */
104332b31808SJens Wiklander transform->minlen =
104432b31808SJens Wiklander transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY;
104532b31808SJens Wiklander
104632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
104732b31808SJens Wiklander /*
104832b31808SJens Wiklander * Setup psa keys and alg
104932b31808SJens Wiklander */
1050b0563631STom Van Eyck if ((status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher,
105132b31808SJens Wiklander transform->taglen,
105232b31808SJens Wiklander &alg,
105332b31808SJens Wiklander &key_type,
105432b31808SJens Wiklander &key_bits)) != PSA_SUCCESS) {
1055b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(
1056b0563631STom Van Eyck 1, "mbedtls_ssl_cipher_to_psa", PSA_TO_MBEDTLS_ERR(status));
105732b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
105832b31808SJens Wiklander }
105932b31808SJens Wiklander
106032b31808SJens Wiklander transform->psa_alg = alg;
106132b31808SJens Wiklander
106232b31808SJens Wiklander if (alg != MBEDTLS_SSL_NULL_CIPHER) {
106332b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
106432b31808SJens Wiklander psa_set_key_algorithm(&attributes, alg);
106532b31808SJens Wiklander psa_set_key_type(&attributes, key_type);
106632b31808SJens Wiklander
106732b31808SJens Wiklander if ((status = psa_import_key(&attributes,
106832b31808SJens Wiklander key_enc,
106932b31808SJens Wiklander PSA_BITS_TO_BYTES(key_bits),
107032b31808SJens Wiklander &transform->psa_key_enc)) != PSA_SUCCESS) {
1071b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(
1072b0563631STom Van Eyck 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
107332b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
107432b31808SJens Wiklander }
107532b31808SJens Wiklander
107632b31808SJens Wiklander psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);
107732b31808SJens Wiklander
107832b31808SJens Wiklander if ((status = psa_import_key(&attributes,
107932b31808SJens Wiklander key_dec,
108032b31808SJens Wiklander PSA_BITS_TO_BYTES(key_bits),
108132b31808SJens Wiklander &transform->psa_key_dec)) != PSA_SUCCESS) {
1082b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(
1083b0563631STom Van Eyck 1, "psa_import_key", PSA_TO_MBEDTLS_ERR(status));
108432b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
108532b31808SJens Wiklander }
108632b31808SJens Wiklander }
108732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
108832b31808SJens Wiklander
108932b31808SJens Wiklander return 0;
109032b31808SJens Wiklander }
109132b31808SJens Wiklander
109232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_get_cipher_key_info(const mbedtls_ssl_ciphersuite_t * ciphersuite_info,size_t * key_len,size_t * iv_len)109332b31808SJens Wiklander static int ssl_tls13_get_cipher_key_info(
109432b31808SJens Wiklander const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
109532b31808SJens Wiklander size_t *key_len, size_t *iv_len)
109632b31808SJens Wiklander {
109732b31808SJens Wiklander psa_key_type_t key_type;
109832b31808SJens Wiklander psa_algorithm_t alg;
109932b31808SJens Wiklander size_t taglen;
110032b31808SJens Wiklander size_t key_bits;
110132b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
110232b31808SJens Wiklander
110332b31808SJens Wiklander if (ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) {
110432b31808SJens Wiklander taglen = 8;
110532b31808SJens Wiklander } else {
110632b31808SJens Wiklander taglen = 16;
110732b31808SJens Wiklander }
110832b31808SJens Wiklander
1109b0563631STom Van Eyck status = mbedtls_ssl_cipher_to_psa((mbedtls_cipher_type_t) ciphersuite_info->cipher, taglen,
111032b31808SJens Wiklander &alg, &key_type, &key_bits);
111132b31808SJens Wiklander if (status != PSA_SUCCESS) {
111232b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
111332b31808SJens Wiklander }
111432b31808SJens Wiklander
111532b31808SJens Wiklander *key_len = PSA_BITS_TO_BYTES(key_bits);
111632b31808SJens Wiklander
111732b31808SJens Wiklander /* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */
111832b31808SJens Wiklander *iv_len = 12;
111932b31808SJens Wiklander
112032b31808SJens Wiklander return 0;
112132b31808SJens Wiklander }
112232b31808SJens Wiklander
112332b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
112432b31808SJens Wiklander /*
112532b31808SJens Wiklander * ssl_tls13_generate_early_key() generates the key necessary for protecting
112632b31808SJens Wiklander * the early application data and handshake messages as described in section 7
112732b31808SJens Wiklander * of RFC 8446.
112832b31808SJens Wiklander *
112932b31808SJens Wiklander * NOTE: Only one key is generated, the key for the traffic from the client to
113032b31808SJens Wiklander * the server. The TLS 1.3 specification does not define a secret and thus
113132b31808SJens Wiklander * a key for server early traffic.
113232b31808SJens Wiklander */
113332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_generate_early_key(mbedtls_ssl_context * ssl,mbedtls_ssl_key_set * traffic_keys)113432b31808SJens Wiklander static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
113532b31808SJens Wiklander mbedtls_ssl_key_set *traffic_keys)
113632b31808SJens Wiklander {
113732b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
113832b31808SJens Wiklander mbedtls_md_type_t md_type;
113932b31808SJens Wiklander psa_algorithm_t hash_alg;
114032b31808SJens Wiklander size_t hash_len;
114132b31808SJens Wiklander unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
114232b31808SJens Wiklander size_t transcript_len;
1143b0563631STom Van Eyck size_t key_len = 0;
1144b0563631STom Van Eyck size_t iv_len = 0;
114532b31808SJens Wiklander mbedtls_ssl_tls13_early_secrets tls13_early_secrets;
114632b31808SJens Wiklander
114732b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1148b0563631STom Van Eyck const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
1149b0563631STom Van Eyck handshake->ciphersuite_info;
115032b31808SJens Wiklander
115132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key"));
115232b31808SJens Wiklander
115332b31808SJens Wiklander ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len);
115432b31808SJens Wiklander if (ret != 0) {
115532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
115632b31808SJens Wiklander goto cleanup;
115732b31808SJens Wiklander }
115832b31808SJens Wiklander
1159b0563631STom Van Eyck md_type = (mbedtls_md_type_t) ciphersuite_info->mac;
116032b31808SJens Wiklander
1161b0563631STom Van Eyck hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
116232b31808SJens Wiklander hash_len = PSA_HASH_LENGTH(hash_alg);
116332b31808SJens Wiklander
116432b31808SJens Wiklander ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
116532b31808SJens Wiklander transcript,
116632b31808SJens Wiklander sizeof(transcript),
116732b31808SJens Wiklander &transcript_len);
116832b31808SJens Wiklander if (ret != 0) {
116932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1,
117032b31808SJens Wiklander "mbedtls_ssl_get_handshake_transcript",
117132b31808SJens Wiklander ret);
117232b31808SJens Wiklander goto cleanup;
117332b31808SJens Wiklander }
117432b31808SJens Wiklander
117532b31808SJens Wiklander ret = mbedtls_ssl_tls13_derive_early_secrets(
117632b31808SJens Wiklander hash_alg, handshake->tls13_master_secrets.early,
117732b31808SJens Wiklander transcript, transcript_len, &tls13_early_secrets);
117832b31808SJens Wiklander if (ret != 0) {
117932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(
118032b31808SJens Wiklander 1, "mbedtls_ssl_tls13_derive_early_secrets", ret);
118132b31808SJens Wiklander goto cleanup;
118232b31808SJens Wiklander }
118332b31808SJens Wiklander
118432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(
118532b31808SJens Wiklander 4, "Client early traffic secret",
118632b31808SJens Wiklander tls13_early_secrets.client_early_traffic_secret, hash_len);
118732b31808SJens Wiklander
118832b31808SJens Wiklander /*
118932b31808SJens Wiklander * Export client handshake traffic secret
119032b31808SJens Wiklander */
119132b31808SJens Wiklander if (ssl->f_export_keys != NULL) {
119232b31808SJens Wiklander ssl->f_export_keys(
119332b31808SJens Wiklander ssl->p_export_keys,
119432b31808SJens Wiklander MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET,
119532b31808SJens Wiklander tls13_early_secrets.client_early_traffic_secret,
119632b31808SJens Wiklander hash_len,
119732b31808SJens Wiklander handshake->randbytes,
119832b31808SJens Wiklander handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
119932b31808SJens Wiklander MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
120032b31808SJens Wiklander }
120132b31808SJens Wiklander
120232b31808SJens Wiklander ret = ssl_tls13_make_traffic_key(
120332b31808SJens Wiklander hash_alg,
120432b31808SJens Wiklander tls13_early_secrets.client_early_traffic_secret,
120532b31808SJens Wiklander hash_len, traffic_keys->client_write_key, key_len,
120632b31808SJens Wiklander traffic_keys->client_write_iv, iv_len);
120732b31808SJens Wiklander if (ret != 0) {
120832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_make_traffic_key", ret);
120932b31808SJens Wiklander goto cleanup;
121032b31808SJens Wiklander }
121132b31808SJens Wiklander traffic_keys->key_len = key_len;
121232b31808SJens Wiklander traffic_keys->iv_len = iv_len;
121332b31808SJens Wiklander
121432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client early write_key",
121532b31808SJens Wiklander traffic_keys->client_write_key,
121632b31808SJens Wiklander traffic_keys->key_len);
121732b31808SJens Wiklander
121832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client early write_iv",
121932b31808SJens Wiklander traffic_keys->client_write_iv,
122032b31808SJens Wiklander traffic_keys->iv_len);
122132b31808SJens Wiklander
122232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_early_key"));
122332b31808SJens Wiklander
122432b31808SJens Wiklander cleanup:
122532b31808SJens Wiklander /* Erase early secrets and transcript */
122632b31808SJens Wiklander mbedtls_platform_zeroize(
122732b31808SJens Wiklander &tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets));
122832b31808SJens Wiklander mbedtls_platform_zeroize(transcript, sizeof(transcript));
122932b31808SJens Wiklander return ret;
123032b31808SJens Wiklander }
123132b31808SJens Wiklander
mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context * ssl)123232b31808SJens Wiklander int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl)
123332b31808SJens Wiklander {
123432b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
123532b31808SJens Wiklander mbedtls_ssl_key_set traffic_keys;
123632b31808SJens Wiklander mbedtls_ssl_transform *transform_earlydata = NULL;
123732b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
123832b31808SJens Wiklander
123932b31808SJens Wiklander /* Next evolution in key schedule: Establish early_data secret and
124032b31808SJens Wiklander * key material. */
124132b31808SJens Wiklander ret = ssl_tls13_generate_early_key(ssl, &traffic_keys);
124232b31808SJens Wiklander if (ret != 0) {
124332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_early_key",
124432b31808SJens Wiklander ret);
124532b31808SJens Wiklander goto cleanup;
124632b31808SJens Wiklander }
124732b31808SJens Wiklander
124832b31808SJens Wiklander transform_earlydata = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
124932b31808SJens Wiklander if (transform_earlydata == NULL) {
125032b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
125132b31808SJens Wiklander goto cleanup;
125232b31808SJens Wiklander }
125332b31808SJens Wiklander
125432b31808SJens Wiklander ret = mbedtls_ssl_tls13_populate_transform(
125532b31808SJens Wiklander transform_earlydata,
125632b31808SJens Wiklander ssl->conf->endpoint,
125732b31808SJens Wiklander handshake->ciphersuite_info->id,
125832b31808SJens Wiklander &traffic_keys,
125932b31808SJens Wiklander ssl);
126032b31808SJens Wiklander if (ret != 0) {
126132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
126232b31808SJens Wiklander goto cleanup;
126332b31808SJens Wiklander }
126432b31808SJens Wiklander handshake->transform_earlydata = transform_earlydata;
126532b31808SJens Wiklander
126632b31808SJens Wiklander cleanup:
126732b31808SJens Wiklander mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
126832b31808SJens Wiklander if (ret != 0) {
126932b31808SJens Wiklander mbedtls_free(transform_earlydata);
127032b31808SJens Wiklander }
127132b31808SJens Wiklander
127232b31808SJens Wiklander return ret;
127332b31808SJens Wiklander }
127432b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
127532b31808SJens Wiklander
mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context * ssl)127632b31808SJens Wiklander int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl)
127732b31808SJens Wiklander {
127832b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
127932b31808SJens Wiklander psa_algorithm_t hash_alg;
128032b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
128132b31808SJens Wiklander unsigned char *psk = NULL;
128232b31808SJens Wiklander size_t psk_len = 0;
128332b31808SJens Wiklander
128432b31808SJens Wiklander if (handshake->ciphersuite_info == NULL) {
128532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("cipher suite info not found"));
128632b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
128732b31808SJens Wiklander }
128832b31808SJens Wiklander
1289b0563631STom Van Eyck hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac);
129032b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
129132b31808SJens Wiklander if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
129232b31808SJens Wiklander ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len);
129332b31808SJens Wiklander if (ret != 0) {
129432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_export_handshake_psk",
129532b31808SJens Wiklander ret);
129632b31808SJens Wiklander return ret;
129732b31808SJens Wiklander }
129832b31808SJens Wiklander }
129932b31808SJens Wiklander #endif
130032b31808SJens Wiklander
130132b31808SJens Wiklander ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, NULL, psk, psk_len,
130232b31808SJens Wiklander handshake->tls13_master_secrets.early);
130332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) && \
130432b31808SJens Wiklander defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
130532b31808SJens Wiklander mbedtls_free((void *) psk);
130632b31808SJens Wiklander #endif
130732b31808SJens Wiklander if (ret != 0) {
130832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
130932b31808SJens Wiklander return ret;
131032b31808SJens Wiklander }
131132b31808SJens Wiklander
131232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_key_schedule_stage_early",
131332b31808SJens Wiklander handshake->tls13_master_secrets.early,
131432b31808SJens Wiklander PSA_HASH_LENGTH(hash_alg));
131532b31808SJens Wiklander return 0;
131632b31808SJens Wiklander }
131732b31808SJens Wiklander
131832b31808SJens Wiklander /**
131932b31808SJens Wiklander * \brief Compute TLS 1.3 handshake traffic keys.
132032b31808SJens Wiklander *
132132b31808SJens Wiklander * ssl_tls13_generate_handshake_keys() generates keys necessary for
132232b31808SJens Wiklander * protecting the handshake messages, as described in Section 7 of
132332b31808SJens Wiklander * RFC 8446.
132432b31808SJens Wiklander *
132532b31808SJens Wiklander * \param ssl The SSL context to operate on. This must be in
132632b31808SJens Wiklander * key schedule stage \c Handshake, see
132732b31808SJens Wiklander * ssl_tls13_key_schedule_stage_handshake().
132832b31808SJens Wiklander * \param traffic_keys The address at which to store the handshake traffic
132932b31808SJens Wiklander * keys. This must be writable but may be uninitialized.
133032b31808SJens Wiklander *
133132b31808SJens Wiklander * \returns \c 0 on success.
133232b31808SJens Wiklander * \returns A negative error code on failure.
133332b31808SJens Wiklander */
133432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_generate_handshake_keys(mbedtls_ssl_context * ssl,mbedtls_ssl_key_set * traffic_keys)133532b31808SJens Wiklander static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
133632b31808SJens Wiklander mbedtls_ssl_key_set *traffic_keys)
133732b31808SJens Wiklander {
133832b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
133932b31808SJens Wiklander mbedtls_md_type_t md_type;
134032b31808SJens Wiklander psa_algorithm_t hash_alg;
134132b31808SJens Wiklander size_t hash_len;
134232b31808SJens Wiklander unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
134332b31808SJens Wiklander size_t transcript_len;
1344b0563631STom Van Eyck size_t key_len = 0;
1345b0563631STom Van Eyck size_t iv_len = 0;
134632b31808SJens Wiklander
134732b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1348b0563631STom Van Eyck const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
1349b0563631STom Van Eyck handshake->ciphersuite_info;
1350b0563631STom Van Eyck mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets =
1351b0563631STom Van Eyck &handshake->tls13_hs_secrets;
135232b31808SJens Wiklander
135332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys"));
135432b31808SJens Wiklander
135532b31808SJens Wiklander ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len);
135632b31808SJens Wiklander if (ret != 0) {
135732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
135832b31808SJens Wiklander return ret;
135932b31808SJens Wiklander }
136032b31808SJens Wiklander
1361b0563631STom Van Eyck md_type = (mbedtls_md_type_t) ciphersuite_info->mac;
136232b31808SJens Wiklander
1363b0563631STom Van Eyck hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
136432b31808SJens Wiklander hash_len = PSA_HASH_LENGTH(hash_alg);
136532b31808SJens Wiklander
136632b31808SJens Wiklander ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
136732b31808SJens Wiklander transcript,
136832b31808SJens Wiklander sizeof(transcript),
136932b31808SJens Wiklander &transcript_len);
137032b31808SJens Wiklander if (ret != 0) {
137132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1,
137232b31808SJens Wiklander "mbedtls_ssl_get_handshake_transcript",
137332b31808SJens Wiklander ret);
137432b31808SJens Wiklander return ret;
137532b31808SJens Wiklander }
137632b31808SJens Wiklander
1377b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_handshake_secrets(
1378b0563631STom Van Eyck hash_alg, handshake->tls13_master_secrets.handshake,
137932b31808SJens Wiklander transcript, transcript_len, tls13_hs_secrets);
138032b31808SJens Wiklander if (ret != 0) {
138132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_handshake_secrets",
138232b31808SJens Wiklander ret);
138332b31808SJens Wiklander return ret;
138432b31808SJens Wiklander }
138532b31808SJens Wiklander
138632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "Client handshake traffic secret",
138732b31808SJens Wiklander tls13_hs_secrets->client_handshake_traffic_secret,
138832b31808SJens Wiklander hash_len);
138932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "Server handshake traffic secret",
139032b31808SJens Wiklander tls13_hs_secrets->server_handshake_traffic_secret,
139132b31808SJens Wiklander hash_len);
139232b31808SJens Wiklander
139332b31808SJens Wiklander /*
139432b31808SJens Wiklander * Export client handshake traffic secret
139532b31808SJens Wiklander */
139632b31808SJens Wiklander if (ssl->f_export_keys != NULL) {
1397b0563631STom Van Eyck ssl->f_export_keys(
1398b0563631STom Van Eyck ssl->p_export_keys,
139932b31808SJens Wiklander MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
140032b31808SJens Wiklander tls13_hs_secrets->client_handshake_traffic_secret,
140132b31808SJens Wiklander hash_len,
140232b31808SJens Wiklander handshake->randbytes,
140332b31808SJens Wiklander handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
140432b31808SJens Wiklander MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
140532b31808SJens Wiklander
1406b0563631STom Van Eyck ssl->f_export_keys(
1407b0563631STom Van Eyck ssl->p_export_keys,
140832b31808SJens Wiklander MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET,
140932b31808SJens Wiklander tls13_hs_secrets->server_handshake_traffic_secret,
141032b31808SJens Wiklander hash_len,
141132b31808SJens Wiklander handshake->randbytes,
141232b31808SJens Wiklander handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
141332b31808SJens Wiklander MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
141432b31808SJens Wiklander }
141532b31808SJens Wiklander
1416b0563631STom Van Eyck ret = mbedtls_ssl_tls13_make_traffic_keys(
1417b0563631STom Van Eyck hash_alg,
141832b31808SJens Wiklander tls13_hs_secrets->client_handshake_traffic_secret,
141932b31808SJens Wiklander tls13_hs_secrets->server_handshake_traffic_secret,
142032b31808SJens Wiklander hash_len, key_len, iv_len, traffic_keys);
142132b31808SJens Wiklander if (ret != 0) {
142232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
142332b31808SJens Wiklander goto exit;
142432b31808SJens Wiklander }
142532b31808SJens Wiklander
142632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_key",
142732b31808SJens Wiklander traffic_keys->client_write_key,
142832b31808SJens Wiklander traffic_keys->key_len);
142932b31808SJens Wiklander
143032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_key",
143132b31808SJens Wiklander traffic_keys->server_write_key,
143232b31808SJens Wiklander traffic_keys->key_len);
143332b31808SJens Wiklander
143432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_iv",
143532b31808SJens Wiklander traffic_keys->client_write_iv,
143632b31808SJens Wiklander traffic_keys->iv_len);
143732b31808SJens Wiklander
143832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_iv",
143932b31808SJens Wiklander traffic_keys->server_write_iv,
144032b31808SJens Wiklander traffic_keys->iv_len);
144132b31808SJens Wiklander
144232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_handshake_keys"));
144332b31808SJens Wiklander
144432b31808SJens Wiklander exit:
144532b31808SJens Wiklander
144632b31808SJens Wiklander return ret;
144732b31808SJens Wiklander }
144832b31808SJens Wiklander
144932b31808SJens Wiklander /**
145032b31808SJens Wiklander * \brief Transition into handshake stage of TLS 1.3 key schedule.
145132b31808SJens Wiklander *
145232b31808SJens Wiklander * The TLS 1.3 key schedule can be viewed as a simple state machine
145332b31808SJens Wiklander * with states Initial -> Early -> Handshake -> Application, and
145432b31808SJens Wiklander * this function represents the Early -> Handshake transition.
145532b31808SJens Wiklander *
145632b31808SJens Wiklander * In the handshake stage, ssl_tls13_generate_handshake_keys()
145732b31808SJens Wiklander * can be used to derive the handshake traffic keys.
145832b31808SJens Wiklander *
145932b31808SJens Wiklander * \param ssl The SSL context to operate on. This must be in key schedule
146032b31808SJens Wiklander * stage \c Early.
146132b31808SJens Wiklander *
146232b31808SJens Wiklander * \returns \c 0 on success.
146332b31808SJens Wiklander * \returns A negative error code on failure.
146432b31808SJens Wiklander */
146532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context * ssl)146632b31808SJens Wiklander static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
146732b31808SJens Wiklander {
146832b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
146932b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1470b0563631STom Van Eyck psa_algorithm_t const hash_alg = mbedtls_md_psa_alg_from_type(
1471b0563631STom Van Eyck (mbedtls_md_type_t) handshake->ciphersuite_info->mac);
147232b31808SJens Wiklander unsigned char *shared_secret = NULL;
147332b31808SJens Wiklander size_t shared_secret_len = 0;
147432b31808SJens Wiklander
147532b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
147632b31808SJens Wiklander /*
147732b31808SJens Wiklander * Compute ECDHE secret used to compute the handshake secret from which
147832b31808SJens Wiklander * client_handshake_traffic_secret and server_handshake_traffic_secret
147932b31808SJens Wiklander * are derived in the handshake secret derivation stage.
148032b31808SJens Wiklander */
148132b31808SJens Wiklander if (mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) {
1482b0563631STom Van Eyck if (mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) ||
1483b0563631STom Van Eyck mbedtls_ssl_tls13_named_group_is_ffdh(handshake->offered_group_id)) {
1484b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
1485b0563631STom Van Eyck psa_algorithm_t alg =
1486b0563631STom Van Eyck mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id) ?
1487b0563631STom Van Eyck PSA_ALG_ECDH : PSA_ALG_FFDH;
1488b0563631STom Van Eyck
148932b31808SJens Wiklander /* Compute ECDH shared secret. */
149032b31808SJens Wiklander psa_status_t status = PSA_ERROR_GENERIC_ERROR;
149132b31808SJens Wiklander psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
149232b31808SJens Wiklander
1493b0563631STom Van Eyck status = psa_get_key_attributes(handshake->xxdh_psa_privkey,
149432b31808SJens Wiklander &key_attributes);
149532b31808SJens Wiklander if (status != PSA_SUCCESS) {
149632b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
149732b31808SJens Wiklander }
149832b31808SJens Wiklander
149932b31808SJens Wiklander shared_secret_len = PSA_BITS_TO_BYTES(
150032b31808SJens Wiklander psa_get_key_bits(&key_attributes));
150132b31808SJens Wiklander shared_secret = mbedtls_calloc(1, shared_secret_len);
150232b31808SJens Wiklander if (shared_secret == NULL) {
150332b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED;
150432b31808SJens Wiklander }
150532b31808SJens Wiklander
150632b31808SJens Wiklander status = psa_raw_key_agreement(
1507b0563631STom Van Eyck alg, handshake->xxdh_psa_privkey,
1508b0563631STom Van Eyck handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
150932b31808SJens Wiklander shared_secret, shared_secret_len, &shared_secret_len);
151032b31808SJens Wiklander if (status != PSA_SUCCESS) {
151132b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
151232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
151332b31808SJens Wiklander goto cleanup;
151432b31808SJens Wiklander }
151532b31808SJens Wiklander
1516b0563631STom Van Eyck status = psa_destroy_key(handshake->xxdh_psa_privkey);
151732b31808SJens Wiklander if (status != PSA_SUCCESS) {
151832b31808SJens Wiklander ret = PSA_TO_MBEDTLS_ERR(status);
151932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
152032b31808SJens Wiklander goto cleanup;
152132b31808SJens Wiklander }
152232b31808SJens Wiklander
1523b0563631STom Van Eyck handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
1524b0563631STom Van Eyck #endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
152532b31808SJens Wiklander } else {
152632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(1, ("Group not supported."));
152732b31808SJens Wiklander return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
152832b31808SJens Wiklander }
152932b31808SJens Wiklander }
153032b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
153132b31808SJens Wiklander
153232b31808SJens Wiklander /*
153332b31808SJens Wiklander * Compute the Handshake Secret
153432b31808SJens Wiklander */
1535b0563631STom Van Eyck ret = mbedtls_ssl_tls13_evolve_secret(
1536b0563631STom Van Eyck hash_alg, handshake->tls13_master_secrets.early,
153732b31808SJens Wiklander shared_secret, shared_secret_len,
153832b31808SJens Wiklander handshake->tls13_master_secrets.handshake);
153932b31808SJens Wiklander if (ret != 0) {
154032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
154132b31808SJens Wiklander goto cleanup;
154232b31808SJens Wiklander }
154332b31808SJens Wiklander
154432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "Handshake secret",
154532b31808SJens Wiklander handshake->tls13_master_secrets.handshake,
154632b31808SJens Wiklander PSA_HASH_LENGTH(hash_alg));
154732b31808SJens Wiklander
154832b31808SJens Wiklander cleanup:
154932b31808SJens Wiklander if (shared_secret != NULL) {
1550b0563631STom Van Eyck mbedtls_zeroize_and_free(shared_secret, shared_secret_len);
155132b31808SJens Wiklander }
155232b31808SJens Wiklander
155332b31808SJens Wiklander return ret;
155432b31808SJens Wiklander }
155532b31808SJens Wiklander
155632b31808SJens Wiklander /**
155732b31808SJens Wiklander * \brief Compute TLS 1.3 application traffic keys.
155832b31808SJens Wiklander *
155932b31808SJens Wiklander * ssl_tls13_generate_application_keys() generates application traffic
156032b31808SJens Wiklander * keys, since any record following a 1-RTT Finished message MUST be
156132b31808SJens Wiklander * encrypted under the application traffic key.
156232b31808SJens Wiklander *
156332b31808SJens Wiklander * \param ssl The SSL context to operate on. This must be in
156432b31808SJens Wiklander * key schedule stage \c Application, see
156532b31808SJens Wiklander * ssl_tls13_key_schedule_stage_application().
156632b31808SJens Wiklander * \param traffic_keys The address at which to store the application traffic
156732b31808SJens Wiklander * keys. This must be writable but may be uninitialized.
156832b31808SJens Wiklander *
156932b31808SJens Wiklander * \returns \c 0 on success.
157032b31808SJens Wiklander * \returns A negative error code on failure.
157132b31808SJens Wiklander */
157232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_generate_application_keys(mbedtls_ssl_context * ssl,mbedtls_ssl_key_set * traffic_keys)157332b31808SJens Wiklander static int ssl_tls13_generate_application_keys(
157432b31808SJens Wiklander mbedtls_ssl_context *ssl,
157532b31808SJens Wiklander mbedtls_ssl_key_set *traffic_keys)
157632b31808SJens Wiklander {
157732b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
157832b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
157932b31808SJens Wiklander
158032b31808SJens Wiklander /* Address at which to store the application secrets */
158132b31808SJens Wiklander mbedtls_ssl_tls13_application_secrets * const app_secrets =
158232b31808SJens Wiklander &ssl->session_negotiate->app_secrets;
158332b31808SJens Wiklander
158432b31808SJens Wiklander /* Holding the transcript up to and including the ServerFinished */
158532b31808SJens Wiklander unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
158632b31808SJens Wiklander size_t transcript_len;
158732b31808SJens Wiklander
158832b31808SJens Wiklander /* Variables relating to the hash for the chosen ciphersuite. */
158932b31808SJens Wiklander mbedtls_md_type_t md_type;
159032b31808SJens Wiklander
159132b31808SJens Wiklander psa_algorithm_t hash_alg;
159232b31808SJens Wiklander size_t hash_len;
159332b31808SJens Wiklander
159432b31808SJens Wiklander /* Variables relating to the cipher for the chosen ciphersuite. */
1595b0563631STom Van Eyck size_t key_len = 0, iv_len = 0;
159632b31808SJens Wiklander
159732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive application traffic keys"));
159832b31808SJens Wiklander
159932b31808SJens Wiklander /* Extract basic information about hash and ciphersuite */
160032b31808SJens Wiklander
160132b31808SJens Wiklander ret = ssl_tls13_get_cipher_key_info(handshake->ciphersuite_info,
160232b31808SJens Wiklander &key_len, &iv_len);
160332b31808SJens Wiklander if (ret != 0) {
160432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
160532b31808SJens Wiklander goto cleanup;
160632b31808SJens Wiklander }
160732b31808SJens Wiklander
1608b0563631STom Van Eyck md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac;
160932b31808SJens Wiklander
1610b0563631STom Van Eyck hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) handshake->ciphersuite_info->mac);
161132b31808SJens Wiklander hash_len = PSA_HASH_LENGTH(hash_alg);
161232b31808SJens Wiklander
161332b31808SJens Wiklander /* Compute current handshake transcript. It's the caller's responsibility
161432b31808SJens Wiklander * to call this at the right time, that is, after the ServerFinished. */
161532b31808SJens Wiklander
161632b31808SJens Wiklander ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
161732b31808SJens Wiklander transcript, sizeof(transcript),
161832b31808SJens Wiklander &transcript_len);
161932b31808SJens Wiklander if (ret != 0) {
162032b31808SJens Wiklander goto cleanup;
162132b31808SJens Wiklander }
162232b31808SJens Wiklander
162332b31808SJens Wiklander /* Compute application secrets from master secret and transcript hash. */
162432b31808SJens Wiklander
1625b0563631STom Van Eyck ret = mbedtls_ssl_tls13_derive_application_secrets(
1626b0563631STom Van Eyck hash_alg, handshake->tls13_master_secrets.app,
1627b0563631STom Van Eyck transcript, transcript_len, app_secrets);
162832b31808SJens Wiklander if (ret != 0) {
1629b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_RET(
1630b0563631STom Van Eyck 1, "mbedtls_ssl_tls13_derive_application_secrets", ret);
163132b31808SJens Wiklander goto cleanup;
163232b31808SJens Wiklander }
163332b31808SJens Wiklander
163432b31808SJens Wiklander /* Derive first epoch of IV + Key for application traffic. */
163532b31808SJens Wiklander
1636b0563631STom Van Eyck ret = mbedtls_ssl_tls13_make_traffic_keys(
1637b0563631STom Van Eyck hash_alg,
163832b31808SJens Wiklander app_secrets->client_application_traffic_secret_N,
163932b31808SJens Wiklander app_secrets->server_application_traffic_secret_N,
164032b31808SJens Wiklander hash_len, key_len, iv_len, traffic_keys);
164132b31808SJens Wiklander if (ret != 0) {
164232b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
164332b31808SJens Wiklander goto cleanup;
164432b31808SJens Wiklander }
164532b31808SJens Wiklander
164632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "Client application traffic secret",
164732b31808SJens Wiklander app_secrets->client_application_traffic_secret_N,
164832b31808SJens Wiklander hash_len);
164932b31808SJens Wiklander
165032b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "Server application traffic secret",
165132b31808SJens Wiklander app_secrets->server_application_traffic_secret_N,
165232b31808SJens Wiklander hash_len);
165332b31808SJens Wiklander
165432b31808SJens Wiklander /*
165532b31808SJens Wiklander * Export client/server application traffic secret 0
165632b31808SJens Wiklander */
165732b31808SJens Wiklander if (ssl->f_export_keys != NULL) {
1658b0563631STom Van Eyck ssl->f_export_keys(
1659b0563631STom Van Eyck ssl->p_export_keys,
166032b31808SJens Wiklander MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET,
166132b31808SJens Wiklander app_secrets->client_application_traffic_secret_N, hash_len,
166232b31808SJens Wiklander handshake->randbytes,
166332b31808SJens Wiklander handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
166432b31808SJens Wiklander MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
166532b31808SJens Wiklander a new constant for TLS 1.3! */);
166632b31808SJens Wiklander
1667b0563631STom Van Eyck ssl->f_export_keys(
1668b0563631STom Van Eyck ssl->p_export_keys,
166932b31808SJens Wiklander MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET,
167032b31808SJens Wiklander app_secrets->server_application_traffic_secret_N, hash_len,
167132b31808SJens Wiklander handshake->randbytes,
167232b31808SJens Wiklander handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
167332b31808SJens Wiklander MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
167432b31808SJens Wiklander a new constant for TLS 1.3! */);
167532b31808SJens Wiklander }
167632b31808SJens Wiklander
167732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client application_write_key:",
167832b31808SJens Wiklander traffic_keys->client_write_key, key_len);
167932b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "server application write key",
168032b31808SJens Wiklander traffic_keys->server_write_key, key_len);
168132b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "client application write IV",
168232b31808SJens Wiklander traffic_keys->client_write_iv, iv_len);
168332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_BUF(4, "server application write IV",
168432b31808SJens Wiklander traffic_keys->server_write_iv, iv_len);
168532b31808SJens Wiklander
168632b31808SJens Wiklander MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive application traffic keys"));
168732b31808SJens Wiklander
168832b31808SJens Wiklander cleanup:
168932b31808SJens Wiklander /* randbytes is not used again */
169032b31808SJens Wiklander mbedtls_platform_zeroize(ssl->handshake->randbytes,
169132b31808SJens Wiklander sizeof(ssl->handshake->randbytes));
169232b31808SJens Wiklander
169332b31808SJens Wiklander mbedtls_platform_zeroize(transcript, sizeof(transcript));
169432b31808SJens Wiklander return ret;
169532b31808SJens Wiklander }
169632b31808SJens Wiklander
mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context * ssl)169732b31808SJens Wiklander int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl)
169832b31808SJens Wiklander {
169932b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
170032b31808SJens Wiklander mbedtls_ssl_key_set traffic_keys;
170132b31808SJens Wiklander mbedtls_ssl_transform *transform_handshake = NULL;
170232b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
170332b31808SJens Wiklander
170432b31808SJens Wiklander /* Compute handshake secret */
170532b31808SJens Wiklander ret = ssl_tls13_key_schedule_stage_handshake(ssl);
170632b31808SJens Wiklander if (ret != 0) {
170732b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_master_secret", ret);
170832b31808SJens Wiklander goto cleanup;
170932b31808SJens Wiklander }
171032b31808SJens Wiklander
171132b31808SJens Wiklander /* Next evolution in key schedule: Establish handshake secret and
171232b31808SJens Wiklander * key material. */
171332b31808SJens Wiklander ret = ssl_tls13_generate_handshake_keys(ssl, &traffic_keys);
171432b31808SJens Wiklander if (ret != 0) {
171532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_handshake_keys",
171632b31808SJens Wiklander ret);
171732b31808SJens Wiklander goto cleanup;
171832b31808SJens Wiklander }
171932b31808SJens Wiklander
172032b31808SJens Wiklander transform_handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
172132b31808SJens Wiklander if (transform_handshake == NULL) {
172232b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
172332b31808SJens Wiklander goto cleanup;
172432b31808SJens Wiklander }
172532b31808SJens Wiklander
172632b31808SJens Wiklander ret = mbedtls_ssl_tls13_populate_transform(
172732b31808SJens Wiklander transform_handshake,
172832b31808SJens Wiklander ssl->conf->endpoint,
172932b31808SJens Wiklander handshake->ciphersuite_info->id,
173032b31808SJens Wiklander &traffic_keys,
173132b31808SJens Wiklander ssl);
173232b31808SJens Wiklander if (ret != 0) {
173332b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
173432b31808SJens Wiklander goto cleanup;
173532b31808SJens Wiklander }
173632b31808SJens Wiklander handshake->transform_handshake = transform_handshake;
173732b31808SJens Wiklander
173832b31808SJens Wiklander cleanup:
173932b31808SJens Wiklander mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
174032b31808SJens Wiklander if (ret != 0) {
174132b31808SJens Wiklander mbedtls_free(transform_handshake);
174232b31808SJens Wiklander }
174332b31808SJens Wiklander
174432b31808SJens Wiklander return ret;
174532b31808SJens Wiklander }
174632b31808SJens Wiklander
mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context * ssl)174732b31808SJens Wiklander int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
174832b31808SJens Wiklander {
174932b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
175032b31808SJens Wiklander mbedtls_md_type_t md_type;
175132b31808SJens Wiklander mbedtls_ssl_handshake_params *handshake = ssl->handshake;
175232b31808SJens Wiklander unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
175332b31808SJens Wiklander size_t transcript_len;
175432b31808SJens Wiklander
1755b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(
1756b0563631STom Van Eyck 2, ("=> mbedtls_ssl_tls13_compute_resumption_master_secret"));
175732b31808SJens Wiklander
1758b0563631STom Van Eyck md_type = (mbedtls_md_type_t) handshake->ciphersuite_info->mac;
175932b31808SJens Wiklander
176032b31808SJens Wiklander ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
176132b31808SJens Wiklander transcript, sizeof(transcript),
176232b31808SJens Wiklander &transcript_len);
176332b31808SJens Wiklander if (ret != 0) {
176432b31808SJens Wiklander return ret;
176532b31808SJens Wiklander }
176632b31808SJens Wiklander
176732b31808SJens Wiklander ret = mbedtls_ssl_tls13_derive_resumption_master_secret(
1768b0563631STom Van Eyck mbedtls_md_psa_alg_from_type(md_type),
176932b31808SJens Wiklander handshake->tls13_master_secrets.app,
177032b31808SJens Wiklander transcript, transcript_len,
177132b31808SJens Wiklander &ssl->session_negotiate->app_secrets);
177232b31808SJens Wiklander if (ret != 0) {
177332b31808SJens Wiklander return ret;
177432b31808SJens Wiklander }
177532b31808SJens Wiklander
177632b31808SJens Wiklander /* Erase master secrets */
177732b31808SJens Wiklander mbedtls_platform_zeroize(&handshake->tls13_master_secrets,
177832b31808SJens Wiklander sizeof(handshake->tls13_master_secrets));
177932b31808SJens Wiklander
1780b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_BUF(
1781b0563631STom Van Eyck 4, "Resumption master secret",
178232b31808SJens Wiklander ssl->session_negotiate->app_secrets.resumption_master_secret,
1783b0563631STom Van Eyck PSA_HASH_LENGTH(mbedtls_md_psa_alg_from_type(md_type)));
178432b31808SJens Wiklander
1785b0563631STom Van Eyck MBEDTLS_SSL_DEBUG_MSG(
1786b0563631STom Van Eyck 2, ("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));
178732b31808SJens Wiklander return 0;
178832b31808SJens Wiklander }
178932b31808SJens Wiklander
mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context * ssl)179032b31808SJens Wiklander int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl)
179132b31808SJens Wiklander {
179232b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
179332b31808SJens Wiklander mbedtls_ssl_key_set traffic_keys;
179432b31808SJens Wiklander mbedtls_ssl_transform *transform_application = NULL;
179532b31808SJens Wiklander
179632b31808SJens Wiklander ret = ssl_tls13_key_schedule_stage_application(ssl);
179732b31808SJens Wiklander if (ret != 0) {
179832b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1,
179932b31808SJens Wiklander "ssl_tls13_key_schedule_stage_application", ret);
180032b31808SJens Wiklander goto cleanup;
180132b31808SJens Wiklander }
180232b31808SJens Wiklander
180332b31808SJens Wiklander ret = ssl_tls13_generate_application_keys(ssl, &traffic_keys);
180432b31808SJens Wiklander if (ret != 0) {
180532b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1,
180632b31808SJens Wiklander "ssl_tls13_generate_application_keys", ret);
180732b31808SJens Wiklander goto cleanup;
180832b31808SJens Wiklander }
180932b31808SJens Wiklander
181032b31808SJens Wiklander transform_application =
181132b31808SJens Wiklander mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
181232b31808SJens Wiklander if (transform_application == NULL) {
181332b31808SJens Wiklander ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
181432b31808SJens Wiklander goto cleanup;
181532b31808SJens Wiklander }
181632b31808SJens Wiklander
181732b31808SJens Wiklander ret = mbedtls_ssl_tls13_populate_transform(
181832b31808SJens Wiklander transform_application,
181932b31808SJens Wiklander ssl->conf->endpoint,
182032b31808SJens Wiklander ssl->handshake->ciphersuite_info->id,
182132b31808SJens Wiklander &traffic_keys,
182232b31808SJens Wiklander ssl);
182332b31808SJens Wiklander if (ret != 0) {
182432b31808SJens Wiklander MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
182532b31808SJens Wiklander goto cleanup;
182632b31808SJens Wiklander }
182732b31808SJens Wiklander
182832b31808SJens Wiklander ssl->transform_application = transform_application;
182932b31808SJens Wiklander
183032b31808SJens Wiklander cleanup:
183132b31808SJens Wiklander
183232b31808SJens Wiklander mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
183332b31808SJens Wiklander if (ret != 0) {
183432b31808SJens Wiklander mbedtls_free(transform_application);
183532b31808SJens Wiklander }
183632b31808SJens Wiklander return ret;
183732b31808SJens Wiklander }
183832b31808SJens Wiklander
183932b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context * ssl,unsigned char ** psk,size_t * psk_len)184032b31808SJens Wiklander int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl,
184132b31808SJens Wiklander unsigned char **psk,
184232b31808SJens Wiklander size_t *psk_len)
184332b31808SJens Wiklander {
184432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
184532b31808SJens Wiklander psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
184632b31808SJens Wiklander psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
184732b31808SJens Wiklander
184832b31808SJens Wiklander *psk_len = 0;
184932b31808SJens Wiklander *psk = NULL;
185032b31808SJens Wiklander
185132b31808SJens Wiklander if (mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
185232b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
185332b31808SJens Wiklander }
185432b31808SJens Wiklander
185532b31808SJens Wiklander status = psa_get_key_attributes(ssl->handshake->psk_opaque, &key_attributes);
185632b31808SJens Wiklander if (status != PSA_SUCCESS) {
185732b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
185832b31808SJens Wiklander }
185932b31808SJens Wiklander
186032b31808SJens Wiklander *psk_len = PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attributes));
186132b31808SJens Wiklander *psk = mbedtls_calloc(1, *psk_len);
186232b31808SJens Wiklander if (*psk == NULL) {
186332b31808SJens Wiklander return MBEDTLS_ERR_SSL_ALLOC_FAILED;
186432b31808SJens Wiklander }
186532b31808SJens Wiklander
186632b31808SJens Wiklander status = psa_export_key(ssl->handshake->psk_opaque,
186732b31808SJens Wiklander (uint8_t *) *psk, *psk_len, psk_len);
186832b31808SJens Wiklander if (status != PSA_SUCCESS) {
186932b31808SJens Wiklander mbedtls_free((void *) *psk);
187032b31808SJens Wiklander *psk = NULL;
187132b31808SJens Wiklander return PSA_TO_MBEDTLS_ERR(status);
187232b31808SJens Wiklander }
187332b31808SJens Wiklander return 0;
187432b31808SJens Wiklander #else
187532b31808SJens Wiklander *psk = ssl->handshake->psk;
187632b31808SJens Wiklander *psk_len = ssl->handshake->psk_len;
187732b31808SJens Wiklander if (*psk == NULL) {
187832b31808SJens Wiklander return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
187932b31808SJens Wiklander }
188032b31808SJens Wiklander return 0;
188132b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
188232b31808SJens Wiklander }
188332b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
188432b31808SJens Wiklander
1885*273a583eSThomas Bourgoin #if defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT)
mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg,const unsigned char * secret,const size_t secret_len,const unsigned char * label,const size_t label_len,const unsigned char * context_value,const size_t context_len,unsigned char * out,const size_t out_len)1886*273a583eSThomas Bourgoin int mbedtls_ssl_tls13_exporter(const psa_algorithm_t hash_alg,
1887*273a583eSThomas Bourgoin const unsigned char *secret, const size_t secret_len,
1888*273a583eSThomas Bourgoin const unsigned char *label, const size_t label_len,
1889*273a583eSThomas Bourgoin const unsigned char *context_value, const size_t context_len,
1890*273a583eSThomas Bourgoin unsigned char *out, const size_t out_len)
1891*273a583eSThomas Bourgoin {
1892*273a583eSThomas Bourgoin size_t hash_len = PSA_HASH_LENGTH(hash_alg);
1893*273a583eSThomas Bourgoin unsigned char hkdf_secret[MBEDTLS_TLS1_3_MD_MAX_SIZE];
1894*273a583eSThomas Bourgoin int ret = 0;
1895*273a583eSThomas Bourgoin
1896*273a583eSThomas Bourgoin ret = mbedtls_ssl_tls13_derive_secret(hash_alg, secret, secret_len, label, label_len, NULL, 0,
1897*273a583eSThomas Bourgoin MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, hkdf_secret,
1898*273a583eSThomas Bourgoin hash_len);
1899*273a583eSThomas Bourgoin if (ret != 0) {
1900*273a583eSThomas Bourgoin goto exit;
1901*273a583eSThomas Bourgoin }
1902*273a583eSThomas Bourgoin ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
1903*273a583eSThomas Bourgoin hkdf_secret,
1904*273a583eSThomas Bourgoin hash_len,
1905*273a583eSThomas Bourgoin MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exporter),
1906*273a583eSThomas Bourgoin context_value,
1907*273a583eSThomas Bourgoin context_len,
1908*273a583eSThomas Bourgoin MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
1909*273a583eSThomas Bourgoin out,
1910*273a583eSThomas Bourgoin out_len);
1911*273a583eSThomas Bourgoin
1912*273a583eSThomas Bourgoin exit:
1913*273a583eSThomas Bourgoin mbedtls_platform_zeroize(hkdf_secret, sizeof(hkdf_secret));
1914*273a583eSThomas Bourgoin return ret;
1915*273a583eSThomas Bourgoin }
1916*273a583eSThomas Bourgoin #endif /* defined(MBEDTLS_SSL_KEYING_MATERIAL_EXPORT) */
1917*273a583eSThomas Bourgoin
191832b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
1919