/*
 *  TLS 1.3 key schedule
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 ( the "License" ); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "common.h"

#if defined(MBEDTLS_SSL_PROTO_TLS1_3)

#include <stdint.h>
#include <string.h>

#include "mbedtls/hkdf.h"
#include "mbedtls/debug.h"
#include "mbedtls/error.h"
#include "mbedtls/platform.h"

#include "ssl_misc.h"
#include "ssl_tls13_keys.h"
#include "ssl_tls13_invasive.h"

#include "psa/crypto.h"

#define MBEDTLS_SSL_TLS1_3_LABEL(name, string)       \
    .name = string,

struct mbedtls_ssl_tls13_labels_struct const mbedtls_ssl_tls13_labels =
{
    /* This seems to work in C, despite the string literal being one
     * character too long due to the 0-termination. */
    MBEDTLS_SSL_TLS1_3_LABEL_LIST
};

#undef MBEDTLS_SSL_TLS1_3_LABEL

/*
 * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
 *
 * The HkdfLabel is specified in RFC 8446 as follows:
 *
 * struct HkdfLabel {
 *   uint16 length;            // Length of expanded key material
 *   opaque label<7..255>;     // Always prefixed by "tls13 "
 *   opaque context<0..255>;   // Usually a communication transcript hash
 * };
 *
 * Parameters:
 * - desired_length: Length of expanded key material
 *                   Even though the standard allows expansion to up to
 *                   2**16 Bytes, TLS 1.3 never uses expansion to more than
 *                   255 Bytes, so we require `desired_length` to be at most
 *                   255. This allows us to save a few Bytes of code by
 *                   hardcoding the writing of the high bytes.
 * - (label, label_len): label + label length, without "tls13 " prefix
 *                       The label length MUST be less than or equal to
 *                       MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
 *                       It is the caller's responsibility to ensure this.
 *                       All (label, label length) pairs used in TLS 1.3
 *                       can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
 * - (ctx, ctx_len): context + context length
 *                   The context length MUST be less than or equal to
 *                   MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
 *                   It is the caller's responsibility to ensure this.
 * - dst: Target buffer for HkdfLabel structure,
 *        This MUST be a writable buffer of size
 *        at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
 * - dst_len: Pointer at which to store the actual length of
 *            the HkdfLabel structure on success.
 */

static const char tls13_label_prefix[6] = "tls13 ";

#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(label_len, context_len) \
    (2                     /* expansion length           */ \
     + 1                   /* label length               */ \
     + label_len                                           \
     + 1                   /* context length             */ \
     + context_len)

#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN                      \
    SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(                             \
        sizeof(tls13_label_prefix) +                       \
        MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN,     \
        MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN)

static void 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)
{
    size_t total_label_len =
        sizeof(tls13_label_prefix) + label_len;
    size_t total_hkdf_lbl_len =
        SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN(total_label_len, ctx_len);

    unsigned char *p = dst;

    /* Add the size of the expanded key material.
     * We're hardcoding the high byte to 0 here assuming that we never use
     * TLS 1.3 HKDF key expansion to more than 255 Bytes. */
#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
#error "The implementation of ssl_tls13_hkdf_encode_label() is not fit for the \
    value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
#endif

    *p++ = 0;
    *p++ = MBEDTLS_BYTE_0(desired_length);

    /* Add label incl. prefix */
    *p++ = MBEDTLS_BYTE_0(total_label_len);
    memcpy(p, tls13_label_prefix, sizeof(tls13_label_prefix));
    p += sizeof(tls13_label_prefix);
    memcpy(p, label, label_len);
    p += label_len;

    /* Add context value */
    *p++ = MBEDTLS_BYTE_0(ctx_len);
    if (ctx_len != 0) {
        memcpy(p, ctx, ctx_len);
    }

    /* Return total length to the caller.  */
    *dst_len = total_hkdf_lbl_len;
}

int 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)
{
    unsigned char hkdf_label[SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN];
    size_t hkdf_label_len = 0;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_key_derivation_operation_t operation =
        PSA_KEY_DERIVATION_OPERATION_INIT;

    if (label_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN) {
        /* Should never happen since this is an internal
         * function, and we know statically which labels
         * are allowed. */
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    if (ctx_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN) {
        /* Should not happen, as above. */
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    if (buf_len > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN) {
        /* Should not happen, as above. */
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    ssl_tls13_hkdf_encode_label(buf_len,
                                label, label_len,
                                ctx, ctx_len,
                                hkdf_label,
                                &hkdf_label_len);

    status = psa_key_derivation_setup(&operation, PSA_ALG_HKDF_EXPAND(hash_alg));

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_input_bytes(&operation,
                                            PSA_KEY_DERIVATION_INPUT_SECRET,
                                            secret,
                                            secret_len);

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_input_bytes(&operation,
                                            PSA_KEY_DERIVATION_INPUT_INFO,
                                            hkdf_label,
                                            hkdf_label_len);

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_output_bytes(&operation,
                                             buf,
                                             buf_len);

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

cleanup:
    abort_status = psa_key_derivation_abort(&operation);
    status = (status == PSA_SUCCESS ? abort_status : status);
    mbedtls_platform_zeroize(hkdf_label, hkdf_label_len);
    return psa_ssl_status_to_mbedtls(status);
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int 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)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    ret = mbedtls_ssl_tls13_hkdf_expand_label(
        hash_alg,
        secret, secret_len,
        MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(key),
        NULL, 0,
        key, key_len);
    if (ret != 0) {
        return ret;
    }

    ret = mbedtls_ssl_tls13_hkdf_expand_label(
        hash_alg,
        secret, secret_len,
        MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(iv),
        NULL, 0,
        iv, iv_len);
    return ret;
}

/*
 * The traffic keying material is generated from the following inputs:
 *
 *  - One secret value per sender.
 *  - A purpose value indicating the specific value being generated
 *  - The desired lengths of key and IV.
 *
 * The expansion itself is based on HKDF:
 *
 *   [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
 *   [sender]_write_iv  = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
 *
 * [sender] denotes the sending side and the Secret value is provided
 * by the function caller. Note that we generate server and client side
 * keys in a single function call.
 */
int 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)
{
    int ret = 0;

    ret = ssl_tls13_make_traffic_key(
        hash_alg, client_secret, secret_len,
        keys->client_write_key, key_len,
        keys->client_write_iv, iv_len);
    if (ret != 0) {
        return ret;
    }

    ret = ssl_tls13_make_traffic_key(
        hash_alg, server_secret, secret_len,
        keys->server_write_key, key_len,
        keys->server_write_iv, iv_len);
    if (ret != 0) {
        return ret;
    }

    keys->key_len = key_len;
    keys->iv_len = iv_len;

    return 0;
}

int 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)
{
    int ret;
    unsigned char hashed_context[PSA_HASH_MAX_SIZE];
    if (ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED) {
        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

        status = psa_hash_compute(hash_alg, ctx, ctx_len, hashed_context,
                                  PSA_HASH_LENGTH(hash_alg), &ctx_len);
        if (status != PSA_SUCCESS) {
            ret = psa_ssl_status_to_mbedtls(status);
            return ret;
        }
    } else {
        if (ctx_len > sizeof(hashed_context)) {
            /* This should never happen since this function is internal
             * and the code sets `ctx_hashed` correctly.
             * Let's double-check nonetheless to not run at the risk
             * of getting a stack overflow. */
            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
        }

        memcpy(hashed_context, ctx, ctx_len);
    }

    return mbedtls_ssl_tls13_hkdf_expand_label(hash_alg,
                                               secret, secret_len,
                                               label, label_len,
                                               hashed_context, ctx_len,
                                               dstbuf, dstbuf_len);

}

int 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)
{
    int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t hlen;
    unsigned char tmp_secret[PSA_MAC_MAX_SIZE] = { 0 };
    const unsigned char all_zeroes_input[MBEDTLS_TLS1_3_MD_MAX_SIZE] = { 0 };
    const unsigned char *l_input = NULL;
    size_t l_input_len;

    psa_key_derivation_operation_t operation =
        PSA_KEY_DERIVATION_OPERATION_INIT;

    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    hlen = PSA_HASH_LENGTH(hash_alg);

    /* For non-initial runs, call Derive-Secret( ., "derived", "")
     * on the old secret. */
    if (secret_old != NULL) {
        ret = mbedtls_ssl_tls13_derive_secret(
            hash_alg,
            secret_old, hlen,
            MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(derived),
            NULL, 0,        /* context */
            MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
            tmp_secret, hlen);
        if (ret != 0) {
            goto cleanup;
        }
    }

    ret = 0;

    if (input != NULL && input_len != 0) {
        l_input = input;
        l_input_len = input_len;
    } else {
        l_input = all_zeroes_input;
        l_input_len = hlen;
    }

    status = psa_key_derivation_setup(&operation,
                                      PSA_ALG_HKDF_EXTRACT(hash_alg));

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_input_bytes(&operation,
                                            PSA_KEY_DERIVATION_INPUT_SALT,
                                            tmp_secret,
                                            hlen);

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_input_bytes(&operation,
                                            PSA_KEY_DERIVATION_INPUT_SECRET,
                                            l_input, l_input_len);

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    status = psa_key_derivation_output_bytes(&operation,
                                             secret_new,
                                             PSA_HASH_LENGTH(hash_alg));

    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

cleanup:
    abort_status = psa_key_derivation_abort(&operation);
    status = (status == PSA_SUCCESS ? abort_status : status);
    ret = (ret == 0 ? psa_ssl_status_to_mbedtls(status) : ret);
    mbedtls_platform_zeroize(tmp_secret, sizeof(tmp_secret));
    return ret;
}

int 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)
{
    int ret;
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    /*
     *            0
     *            |
     *            v
     *  PSK ->  HKDF-Extract = Early Secret
     *            |
     *            +-----> Derive-Secret(., "c e traffic", ClientHello)
     *            |                     = client_early_traffic_secret
     *            |
     *            +-----> Derive-Secret(., "e exp master", ClientHello)
     *            |                     = early_exporter_master_secret
     *            v
     */

    /* Create client_early_traffic_secret */
    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          early_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_e_traffic),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->client_early_traffic_secret,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    /* Create early exporter */
    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          early_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(e_exp_master),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->early_exporter_master_secret,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    return 0;
}

int 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)
{
    int ret;
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    /*
     *
     * Handshake Secret
     * |
     * +-----> Derive-Secret( ., "c hs traffic",
     * |                     ClientHello...ServerHello )
     * |                     = client_handshake_traffic_secret
     * |
     * +-----> Derive-Secret( ., "s hs traffic",
     * |                     ClientHello...ServerHello )
     * |                     = server_handshake_traffic_secret
     *
     */

    /*
     * Compute client_handshake_traffic_secret with
     * Derive-Secret( ., "c hs traffic", ClientHello...ServerHello )
     */

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          handshake_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_hs_traffic),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->client_handshake_traffic_secret,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    /*
     * Compute server_handshake_traffic_secret with
     * Derive-Secret( ., "s hs traffic", ClientHello...ServerHello )
     */

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          handshake_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_hs_traffic),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->server_handshake_traffic_secret,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    return 0;
}

int 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)
{
    int ret;
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    /* Generate {client,server}_application_traffic_secret_0
     *
     * Master Secret
     * |
     * +-----> Derive-Secret( ., "c ap traffic",
     * |                      ClientHello...server Finished )
     * |                      = client_application_traffic_secret_0
     * |
     * +-----> Derive-Secret( ., "s ap traffic",
     * |                      ClientHello...Server Finished )
     * |                      = server_application_traffic_secret_0
     * |
     * +-----> Derive-Secret( ., "exp master",
     * |                      ClientHello...server Finished)
     * |                      = exporter_master_secret
     *
     */

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          application_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(c_ap_traffic),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->client_application_traffic_secret_N,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          application_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(s_ap_traffic),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->server_application_traffic_secret_N,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          application_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(exp_master),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->exporter_master_secret,
                                          hash_len);
    if (ret != 0) {
        return ret;
    }

    return 0;
}

/* Generate resumption_master_secret for use with the ticket exchange.
 *
 * This is not integrated with mbedtls_ssl_tls13_derive_application_secrets()
 * because it uses the transcript hash up to and including ClientFinished. */
int 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)
{
    int ret;
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                          application_secret, hash_len,
                                          MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_master),
                                          transcript, transcript_len,
                                          MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED,
                                          derived->resumption_master_secret,
                                          hash_len);

    if (ret != 0) {
        return ret;
    }

    return 0;
}

/**
 * \brief Transition into application stage of TLS 1.3 key schedule.
 *
 *        The TLS 1.3 key schedule can be viewed as a simple state machine
 *        with states Initial -> Early -> Handshake -> Application, and
 *        this function represents the Handshake -> Application transition.
 *
 *        In the handshake stage, ssl_tls13_generate_application_keys()
 *        can be used to derive the handshake traffic keys.
 *
 * \param ssl  The SSL context to operate on. This must be in key schedule
 *             stage \c Handshake.
 *
 * \returns    \c 0 on success.
 * \returns    A negative error code on failure.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_schedule_stage_application(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
        handshake->ciphersuite_info->mac);

    /*
     * Compute MasterSecret
     */
    ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
                                          handshake->tls13_master_secrets.handshake,
                                          NULL, 0,
                                          handshake->tls13_master_secrets.app);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
        return ret;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "Master secret",
                          handshake->tls13_master_secrets.app, PSA_HASH_LENGTH(hash_alg));

    return 0;
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int 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)
{
    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    size_t hash_len = PSA_HASH_LENGTH(hash_alg);
    unsigned char finished_key[PSA_MAC_MAX_SIZE];
    int ret;
    psa_algorithm_t alg;

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    /* TLS 1.3 Finished message
     *
     * struct {
     *     opaque verify_data[Hash.length];
     * } Finished;
     *
     * verify_data =
     *     HMAC( finished_key,
     *            Hash( Handshake Context +
     *                  Certificate*      +
     *                  CertificateVerify* )
     *    )
     *
     * finished_key =
     *    HKDF-Expand-Label( BaseKey, "finished", "", Hash.length )
     */

    ret = mbedtls_ssl_tls13_hkdf_expand_label(
        hash_alg, base_key, hash_len,
        MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(finished),
        NULL, 0,
        finished_key, hash_len);
    if (ret != 0) {
        goto exit;
    }

    alg = PSA_ALG_HMAC(hash_alg);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
    psa_set_key_algorithm(&attributes, alg);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);

    status = psa_import_key(&attributes, finished_key, hash_len, &key);
    if (status != PSA_SUCCESS) {
        ret = psa_ssl_status_to_mbedtls(status);
        goto exit;
    }

    status = psa_mac_compute(key, alg, transcript, hash_len,
                             dst, hash_len, dst_len);
    ret = psa_ssl_status_to_mbedtls(status);

exit:

    status = psa_destroy_key(key);
    if (ret == 0) {
        ret = psa_ssl_status_to_mbedtls(status);
    }

    mbedtls_platform_zeroize(finished_key, sizeof(finished_key));

    return ret;
}

int mbedtls_ssl_tls13_calculate_verify_data(mbedtls_ssl_context *ssl,
                                            unsigned char *dst,
                                            size_t dst_len,
                                            size_t *actual_len,
                                            int from)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
    size_t transcript_len;

    unsigned char *base_key = NULL;
    size_t base_key_len = 0;
    mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets =
        &ssl->handshake->tls13_hs_secrets;

    mbedtls_md_type_t const md_type = ssl->handshake->ciphersuite_info->mac;

    psa_algorithm_t hash_alg = mbedtls_hash_info_psa_from_md(
        ssl->handshake->ciphersuite_info->mac);
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> mbedtls_ssl_tls13_calculate_verify_data"));

    if (from == MBEDTLS_SSL_IS_CLIENT) {
        base_key = tls13_hs_secrets->client_handshake_traffic_secret;
        base_key_len = sizeof(tls13_hs_secrets->client_handshake_traffic_secret);
    } else {
        base_key = tls13_hs_secrets->server_handshake_traffic_secret;
        base_key_len = sizeof(tls13_hs_secrets->server_handshake_traffic_secret);
    }

    if (dst_len < hash_len) {
        ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
        goto exit;
    }

    ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
                                               transcript, sizeof(transcript),
                                               &transcript_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret);
        goto exit;
    }
    MBEDTLS_SSL_DEBUG_BUF(4, "handshake hash", transcript, transcript_len);

    ret = ssl_tls13_calc_finished_core(hash_alg, base_key, transcript, dst, actual_len);
    if (ret != 0) {
        goto exit;
    }

    MBEDTLS_SSL_DEBUG_BUF(3, "verify_data for finished message", dst, hash_len);
    MBEDTLS_SSL_DEBUG_MSG(2, ("<= mbedtls_ssl_tls13_calculate_verify_data"));

exit:
    /* Erase handshake secrets */
    mbedtls_platform_zeroize(base_key, base_key_len);
    mbedtls_platform_zeroize(transcript, sizeof(transcript));
    return ret;
}

int 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)
{
    int ret = 0;
    unsigned char binder_key[PSA_MAC_MAX_SIZE];
    unsigned char early_secret[PSA_MAC_MAX_SIZE];
    size_t const hash_len = PSA_HASH_LENGTH(hash_alg);
    size_t actual_len;

#if !defined(MBEDTLS_DEBUG_C)
    ssl = NULL; /* make sure we don't use it except for debug */
    ((void) ssl);
#endif

    /* We should never call this function with an unknown hash,
     * but add an assertion anyway. */
    if (!PSA_ALG_IS_HASH(hash_alg)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    /*
     *            0
     *            |
     *            v
     *  PSK ->  HKDF-Extract = Early Secret
     *            |
     *            +-----> Derive-Secret(., "ext binder" | "res binder", "")
     *            |                     = binder_key
     *            v
     */

    ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
                                          NULL,           /* Old secret */
                                          psk, psk_len,   /* Input      */
                                          early_secret);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
        goto exit;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_create_psk_binder",
                          early_secret, hash_len);

    if (psk_type == MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION) {
        ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                              early_secret, hash_len,
                                              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(res_binder),
                                              NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
                                              binder_key, hash_len);
        MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'res binder'"));
    } else {
        ret = mbedtls_ssl_tls13_derive_secret(hash_alg,
                                              early_secret, hash_len,
                                              MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(ext_binder),
                                              NULL, 0, MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
                                              binder_key, hash_len);
        MBEDTLS_SSL_DEBUG_MSG(4, ("Derive Early Secret with 'ext binder'"));
    }

    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_secret", ret);
        goto exit;
    }

    /*
     * The binding_value is computed in the same way as the Finished message
     * but with the BaseKey being the binder_key.
     */

    ret = ssl_tls13_calc_finished_core(hash_alg, binder_key, transcript,
                                       result, &actual_len);
    if (ret != 0) {
        goto exit;
    }

    MBEDTLS_SSL_DEBUG_BUF(3, "psk binder", result, actual_len);

exit:

    mbedtls_platform_zeroize(early_secret, sizeof(early_secret));
    mbedtls_platform_zeroize(binder_key,   sizeof(binder_key));
    return ret;
}

int mbedtls_ssl_tls13_populate_transform(mbedtls_ssl_transform *transform,
                                         int endpoint,
                                         int ciphersuite,
                                         mbedtls_ssl_key_set const *traffic_keys,
                                         mbedtls_ssl_context *ssl /* DEBUG ONLY */)
{
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
    int ret;
    mbedtls_cipher_info_t const *cipher_info;
#endif /* MBEDTLS_USE_PSA_CRYPTO */
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
    unsigned char const *key_enc;
    unsigned char const *iv_enc;
    unsigned char const *key_dec;
    unsigned char const *iv_dec;

#if defined(MBEDTLS_USE_PSA_CRYPTO)
    psa_key_type_t key_type;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_algorithm_t alg;
    size_t key_bits;
    psa_status_t status = PSA_SUCCESS;
#endif

#if !defined(MBEDTLS_DEBUG_C)
    ssl = NULL; /* make sure we don't use it except for those cases */
    (void) ssl;
#endif

    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
    if (ciphersuite_info == NULL) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("ciphersuite info for %d not found",
                                  ciphersuite));
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

#if !defined(MBEDTLS_USE_PSA_CRYPTO)
    cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->cipher);
    if (cipher_info == NULL) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("cipher info for %u not found",
                                  ciphersuite_info->cipher));
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

    /*
     * Setup cipher contexts in target transform
     */
    if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_enc,
                                    cipher_info)) != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
        return ret;
    }

    if ((ret = mbedtls_cipher_setup(&transform->cipher_ctx_dec,
                                    cipher_info)) != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setup", ret);
        return ret;
    }
#endif /* MBEDTLS_USE_PSA_CRYPTO */

#if defined(MBEDTLS_SSL_SRV_C)
    if (endpoint == MBEDTLS_SSL_IS_SERVER) {
        key_enc = traffic_keys->server_write_key;
        key_dec = traffic_keys->client_write_key;
        iv_enc = traffic_keys->server_write_iv;
        iv_dec = traffic_keys->client_write_iv;
    } else
#endif /* MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_CLI_C)
    if (endpoint == MBEDTLS_SSL_IS_CLIENT) {
        key_enc = traffic_keys->client_write_key;
        key_dec = traffic_keys->server_write_key;
        iv_enc = traffic_keys->client_write_iv;
        iv_dec = traffic_keys->server_write_iv;
    } else
#endif /* MBEDTLS_SSL_CLI_C */
    {
        /* should not happen */
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    memcpy(transform->iv_enc, iv_enc, traffic_keys->iv_len);
    memcpy(transform->iv_dec, iv_dec, traffic_keys->iv_len);

#if !defined(MBEDTLS_USE_PSA_CRYPTO)
    if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_enc,
                                     key_enc, cipher_info->key_bitlen,
                                     MBEDTLS_ENCRYPT)) != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
        return ret;
    }

    if ((ret = mbedtls_cipher_setkey(&transform->cipher_ctx_dec,
                                     key_dec, cipher_info->key_bitlen,
                                     MBEDTLS_DECRYPT)) != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_cipher_setkey", ret);
        return ret;
    }
#endif /* MBEDTLS_USE_PSA_CRYPTO */

    /*
     * Setup other fields in SSL transform
     */

    if ((ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) != 0) {
        transform->taglen  = 8;
    } else {
        transform->taglen  = 16;
    }

    transform->ivlen       = traffic_keys->iv_len;
    transform->maclen      = 0;
    transform->fixed_ivlen = transform->ivlen;
    transform->tls_version = MBEDTLS_SSL_VERSION_TLS1_3;

    /* We add the true record content type (1 Byte) to the plaintext and
     * then pad to the configured granularity. The minimum length of the
     * type-extended and padded plaintext is therefore the padding
     * granularity. */
    transform->minlen =
        transform->taglen + MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY;

#if defined(MBEDTLS_USE_PSA_CRYPTO)
    /*
     * Setup psa keys and alg
     */
    if ((status = mbedtls_ssl_cipher_to_psa(ciphersuite_info->cipher,
                                            transform->taglen,
                                            &alg,
                                            &key_type,
                                            &key_bits)) != PSA_SUCCESS) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_cipher_to_psa", psa_ssl_status_to_mbedtls(status));
        return psa_ssl_status_to_mbedtls(status);
    }

    transform->psa_alg = alg;

    if (alg != MBEDTLS_SSL_NULL_CIPHER) {
        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
        psa_set_key_algorithm(&attributes, alg);
        psa_set_key_type(&attributes, key_type);

        if ((status = psa_import_key(&attributes,
                                     key_enc,
                                     PSA_BITS_TO_BYTES(key_bits),
                                     &transform->psa_key_enc)) != PSA_SUCCESS) {
            MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", psa_ssl_status_to_mbedtls(status));
            return psa_ssl_status_to_mbedtls(status);
        }

        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT);

        if ((status = psa_import_key(&attributes,
                                     key_dec,
                                     PSA_BITS_TO_BYTES(key_bits),
                                     &transform->psa_key_dec)) != PSA_SUCCESS) {
            MBEDTLS_SSL_DEBUG_RET(1, "psa_import_key", psa_ssl_status_to_mbedtls(status));
            return psa_ssl_status_to_mbedtls(status);
        }
    }
#endif /* MBEDTLS_USE_PSA_CRYPTO */

    return 0;
}

MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_get_cipher_key_info(
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info,
    size_t *key_len, size_t *iv_len)
{
    psa_key_type_t key_type;
    psa_algorithm_t alg;
    size_t taglen;
    size_t key_bits;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    if (ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG) {
        taglen = 8;
    } else {
        taglen = 16;
    }

    status = mbedtls_ssl_cipher_to_psa(ciphersuite_info->cipher, taglen,
                                       &alg, &key_type, &key_bits);
    if (status != PSA_SUCCESS) {
        return psa_ssl_status_to_mbedtls(status);
    }

    *key_len = PSA_BITS_TO_BYTES(key_bits);

    /* TLS 1.3 only have AEAD ciphers, IV length is unconditionally 12 bytes */
    *iv_len = 12;

    return 0;
}

#if defined(MBEDTLS_SSL_EARLY_DATA)
/*
 * ssl_tls13_generate_early_key() generates the key necessary for protecting
 * the early application data and handshake messages as described in section 7
 * of RFC 8446.
 *
 * NOTE: Only one key is generated, the key for the traffic from the client to
 *       the server. The TLS 1.3 specification does not define a secret and thus
 *       a key for server early traffic.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_early_key(mbedtls_ssl_context *ssl,
                                        mbedtls_ssl_key_set *traffic_keys)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_md_type_t md_type;
    psa_algorithm_t hash_alg;
    size_t hash_len;
    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
    size_t transcript_len;
    size_t key_len;
    size_t iv_len;
    mbedtls_ssl_tls13_early_secrets tls13_early_secrets;

    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_early_key"));

    ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
        goto cleanup;
    }

    md_type = ciphersuite_info->mac;

    hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
    hash_len = PSA_HASH_LENGTH(hash_alg);

    ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
                                               transcript,
                                               sizeof(transcript),
                                               &transcript_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1,
                              "mbedtls_ssl_get_handshake_transcript",
                              ret);
        goto cleanup;
    }

    ret = mbedtls_ssl_tls13_derive_early_secrets(
        hash_alg, handshake->tls13_master_secrets.early,
        transcript, transcript_len, &tls13_early_secrets);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(
            1, "mbedtls_ssl_tls13_derive_early_secrets", ret);
        goto cleanup;
    }

    MBEDTLS_SSL_DEBUG_BUF(
        4, "Client early traffic secret",
        tls13_early_secrets.client_early_traffic_secret, hash_len);

    /*
     * Export client handshake traffic secret
     */
    if (ssl->f_export_keys != NULL) {
        ssl->f_export_keys(
            ssl->p_export_keys,
            MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_EARLY_SECRET,
            tls13_early_secrets.client_early_traffic_secret,
            hash_len,
            handshake->randbytes,
            handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
            MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
    }

    ret = ssl_tls13_make_traffic_key(
        hash_alg,
        tls13_early_secrets.client_early_traffic_secret,
        hash_len, traffic_keys->client_write_key, key_len,
        traffic_keys->client_write_iv, iv_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_make_traffic_key", ret);
        goto cleanup;
    }
    traffic_keys->key_len = key_len;
    traffic_keys->iv_len = iv_len;

    MBEDTLS_SSL_DEBUG_BUF(4, "client early write_key",
                          traffic_keys->client_write_key,
                          traffic_keys->key_len);

    MBEDTLS_SSL_DEBUG_BUF(4, "client early write_iv",
                          traffic_keys->client_write_iv,
                          traffic_keys->iv_len);

    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_early_key"));

cleanup:
    /* Erase early secrets and transcript */
    mbedtls_platform_zeroize(
        &tls13_early_secrets, sizeof(mbedtls_ssl_tls13_early_secrets));
    mbedtls_platform_zeroize(transcript, sizeof(transcript));
    return ret;
}

int mbedtls_ssl_tls13_compute_early_transform(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_key_set traffic_keys;
    mbedtls_ssl_transform *transform_earlydata = NULL;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;

    /* Next evolution in key schedule: Establish early_data secret and
     * key material. */
    ret = ssl_tls13_generate_early_key(ssl, &traffic_keys);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_early_key",
                              ret);
        goto cleanup;
    }

    transform_earlydata = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
    if (transform_earlydata == NULL) {
        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
        goto cleanup;
    }

    ret = mbedtls_ssl_tls13_populate_transform(
        transform_earlydata,
        ssl->conf->endpoint,
        handshake->ciphersuite_info->id,
        &traffic_keys,
        ssl);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
        goto cleanup;
    }
    handshake->transform_earlydata = transform_earlydata;

cleanup:
    mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
    if (ret != 0) {
        mbedtls_free(transform_earlydata);
    }

    return ret;
}
#endif /* MBEDTLS_SSL_EARLY_DATA */

int mbedtls_ssl_tls13_key_schedule_stage_early(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    psa_algorithm_t hash_alg;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    unsigned char *psk = NULL;
    size_t psk_len = 0;

    if (handshake->ciphersuite_info == NULL) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("cipher suite info not found"));
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
    if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
        ret = mbedtls_ssl_tls13_export_handshake_psk(ssl, &psk, &psk_len);
        if (ret != 0) {
            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_export_handshake_psk",
                                  ret);
            return ret;
        }
    }
#endif

    ret = mbedtls_ssl_tls13_evolve_secret(hash_alg, NULL, psk, psk_len,
                                          handshake->tls13_master_secrets.early);
#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
    defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
    mbedtls_free((void *) psk);
#endif
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
        return ret;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "mbedtls_ssl_tls13_key_schedule_stage_early",
                          handshake->tls13_master_secrets.early,
                          PSA_HASH_LENGTH(hash_alg));
    return 0;
}

/**
 * \brief Compute TLS 1.3 handshake traffic keys.
 *
 *        ssl_tls13_generate_handshake_keys() generates keys necessary for
 *        protecting the handshake messages, as described in Section 7 of
 *        RFC 8446.
 *
 * \param ssl  The SSL context to operate on. This must be in
 *             key schedule stage \c Handshake, see
 *             ssl_tls13_key_schedule_stage_handshake().
 * \param traffic_keys The address at which to store the handshake traffic
 *                     keys. This must be writable but may be uninitialized.
 *
 * \returns    \c 0 on success.
 * \returns    A negative error code on failure.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_handshake_keys(mbedtls_ssl_context *ssl,
                                             mbedtls_ssl_key_set *traffic_keys)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_md_type_t md_type;
    psa_algorithm_t hash_alg;
    size_t hash_len;
    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
    size_t transcript_len;
    size_t key_len;
    size_t iv_len;

    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = handshake->ciphersuite_info;
    mbedtls_ssl_tls13_handshake_secrets *tls13_hs_secrets = &handshake->tls13_hs_secrets;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> ssl_tls13_generate_handshake_keys"));

    ret = ssl_tls13_get_cipher_key_info(ciphersuite_info, &key_len, &iv_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
        return ret;
    }

    md_type = ciphersuite_info->mac;

    hash_alg = mbedtls_hash_info_psa_from_md(ciphersuite_info->mac);
    hash_len = PSA_HASH_LENGTH(hash_alg);

    ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
                                               transcript,
                                               sizeof(transcript),
                                               &transcript_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1,
                              "mbedtls_ssl_get_handshake_transcript",
                              ret);
        return ret;
    }

    ret = mbedtls_ssl_tls13_derive_handshake_secrets(hash_alg,
                                                     handshake->tls13_master_secrets.handshake,
                                                     transcript, transcript_len, tls13_hs_secrets);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_handshake_secrets",
                              ret);
        return ret;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "Client handshake traffic secret",
                          tls13_hs_secrets->client_handshake_traffic_secret,
                          hash_len);
    MBEDTLS_SSL_DEBUG_BUF(4, "Server handshake traffic secret",
                          tls13_hs_secrets->server_handshake_traffic_secret,
                          hash_len);

    /*
     * Export client handshake traffic secret
     */
    if (ssl->f_export_keys != NULL) {
        ssl->f_export_keys(ssl->p_export_keys,
                           MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_HANDSHAKE_TRAFFIC_SECRET,
                           tls13_hs_secrets->client_handshake_traffic_secret,
                           hash_len,
                           handshake->randbytes,
                           handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
                           MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);

        ssl->f_export_keys(ssl->p_export_keys,
                           MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_HANDSHAKE_TRAFFIC_SECRET,
                           tls13_hs_secrets->server_handshake_traffic_secret,
                           hash_len,
                           handshake->randbytes,
                           handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
                           MBEDTLS_SSL_TLS_PRF_NONE /* TODO: FIX! */);
    }

    ret = mbedtls_ssl_tls13_make_traffic_keys(hash_alg,
                                              tls13_hs_secrets->client_handshake_traffic_secret,
                                              tls13_hs_secrets->server_handshake_traffic_secret,
                                              hash_len, key_len, iv_len, traffic_keys);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
        goto exit;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_key",
                          traffic_keys->client_write_key,
                          traffic_keys->key_len);

    MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_key",
                          traffic_keys->server_write_key,
                          traffic_keys->key_len);

    MBEDTLS_SSL_DEBUG_BUF(4, "client_handshake write_iv",
                          traffic_keys->client_write_iv,
                          traffic_keys->iv_len);

    MBEDTLS_SSL_DEBUG_BUF(4, "server_handshake write_iv",
                          traffic_keys->server_write_iv,
                          traffic_keys->iv_len);

    MBEDTLS_SSL_DEBUG_MSG(2, ("<= ssl_tls13_generate_handshake_keys"));

exit:

    return ret;
}

/**
 * \brief Transition into handshake stage of TLS 1.3 key schedule.
 *
 *        The TLS 1.3 key schedule can be viewed as a simple state machine
 *        with states Initial -> Early -> Handshake -> Application, and
 *        this function represents the Early -> Handshake transition.
 *
 *        In the handshake stage, ssl_tls13_generate_handshake_keys()
 *        can be used to derive the handshake traffic keys.
 *
 * \param ssl  The SSL context to operate on. This must be in key schedule
 *             stage \c Early.
 *
 * \returns    \c 0 on success.
 * \returns    A negative error code on failure.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_key_schedule_stage_handshake(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    psa_algorithm_t const hash_alg = mbedtls_hash_info_psa_from_md(
        handshake->ciphersuite_info->mac);
    unsigned char *shared_secret = NULL;
    size_t shared_secret_len = 0;

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
    /*
     * Compute ECDHE secret used to compute the handshake secret from which
     * client_handshake_traffic_secret and server_handshake_traffic_secret
     * are derived in the handshake secret derivation stage.
     */
    if (mbedtls_ssl_tls13_key_exchange_mode_with_ephemeral(ssl)) {
        if (mbedtls_ssl_tls13_named_group_is_ecdhe(handshake->offered_group_id)) {
#if defined(MBEDTLS_ECDH_C)
            /* Compute ECDH shared secret. */
            psa_status_t status = PSA_ERROR_GENERIC_ERROR;
            psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;

            status = psa_get_key_attributes(handshake->ecdh_psa_privkey,
                                            &key_attributes);
            if (status != PSA_SUCCESS) {
                ret = psa_ssl_status_to_mbedtls(status);
            }

            shared_secret_len = PSA_BITS_TO_BYTES(
                psa_get_key_bits(&key_attributes));
            shared_secret = mbedtls_calloc(1, shared_secret_len);
            if (shared_secret == NULL) {
                return MBEDTLS_ERR_SSL_ALLOC_FAILED;
            }

            status = psa_raw_key_agreement(
                PSA_ALG_ECDH, handshake->ecdh_psa_privkey,
                handshake->ecdh_psa_peerkey, handshake->ecdh_psa_peerkey_len,
                shared_secret, shared_secret_len, &shared_secret_len);
            if (status != PSA_SUCCESS) {
                ret = psa_ssl_status_to_mbedtls(status);
                MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
                goto cleanup;
            }

            status = psa_destroy_key(handshake->ecdh_psa_privkey);
            if (status != PSA_SUCCESS) {
                ret = psa_ssl_status_to_mbedtls(status);
                MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
                goto cleanup;
            }

            handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
#endif /* MBEDTLS_ECDH_C */
        } else {
            MBEDTLS_SSL_DEBUG_MSG(1, ("Group not supported."));
            return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
        }
    }
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */

    /*
     * Compute the Handshake Secret
     */
    ret = mbedtls_ssl_tls13_evolve_secret(hash_alg,
                                          handshake->tls13_master_secrets.early,
                                          shared_secret, shared_secret_len,
                                          handshake->tls13_master_secrets.handshake);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_evolve_secret", ret);
        goto cleanup;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "Handshake secret",
                          handshake->tls13_master_secrets.handshake,
                          PSA_HASH_LENGTH(hash_alg));

cleanup:
    if (shared_secret != NULL) {
        mbedtls_platform_zeroize(shared_secret, shared_secret_len);
        mbedtls_free(shared_secret);
    }

    return ret;
}

/**
 * \brief Compute TLS 1.3 application traffic keys.
 *
 *        ssl_tls13_generate_application_keys() generates application traffic
 *        keys, since any record following a 1-RTT Finished message MUST be
 *        encrypted under the application traffic key.
 *
 * \param ssl  The SSL context to operate on. This must be in
 *             key schedule stage \c Application, see
 *             ssl_tls13_key_schedule_stage_application().
 * \param traffic_keys The address at which to store the application traffic
 *                     keys. This must be writable but may be uninitialized.
 *
 * \returns    \c 0 on success.
 * \returns    A negative error code on failure.
 */
MBEDTLS_CHECK_RETURN_CRITICAL
static int ssl_tls13_generate_application_keys(
    mbedtls_ssl_context *ssl,
    mbedtls_ssl_key_set *traffic_keys)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;

    /* Address at which to store the application secrets */
    mbedtls_ssl_tls13_application_secrets * const app_secrets =
        &ssl->session_negotiate->app_secrets;

    /* Holding the transcript up to and including the ServerFinished */
    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
    size_t transcript_len;

    /* Variables relating to the hash for the chosen ciphersuite. */
    mbedtls_md_type_t md_type;

    psa_algorithm_t hash_alg;
    size_t hash_len;

    /* Variables relating to the cipher for the chosen ciphersuite. */
    size_t key_len, iv_len;

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> derive application traffic keys"));

    /* Extract basic information about hash and ciphersuite */

    ret = ssl_tls13_get_cipher_key_info(handshake->ciphersuite_info,
                                        &key_len, &iv_len);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_get_cipher_key_info", ret);
        goto cleanup;
    }

    md_type = handshake->ciphersuite_info->mac;

    hash_alg = mbedtls_hash_info_psa_from_md(handshake->ciphersuite_info->mac);
    hash_len = PSA_HASH_LENGTH(hash_alg);

    /* Compute current handshake transcript. It's the caller's responsibility
     * to call this at the right time, that is, after the ServerFinished. */

    ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
                                               transcript, sizeof(transcript),
                                               &transcript_len);
    if (ret != 0) {
        goto cleanup;
    }

    /* Compute application secrets from master secret and transcript hash. */

    ret = mbedtls_ssl_tls13_derive_application_secrets(hash_alg,
                                                       handshake->tls13_master_secrets.app,
                                                       transcript, transcript_len,
                                                       app_secrets);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1,
                              "mbedtls_ssl_tls13_derive_application_secrets", ret);
        goto cleanup;
    }

    /* Derive first epoch of IV + Key for application traffic. */

    ret = mbedtls_ssl_tls13_make_traffic_keys(hash_alg,
                                              app_secrets->client_application_traffic_secret_N,
                                              app_secrets->server_application_traffic_secret_N,
                                              hash_len, key_len, iv_len, traffic_keys);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_make_traffic_keys", ret);
        goto cleanup;
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "Client application traffic secret",
                          app_secrets->client_application_traffic_secret_N,
                          hash_len);

    MBEDTLS_SSL_DEBUG_BUF(4, "Server application traffic secret",
                          app_secrets->server_application_traffic_secret_N,
                          hash_len);

    /*
     * Export client/server application traffic secret 0
     */
    if (ssl->f_export_keys != NULL) {
        ssl->f_export_keys(ssl->p_export_keys,
                           MBEDTLS_SSL_KEY_EXPORT_TLS1_3_CLIENT_APPLICATION_TRAFFIC_SECRET,
                           app_secrets->client_application_traffic_secret_N, hash_len,
                           handshake->randbytes,
                           handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
                           MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
                                                       a new constant for TLS 1.3! */);

        ssl->f_export_keys(ssl->p_export_keys,
                           MBEDTLS_SSL_KEY_EXPORT_TLS1_3_SERVER_APPLICATION_TRAFFIC_SECRET,
                           app_secrets->server_application_traffic_secret_N, hash_len,
                           handshake->randbytes,
                           handshake->randbytes + MBEDTLS_CLIENT_HELLO_RANDOM_LEN,
                           MBEDTLS_SSL_TLS_PRF_NONE /* TODO: this should be replaced by
                                                       a new constant for TLS 1.3! */);
    }

    MBEDTLS_SSL_DEBUG_BUF(4, "client application_write_key:",
                          traffic_keys->client_write_key, key_len);
    MBEDTLS_SSL_DEBUG_BUF(4, "server application write key",
                          traffic_keys->server_write_key, key_len);
    MBEDTLS_SSL_DEBUG_BUF(4, "client application write IV",
                          traffic_keys->client_write_iv, iv_len);
    MBEDTLS_SSL_DEBUG_BUF(4, "server application write IV",
                          traffic_keys->server_write_iv, iv_len);

    MBEDTLS_SSL_DEBUG_MSG(2, ("<= derive application traffic keys"));

cleanup:
    /* randbytes is not used again */
    mbedtls_platform_zeroize(ssl->handshake->randbytes,
                             sizeof(ssl->handshake->randbytes));

    mbedtls_platform_zeroize(transcript, sizeof(transcript));
    return ret;
}

int mbedtls_ssl_tls13_compute_handshake_transform(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_key_set traffic_keys;
    mbedtls_ssl_transform *transform_handshake = NULL;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;

    /* Compute handshake secret */
    ret = ssl_tls13_key_schedule_stage_handshake(ssl);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_derive_master_secret", ret);
        goto cleanup;
    }

    /* Next evolution in key schedule: Establish handshake secret and
     * key material. */
    ret = ssl_tls13_generate_handshake_keys(ssl, &traffic_keys);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "ssl_tls13_generate_handshake_keys",
                              ret);
        goto cleanup;
    }

    transform_handshake = mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
    if (transform_handshake == NULL) {
        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
        goto cleanup;
    }

    ret = mbedtls_ssl_tls13_populate_transform(
        transform_handshake,
        ssl->conf->endpoint,
        handshake->ciphersuite_info->id,
        &traffic_keys,
        ssl);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
        goto cleanup;
    }
    handshake->transform_handshake = transform_handshake;

cleanup:
    mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
    if (ret != 0) {
        mbedtls_free(transform_handshake);
    }

    return ret;
}

int mbedtls_ssl_tls13_compute_resumption_master_secret(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_md_type_t md_type;
    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
    size_t transcript_len;

    MBEDTLS_SSL_DEBUG_MSG(2,
                          ("=> mbedtls_ssl_tls13_compute_resumption_master_secret"));

    md_type = handshake->ciphersuite_info->mac;

    ret = mbedtls_ssl_get_handshake_transcript(ssl, md_type,
                                               transcript, sizeof(transcript),
                                               &transcript_len);
    if (ret != 0) {
        return ret;
    }

    ret = mbedtls_ssl_tls13_derive_resumption_master_secret(
        mbedtls_psa_translate_md(md_type),
        handshake->tls13_master_secrets.app,
        transcript, transcript_len,
        &ssl->session_negotiate->app_secrets);
    if (ret != 0) {
        return ret;
    }

    /* Erase master secrets */
    mbedtls_platform_zeroize(&handshake->tls13_master_secrets,
                             sizeof(handshake->tls13_master_secrets));

    MBEDTLS_SSL_DEBUG_BUF(4, "Resumption master secret",
                          ssl->session_negotiate->app_secrets.resumption_master_secret,
                          PSA_HASH_LENGTH(mbedtls_psa_translate_md(md_type)));

    MBEDTLS_SSL_DEBUG_MSG(2,
                          ("<= mbedtls_ssl_tls13_compute_resumption_master_secret"));
    return 0;
}

int mbedtls_ssl_tls13_compute_application_transform(mbedtls_ssl_context *ssl)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ssl_key_set traffic_keys;
    mbedtls_ssl_transform *transform_application = NULL;

    ret = ssl_tls13_key_schedule_stage_application(ssl);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1,
                              "ssl_tls13_key_schedule_stage_application", ret);
        goto cleanup;
    }

    ret = ssl_tls13_generate_application_keys(ssl, &traffic_keys);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1,
                              "ssl_tls13_generate_application_keys", ret);
        goto cleanup;
    }

    transform_application =
        mbedtls_calloc(1, sizeof(mbedtls_ssl_transform));
    if (transform_application == NULL) {
        ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
        goto cleanup;
    }

    ret = mbedtls_ssl_tls13_populate_transform(
        transform_application,
        ssl->conf->endpoint,
        ssl->handshake->ciphersuite_info->id,
        &traffic_keys,
        ssl);
    if (ret != 0) {
        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_populate_transform", ret);
        goto cleanup;
    }

    ssl->transform_application = transform_application;

cleanup:

    mbedtls_platform_zeroize(&traffic_keys, sizeof(traffic_keys));
    if (ret != 0) {
        mbedtls_free(transform_application);
    }
    return ret;
}

#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
int mbedtls_ssl_tls13_export_handshake_psk(mbedtls_ssl_context *ssl,
                                           unsigned char **psk,
                                           size_t *psk_len)
{
#if defined(MBEDTLS_USE_PSA_CRYPTO)
    psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

    *psk_len = 0;
    *psk = NULL;

    if (mbedtls_svc_key_id_is_null(ssl->handshake->psk_opaque)) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }

    status = psa_get_key_attributes(ssl->handshake->psk_opaque, &key_attributes);
    if (status != PSA_SUCCESS) {
        return psa_ssl_status_to_mbedtls(status);
    }

    *psk_len = PSA_BITS_TO_BYTES(psa_get_key_bits(&key_attributes));
    *psk = mbedtls_calloc(1, *psk_len);
    if (*psk == NULL) {
        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
    }

    status = psa_export_key(ssl->handshake->psk_opaque,
                            (uint8_t *) *psk, *psk_len, psk_len);
    if (status != PSA_SUCCESS) {
        mbedtls_free((void *) *psk);
        *psk = NULL;
        return psa_ssl_status_to_mbedtls(status);
    }
    return 0;
#else
    *psk = ssl->handshake->psk;
    *psk_len = ssl->handshake->psk_len;
    if (*psk == NULL) {
        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
    }
    return 0;
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
}
#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */

#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
