godot/thirdparty/mbedtls/library/psa_crypto.c

/*
 *  PSA crypto layer on top of Mbed TLS crypto
 */
/*
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
 */

#include "common.h"
#include "psa_crypto_core_common.h"

#if defined(MBEDTLS_PSA_CRYPTO_C)

#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#include "check_crypto_config.h"
#endif

#include "psa/crypto.h"
#include "psa/crypto_values.h"

#include "psa_crypto_cipher.h"
#include "psa_crypto_core.h"
#include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h"
#include "psa_crypto_driver_wrappers_no_static.h"
#include "psa_crypto_ecp.h"
#include "psa_crypto_ffdh.h"
#include "psa_crypto_hash.h"
#include "psa_crypto_mac.h"
#include "psa_crypto_rsa.h"
#include "psa_crypto_ecp.h"
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#include "psa_crypto_se.h"
#endif
#include "psa_crypto_slot_management.h"
/* Include internal declarations that are useful for implementing persistently
 * stored keys. */
#include "psa_crypto_storage.h"

#include "psa_crypto_random_impl.h"

#include <stdlib.h>
#include <string.h>
#include "mbedtls/platform.h"

#include "mbedtls/aes.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/bignum.h"
#include "mbedtls/camellia.h"
#include "mbedtls/chacha20.h"
#include "mbedtls/chachapoly.h"
#include "mbedtls/cipher.h"
#include "mbedtls/ccm.h"
#include "mbedtls/cmac.h"
#include "mbedtls/constant_time.h"
#include "mbedtls/des.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h"
#include "mbedtls/entropy.h"
#include "mbedtls/error.h"
#include "mbedtls/gcm.h"
#include "mbedtls/md5.h"
#include "mbedtls/pk.h"
#include "pk_wrap.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "mbedtls/ripemd160.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/psa_util.h"
#include "mbedtls/threading.h"

#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) ||          \
    defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT) ||  \
    defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND)
#define BUILTIN_ALG_ANY_HKDF
#endif

/****************************************************************/
/* Global data, support functions and library management */
/****************************************************************/

static int key_type_is_raw_bytes(psa_key_type_t type)
{}

/* Values for psa_global_data_t::rng_state */
#define RNG_NOT_INITIALIZED
#define RNG_INITIALIZED
#define RNG_SEEDED

/* IDs for PSA crypto subsystems. Starts at 1 to catch potential uninitialized
 * variables as arguments. */
mbedtls_psa_crypto_subsystem;

/* Initialization flags for global_data::initialized */
#define PSA_CRYPTO_SUBSYSTEM_DRIVER_WRAPPERS_INITIALIZED
#define PSA_CRYPTO_SUBSYSTEM_KEY_SLOTS_INITIALIZED
#define PSA_CRYPTO_SUBSYSTEM_TRANSACTION_INITIALIZED

#define PSA_CRYPTO_SUBSYSTEM_ALL_INITIALISED

psa_global_data_t;

static psa_global_data_t global_data;

static uint8_t psa_get_initialized(void)
{}

static uint8_t psa_get_drivers_initialized(void)
{}

#define GUARD_MODULE_INITIALIZED

#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)

/* Declare a local copy of an input buffer and a variable that will be used
 * to store a pointer to the start of the buffer.
 *
 * Note: This macro must be called before any operations which may jump to
 * the exit label, so that the local input copy object is safe to be freed.
 *
 * Assumptions:
 * - input is the name of a pointer to the buffer to be copied
 * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope
 * - input_copy_name is a name that is unused in the current scope
 */
#define LOCAL_INPUT_DECLARE(input, input_copy_name)

/* Allocate a copy of the buffer input and set the pointer input_copy to
 * point to the start of the copy.
 *
 * Assumptions:
 * - psa_status_t status exists
 * - An exit label is declared
 * - input is the name of a pointer to the buffer to be copied
 * - LOCAL_INPUT_DECLARE(input, input_copy) has previously been called
 */
#define LOCAL_INPUT_ALLOC(input, length, input_copy)

/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC()
 *
 * Assumptions:
 * - input_copy is the name of the input copy pointer set by LOCAL_INPUT_ALLOC()
 * - input is the name of the original buffer that was copied
 */
#define LOCAL_INPUT_FREE(input, input_copy)

/* Declare a local copy of an output buffer and a variable that will be used
 * to store a pointer to the start of the buffer.
 *
 * Note: This macro must be called before any operations which may jump to
 * the exit label, so that the local output copy object is safe to be freed.
 *
 * Assumptions:
 * - output is the name of a pointer to the buffer to be copied
 * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope
 * - output_copy_name is a name that is unused in the current scope
 */
#define LOCAL_OUTPUT_DECLARE(output, output_copy_name)

/* Allocate a copy of the buffer output and set the pointer output_copy to
 * point to the start of the copy.
 *
 * Assumptions:
 * - psa_status_t status exists
 * - An exit label is declared
 * - output is the name of a pointer to the buffer to be copied
 * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called
 */
#define LOCAL_OUTPUT_ALLOC(output, length, output_copy)

/* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC()
 * after first copying back its contents to the original buffer.
 *
 * Assumptions:
 * - psa_status_t status exists
 * - output_copy is the name of the output copy pointer set by LOCAL_OUTPUT_ALLOC()
 * - output is the name of the original buffer that was copied
 */
#define LOCAL_OUTPUT_FREE(output, output_copy)
#else /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */
#define LOCAL_INPUT_DECLARE
#define LOCAL_INPUT_ALLOC
#define LOCAL_INPUT_FREE
#define LOCAL_OUTPUT_DECLARE
#define LOCAL_OUTPUT_ALLOC
#define LOCAL_OUTPUT_FREE
#endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */


int psa_can_do_hash(psa_algorithm_t hash_alg)
{}

int psa_can_do_cipher(psa_key_type_t key_type, psa_algorithm_t cipher_alg)
{}


#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT) ||       \
    defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY) ||     \
    defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE)
static int psa_is_dh_key_size_valid(size_t bits)
{
    switch (bits) {
#if defined(PSA_WANT_DH_RFC7919_2048)
        case 2048:
            return 1;
#endif /* PSA_WANT_DH_RFC7919_2048 */
#if defined(PSA_WANT_DH_RFC7919_3072)
        case 3072:
            return 1;
#endif /* PSA_WANT_DH_RFC7919_3072 */
#if defined(PSA_WANT_DH_RFC7919_4096)
        case 4096:
            return 1;
#endif /* PSA_WANT_DH_RFC7919_4096 */
#if defined(PSA_WANT_DH_RFC7919_6144)
        case 6144:
            return 1;
#endif /* PSA_WANT_DH_RFC7919_6144 */
#if defined(PSA_WANT_DH_RFC7919_8192)
        case 8192:
            return 1;
#endif /* PSA_WANT_DH_RFC7919_8192 */
        default:
            return 0;
    }
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT ||
          MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY ||
          PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */

psa_status_t mbedtls_to_psa_error(int ret)
{}

/**
 * \brief                       For output buffers which contain "tags"
 *                              (outputs that may be checked for validity like
 *                              hashes, MACs and signatures), fill the unused
 *                              part of the output buffer (the whole buffer on
 *                              error, the trailing part on success) with
 *                              something that isn't a valid tag (barring an
 *                              attack on the tag and deliberately-crafted
 *                              input), in case the caller doesn't check the
 *                              return status properly.
 *
 * \param output_buffer         Pointer to buffer to wipe. May not be NULL
 *                              unless \p output_buffer_size is zero.
 * \param status                Status of function called to generate
 *                              output_buffer originally
 * \param output_buffer_size    Size of output buffer. If zero, \p output_buffer
 *                              could be NULL.
 * \param output_buffer_length  Length of data written to output_buffer, must be
 *                              less than \p output_buffer_size
 */
static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status,
                                       size_t output_buffer_size, size_t output_buffer_length)
{}


psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type,
                                                    size_t bits)
{}

/** Check whether a given key type is valid for use with a given MAC algorithm
 *
 * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH
 * when called with the validated \p algorithm and \p key_type is well-defined.
 *
 * \param[in] algorithm     The specific MAC algorithm (can be wildcard).
 * \param[in] key_type      The key type of the key to be used with the
 *                          \p algorithm.
 *
 * \retval #PSA_SUCCESS
 *         The \p key_type is valid for use with the \p algorithm
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         The \p key_type is not valid for use with the \p algorithm
 */
MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do(
    psa_algorithm_t algorithm,
    psa_key_type_t key_type)
{}

psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
                                         size_t buffer_length)
{}

psa_status_t psa_copy_key_material_into_slot(psa_key_slot_t *slot,
                                             const uint8_t *data,
                                             size_t data_length)
{}

psa_status_t psa_import_key_into_slot(
    const psa_key_attributes_t *attributes,
    const uint8_t *data, size_t data_length,
    uint8_t *key_buffer, size_t key_buffer_size,
    size_t *key_buffer_length, size_t *bits)
{}

/** Calculate the intersection of two algorithm usage policies.
 *
 * Return 0 (which allows no operation) on incompatibility.
 */
static psa_algorithm_t psa_key_policy_algorithm_intersection(
    psa_key_type_t key_type,
    psa_algorithm_t alg1,
    psa_algorithm_t alg2)
{}

static int psa_key_algorithm_permits(psa_key_type_t key_type,
                                     psa_algorithm_t policy_alg,
                                     psa_algorithm_t requested_alg)
{}

/** Test whether a policy permits an algorithm.
 *
 * The caller must test usage flags separately.
 *
 * \note This function requires providing the key type for which the policy is
 *       being validated, since some algorithm policy definitions (e.g. MAC)
 *       have different properties depending on what kind of cipher it is
 *       combined with.
 *
 * \retval PSA_SUCCESS                  When \p alg is a specific algorithm
 *                                      allowed by the \p policy.
 * \retval PSA_ERROR_INVALID_ARGUMENT   When \p alg is not a specific algorithm
 * \retval PSA_ERROR_NOT_PERMITTED      When \p alg is a specific algorithm, but
 *                                      the \p policy does not allow it.
 */
static psa_status_t psa_key_policy_permits(const psa_key_policy_t *policy,
                                           psa_key_type_t key_type,
                                           psa_algorithm_t alg)
{}

/** Restrict a key policy based on a constraint.
 *
 * \note This function requires providing the key type for which the policy is
 *       being restricted, since some algorithm policy definitions (e.g. MAC)
 *       have different properties depending on what kind of cipher it is
 *       combined with.
 *
 * \param[in] key_type      The key type for which to restrict the policy
 * \param[in,out] policy    The policy to restrict.
 * \param[in] constraint    The policy constraint to apply.
 *
 * \retval #PSA_SUCCESS
 *         \c *policy contains the intersection of the original value of
 *         \c *policy and \c *constraint.
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         \c key_type, \c *policy and \c *constraint are incompatible.
 *         \c *policy is unchanged.
 */
static psa_status_t psa_restrict_key_policy(
    psa_key_type_t key_type,
    psa_key_policy_t *policy,
    const psa_key_policy_t *constraint)
{}

/** Get the description of a key given its identifier and policy constraints
 *  and lock it.
 *
 * The key must have allow all the usage flags set in \p usage. If \p alg is
 * nonzero, the key must allow operations with this algorithm. If \p alg is
 * zero, the algorithm is not checked.
 *
 * In case of a persistent key, the function loads the description of the key
 * into a key slot if not already done.
 *
 * On success, the returned key slot has been registered for reading.
 * It is the responsibility of the caller to then unregister
 * once they have finished reading the contents of the slot.
 * The caller unregisters by calling psa_unregister_read() or
 * psa_unregister_read_under_mutex(). psa_unregister_read() must be called
 * if and only if the caller already holds the global key slot mutex
 * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates
 * the unregister with mutex lock and unlock operations.
 */
static psa_status_t psa_get_and_lock_key_slot_with_policy(
    mbedtls_svc_key_id_t key,
    psa_key_slot_t **p_slot,
    psa_key_usage_t usage,
    psa_algorithm_t alg)
{}

/** Get a key slot containing a transparent key and lock it.
 *
 * A transparent key is a key for which the key material is directly
 * available, as opposed to a key in a secure element and/or to be used
 * by a secure element.
 *
 * This is a temporary function that may be used instead of
 * psa_get_and_lock_key_slot_with_policy() when there is no opaque key support
 * for a cryptographic operation.
 *
 * On success, the returned key slot has been registered for reading.
 * It is the responsibility of the caller to then unregister
 * once they have finished reading the contents of the slot.
 * The caller unregisters by calling psa_unregister_read() or
 * psa_unregister_read_under_mutex(). psa_unregister_read() must be called
 * if and only if the caller already holds the global key slot mutex
 * (when mutexes are enabled). psa_unregister_read_under_mutex() encapsulates
 * psa_unregister_read() with mutex lock and unlock operations.
 */
static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
    mbedtls_svc_key_id_t key,
    psa_key_slot_t **p_slot,
    psa_key_usage_t usage,
    psa_algorithm_t alg)
{}

psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
{}

/** Completely wipe a slot in memory, including its policy.
 * Persistent storage is not affected. */
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
{}

psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key)
{}

/** Retrieve all the publicly-accessible attributes of a key.
 */
psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key,
                                    psa_key_attributes_t *attributes)
{}

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_status_t psa_get_key_slot_number(
    const psa_key_attributes_t *attributes,
    psa_key_slot_number_t *slot_number)
{
    if (attributes->has_slot_number) {
        *slot_number = attributes->slot_number;
        return PSA_SUCCESS;
    } else {
        return PSA_ERROR_INVALID_ARGUMENT;
    }
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

static psa_status_t psa_export_key_buffer_internal(const uint8_t *key_buffer,
                                                   size_t key_buffer_size,
                                                   uint8_t *data,
                                                   size_t data_size,
                                                   size_t *data_length)
{}

psa_status_t psa_export_key_internal(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    uint8_t *data, size_t data_size, size_t *data_length)
{}

psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
                            uint8_t *data_external,
                            size_t data_size,
                            size_t *data_length)
{}

psa_status_t psa_export_public_key_internal(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer,
    size_t key_buffer_size,
    uint8_t *data,
    size_t data_size,
    size_t *data_length)
{}

psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key,
                                   uint8_t *data_external,
                                   size_t data_size,
                                   size_t *data_length)
{}

/** Validate that a key policy is internally well-formed.
 *
 * This function only rejects invalid policies. It does not validate the
 * consistency of the policy with respect to other attributes of the key
 * such as the key type.
 */
static psa_status_t psa_validate_key_policy(const psa_key_policy_t *policy)
{}

/** Validate the internal consistency of key attributes.
 *
 * This function only rejects invalid attribute values. If does not
 * validate the consistency of the attributes with any key data that may
 * be involved in the creation of the key.
 *
 * Call this function early in the key creation process.
 *
 * \param[in] attributes    Key attributes for the new key.
 * \param[out] p_drv        On any return, the driver for the key, if any.
 *                          NULL for a transparent key.
 *
 */
static psa_status_t psa_validate_key_attributes(
    const psa_key_attributes_t *attributes,
    psa_se_drv_table_entry_t **p_drv)
{}

/** Prepare a key slot to receive key material.
 *
 * This function allocates a key slot and sets its metadata.
 *
 * If this function fails, call psa_fail_key_creation().
 *
 * This function is intended to be used as follows:
 * -# Call psa_start_key_creation() to allocate a key slot, prepare
 *    it with the specified attributes, and in case of a volatile key assign it
 *    a volatile key identifier.
 * -# Populate the slot with the key material.
 * -# Call psa_finish_key_creation() to finalize the creation of the slot.
 * In case of failure at any step, stop the sequence and call
 * psa_fail_key_creation().
 *
 * On success, the key slot's state is PSA_SLOT_FILLING.
 * It is the responsibility of the caller to change the slot's state to
 * PSA_SLOT_EMPTY/FULL once key creation has finished.
 *
 * \param method            An identification of the calling function.
 * \param[in] attributes    Key attributes for the new key.
 * \param[out] p_slot       On success, a pointer to the prepared slot.
 * \param[out] p_drv        On any return, the driver for the key, if any.
 *                          NULL for a transparent key.
 *
 * \retval #PSA_SUCCESS
 *         The key slot is ready to receive key material.
 * \return If this function fails, the key slot is an invalid state.
 *         You must call psa_fail_key_creation() to wipe and free the slot.
 */
static psa_status_t psa_start_key_creation(
    psa_key_creation_method_t method,
    const psa_key_attributes_t *attributes,
    psa_key_slot_t **p_slot,
    psa_se_drv_table_entry_t **p_drv)
{}

/** Finalize the creation of a key once its key material has been set.
 *
 * This entails writing the key to persistent storage.
 *
 * If this function fails, call psa_fail_key_creation().
 * See the documentation of psa_start_key_creation() for the intended use
 * of this function.
 *
 * If the finalization succeeds, the function sets the key slot's state to
 * PSA_SLOT_FULL, and the key slot can no longer be accessed as part of the
 * key creation process.
 *
 * \param[in,out] slot  Pointer to the slot with key material.
 * \param[in] driver    The secure element driver for the key,
 *                      or NULL for a transparent key.
 * \param[out] key      On success, identifier of the key. Note that the
 *                      key identifier is also stored in the key slot.
 *
 * \retval #PSA_SUCCESS
 *         The key was successfully created.
 * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription
 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
 * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
 * \retval #PSA_ERROR_DATA_INVALID \emptydescription
 * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
 *
 * \return If this function fails, the key slot is an invalid state.
 *         You must call psa_fail_key_creation() to wipe and free the slot.
 */
static psa_status_t psa_finish_key_creation(
    psa_key_slot_t *slot,
    psa_se_drv_table_entry_t *driver,
    mbedtls_svc_key_id_t *key)
{}

/** Abort the creation of a key.
 *
 * You may call this function after calling psa_start_key_creation(),
 * or after psa_finish_key_creation() fails. In other circumstances, this
 * function may not clean up persistent storage.
 * See the documentation of psa_start_key_creation() for the intended use
 * of this function. Sets the slot's state to PSA_SLOT_EMPTY.
 *
 * \param[in,out] slot  Pointer to the slot with key material.
 * \param[in] driver    The secure element driver for the key,
 *                      or NULL for a transparent key.
 */
static void psa_fail_key_creation(psa_key_slot_t *slot,
                                  psa_se_drv_table_entry_t *driver)
{}

/** Validate optional attributes during key creation.
 *
 * Some key attributes are optional during key creation. If they are
 * specified in the attributes structure, check that they are consistent
 * with the data in the slot.
 *
 * This function should be called near the end of key creation, after
 * the slot in memory is fully populated but before saving persistent data.
 */
static psa_status_t psa_validate_optional_attributes(
    const psa_key_slot_t *slot,
    const psa_key_attributes_t *attributes)
{}

psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
                            const uint8_t *data_external,
                            size_t data_length,
                            mbedtls_svc_key_id_t *key)
{}

#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_status_t mbedtls_psa_register_se_key(
    const psa_key_attributes_t *attributes)
{
    psa_status_t status;
    psa_key_slot_t *slot = NULL;
    psa_se_drv_table_entry_t *driver = NULL;
    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;

    /* Leaving attributes unspecified is not currently supported.
     * It could make sense to query the key type and size from the
     * secure element, but not all secure elements support this
     * and the driver HAL doesn't currently support it. */
    if (psa_get_key_type(attributes) == PSA_KEY_TYPE_NONE) {
        return PSA_ERROR_NOT_SUPPORTED;
    }
    if (psa_get_key_bits(attributes) == 0) {
        return PSA_ERROR_NOT_SUPPORTED;
    }

    /* Not usable with volatile keys, even with an appropriate location,
     * due to the API design.
     * https://github.com/Mbed-TLS/mbedtls/issues/9253
     */
    if (PSA_KEY_LIFETIME_IS_VOLATILE(psa_get_key_lifetime(attributes))) {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    status = psa_start_key_creation(PSA_KEY_CREATION_REGISTER, attributes,
                                    &slot, &driver);
    if (status != PSA_SUCCESS) {
        goto exit;
    }

    status = psa_finish_key_creation(slot, driver, &key);

exit:
    if (status != PSA_SUCCESS) {
        psa_fail_key_creation(slot, driver);
    }

    /* Registration doesn't keep the key in RAM. */
    psa_close_key(key);
    return status;
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */

psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key,
                          const psa_key_attributes_t *specified_attributes,
                          mbedtls_svc_key_id_t *target_key)
{}



/****************************************************************/
/* Message digests */
/****************************************************************/

psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
{}

psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
                            psa_algorithm_t alg)
{}

psa_status_t psa_hash_update(psa_hash_operation_t *operation,
                             const uint8_t *input_external,
                             size_t input_length)
{}

static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation,
                                             uint8_t *hash,
                                             size_t hash_size,
                                             size_t *hash_length)
{}

psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
                             uint8_t *hash_external,
                             size_t hash_size,
                             size_t *hash_length)
{}

psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
                             const uint8_t *hash_external,
                             size_t hash_length)
{}

psa_status_t psa_hash_compute(psa_algorithm_t alg,
                              const uint8_t *input_external, size_t input_length,
                              uint8_t *hash_external, size_t hash_size,
                              size_t *hash_length)
{}

psa_status_t psa_hash_compare(psa_algorithm_t alg,
                              const uint8_t *input_external, size_t input_length,
                              const uint8_t *hash_external, size_t hash_length)
{}

psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
                            psa_hash_operation_t *target_operation)
{}


/****************************************************************/
/* MAC */
/****************************************************************/

psa_status_t psa_mac_abort(psa_mac_operation_t *operation)
{}

static psa_status_t psa_mac_finalize_alg_and_key_validation(
    psa_algorithm_t alg,
    const psa_key_attributes_t *attributes,
    uint8_t *mac_size)
{}

static psa_status_t psa_mac_setup(psa_mac_operation_t *operation,
                                  mbedtls_svc_key_id_t key,
                                  psa_algorithm_t alg,
                                  int is_sign)
{}

psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
                                mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg)
{}

psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
                                  mbedtls_svc_key_id_t key,
                                  psa_algorithm_t alg)
{}

psa_status_t psa_mac_update(psa_mac_operation_t *operation,
                            const uint8_t *input_external,
                            size_t input_length)
{}

psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
                                 uint8_t *mac_external,
                                 size_t mac_size,
                                 size_t *mac_length)
{}

psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
                                   const uint8_t *mac_external,
                                   size_t mac_length)
{}

static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key,
                                             psa_algorithm_t alg,
                                             const uint8_t *input,
                                             size_t input_length,
                                             uint8_t *mac,
                                             size_t mac_size,
                                             size_t *mac_length,
                                             int is_sign)
{}

psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
                             psa_algorithm_t alg,
                             const uint8_t *input_external,
                             size_t input_length,
                             uint8_t *mac_external,
                             size_t mac_size,
                             size_t *mac_length)
{}

psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
                            psa_algorithm_t alg,
                            const uint8_t *input_external,
                            size_t input_length,
                            const uint8_t *mac_external,
                            size_t mac_length)
{}

/****************************************************************/
/* Asymmetric cryptography */
/****************************************************************/

static psa_status_t psa_sign_verify_check_alg(int input_is_message,
                                              psa_algorithm_t alg)
{}

static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key,
                                      int input_is_message,
                                      psa_algorithm_t alg,
                                      const uint8_t *input,
                                      size_t input_length,
                                      uint8_t *signature,
                                      size_t signature_size,
                                      size_t *signature_length)
{}

static psa_status_t psa_verify_internal(mbedtls_svc_key_id_t key,
                                        int input_is_message,
                                        psa_algorithm_t alg,
                                        const uint8_t *input,
                                        size_t input_length,
                                        const uint8_t *signature,
                                        size_t signature_length)
{}

psa_status_t psa_sign_message_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer,
    size_t key_buffer_size,
    psa_algorithm_t alg,
    const uint8_t *input,
    size_t input_length,
    uint8_t *signature,
    size_t signature_size,
    size_t *signature_length)
{}

psa_status_t psa_sign_message(mbedtls_svc_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *input_external,
                              size_t input_length,
                              uint8_t *signature_external,
                              size_t signature_size,
                              size_t *signature_length)
{}

psa_status_t psa_verify_message_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer,
    size_t key_buffer_size,
    psa_algorithm_t alg,
    const uint8_t *input,
    size_t input_length,
    const uint8_t *signature,
    size_t signature_length)
{}

psa_status_t psa_verify_message(mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t *input_external,
                                size_t input_length,
                                const uint8_t *signature_external,
                                size_t signature_length)
{}

psa_status_t psa_sign_hash_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
    uint8_t *signature, size_t signature_size, size_t *signature_length)
{}

psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key,
                           psa_algorithm_t alg,
                           const uint8_t *hash_external,
                           size_t hash_length,
                           uint8_t *signature_external,
                           size_t signature_size,
                           size_t *signature_length)
{}

psa_status_t psa_verify_hash_builtin(
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
    const uint8_t *signature, size_t signature_length)
{}

psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key,
                             psa_algorithm_t alg,
                             const uint8_t *hash_external,
                             size_t hash_length,
                             const uint8_t *signature_external,
                             size_t signature_length)
{}

psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key,
                                    psa_algorithm_t alg,
                                    const uint8_t *input_external,
                                    size_t input_length,
                                    const uint8_t *salt_external,
                                    size_t salt_length,
                                    uint8_t *output_external,
                                    size_t output_size,
                                    size_t *output_length)
{}

psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key,
                                    psa_algorithm_t alg,
                                    const uint8_t *input_external,
                                    size_t input_length,
                                    const uint8_t *salt_external,
                                    size_t salt_length,
                                    uint8_t *output_external,
                                    size_t output_size,
                                    size_t *output_length)
{}

/****************************************************************/
/* Asymmetric interruptible cryptography                        */
/****************************************************************/

static uint32_t psa_interruptible_max_ops =;

void psa_interruptible_set_max_ops(uint32_t max_ops)
{}

uint32_t psa_interruptible_get_max_ops(void)
{}

uint32_t psa_sign_hash_get_num_ops(
    const psa_sign_hash_interruptible_operation_t *operation)
{}

uint32_t psa_verify_hash_get_num_ops(
    const psa_verify_hash_interruptible_operation_t *operation)
{}

static psa_status_t psa_sign_hash_abort_internal(
    psa_sign_hash_interruptible_operation_t *operation)
{}

psa_status_t psa_sign_hash_start(
    psa_sign_hash_interruptible_operation_t *operation,
    mbedtls_svc_key_id_t key, psa_algorithm_t alg,
    const uint8_t *hash_external, size_t hash_length)
{}


psa_status_t psa_sign_hash_complete(
    psa_sign_hash_interruptible_operation_t *operation,
    uint8_t *signature_external, size_t signature_size,
    size_t *signature_length)
{}

psa_status_t psa_sign_hash_abort(
    psa_sign_hash_interruptible_operation_t *operation)
{}

static psa_status_t psa_verify_hash_abort_internal(
    psa_verify_hash_interruptible_operation_t *operation)
{}

psa_status_t psa_verify_hash_start(
    psa_verify_hash_interruptible_operation_t *operation,
    mbedtls_svc_key_id_t key, psa_algorithm_t alg,
    const uint8_t *hash_external, size_t hash_length,
    const uint8_t *signature_external, size_t signature_length)
{}

psa_status_t psa_verify_hash_complete(
    psa_verify_hash_interruptible_operation_t *operation)
{}

psa_status_t psa_verify_hash_abort(
    psa_verify_hash_interruptible_operation_t *operation)
{}

/****************************************************************/
/* Asymmetric interruptible cryptography internal               */
/* implementations                                              */
/****************************************************************/

void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops)
{}

uint32_t mbedtls_psa_sign_hash_get_num_ops(
    const mbedtls_psa_sign_hash_interruptible_operation_t *operation)
{}

uint32_t mbedtls_psa_verify_hash_get_num_ops(
    const mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{}

psa_status_t mbedtls_psa_sign_hash_start(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation,
    const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
    size_t key_buffer_size, psa_algorithm_t alg,
    const uint8_t *hash, size_t hash_length)
{}

psa_status_t mbedtls_psa_sign_hash_complete(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation,
    uint8_t *signature, size_t signature_size,
    size_t *signature_length)
{}

psa_status_t mbedtls_psa_sign_hash_abort(
    mbedtls_psa_sign_hash_interruptible_operation_t *operation)
{}

psa_status_t mbedtls_psa_verify_hash_start(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation,
    const psa_key_attributes_t *attributes,
    const uint8_t *key_buffer, size_t key_buffer_size,
    psa_algorithm_t alg,
    const uint8_t *hash, size_t hash_length,
    const uint8_t *signature, size_t signature_length)
{}

psa_status_t mbedtls_psa_verify_hash_complete(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{}

psa_status_t mbedtls_psa_verify_hash_abort(
    mbedtls_psa_verify_hash_interruptible_operation_t *operation)
{}

static psa_status_t psa_generate_random_internal(uint8_t *output,
                                                 size_t output_size)
{}


/****************************************************************/
/* Symmetric cryptography */
/****************************************************************/

static psa_status_t psa_cipher_setup(psa_cipher_operation_t *operation,
                                     mbedtls_svc_key_id_t key,
                                     psa_algorithm_t alg,
                                     mbedtls_operation_t cipher_operation)
{}

psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
                                      mbedtls_svc_key_id_t key,
                                      psa_algorithm_t alg)
{}

psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
                                      mbedtls_svc_key_id_t key,
                                      psa_algorithm_t alg)
{}

psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
                                    uint8_t *iv_external,
                                    size_t iv_size,
                                    size_t *iv_length)
{}

psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
                               const uint8_t *iv_external,
                               size_t iv_length)
{}

psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
                               const uint8_t *input_external,
                               size_t input_length,
                               uint8_t *output_external,
                               size_t output_size,
                               size_t *output_length)
{}

psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
                               uint8_t *output_external,
                               size_t output_size,
                               size_t *output_length)
{}

psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
{}

psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t *input_external,
                                size_t input_length,
                                uint8_t *output_external,
                                size_t output_size,
                                size_t *output_length)
{}

psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
                                psa_algorithm_t alg,
                                const uint8_t *input_external,
                                size_t input_length,
                                uint8_t *output_external,
                                size_t output_size,
                                size_t *output_length)
{}


/****************************************************************/
/* AEAD */
/****************************************************************/

/* Helper function to get the base algorithm from its variants. */
static psa_algorithm_t psa_aead_get_base_algorithm(psa_algorithm_t alg)
{}

/* Helper function to perform common nonce length checks. */
static psa_status_t psa_aead_check_nonce_length(psa_algorithm_t alg,
                                                size_t nonce_length)
{}

static psa_status_t psa_aead_check_algorithm(psa_algorithm_t alg)
{}

psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *nonce_external,
                              size_t nonce_length,
                              const uint8_t *additional_data_external,
                              size_t additional_data_length,
                              const uint8_t *plaintext_external,
                              size_t plaintext_length,
                              uint8_t *ciphertext_external,
                              size_t ciphertext_size,
                              size_t *ciphertext_length)
{}

psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key,
                              psa_algorithm_t alg,
                              const uint8_t *nonce_external,
                              size_t nonce_length,
                              const uint8_t *additional_data_external,
                              size_t additional_data_length,
                              const uint8_t *ciphertext_external,
                              size_t ciphertext_length,
                              uint8_t *plaintext_external,
                              size_t plaintext_size,
                              size_t *plaintext_length)
{}

static psa_status_t psa_validate_tag_length(psa_algorithm_t alg)
{}

/* Set the key for a multipart authenticated operation. */
static psa_status_t psa_aead_setup(psa_aead_operation_t *operation,
                                   int is_encrypt,
                                   mbedtls_svc_key_id_t key,
                                   psa_algorithm_t alg)
{}

/* Set the key for a multipart authenticated encryption operation. */
psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
                                    mbedtls_svc_key_id_t key,
                                    psa_algorithm_t alg)
{}

/* Set the key for a multipart authenticated decryption operation. */
psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
                                    mbedtls_svc_key_id_t key,
                                    psa_algorithm_t alg)
{}

static psa_status_t psa_aead_set_nonce_internal(psa_aead_operation_t *operation,
                                                const uint8_t *nonce,
                                                size_t nonce_length)
{}

/* Generate a random nonce / IV for multipart AEAD operation */
psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
                                     uint8_t *nonce_external,
                                     size_t nonce_size,
                                     size_t *nonce_length)
{}

/* Set the nonce for a multipart authenticated encryption or decryption
   operation.*/
psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
                                const uint8_t *nonce_external,
                                size_t nonce_length)
{}

/* Declare the lengths of the message and additional data for multipart AEAD. */
psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
                                  size_t ad_length,
                                  size_t plaintext_length)
{}

/* Pass additional data to an active multipart AEAD operation. */
psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
                                const uint8_t *input_external,
                                size_t input_length)
{}

/* Encrypt or decrypt a message fragment in an active multipart AEAD
   operation.*/
psa_status_t psa_aead_update(psa_aead_operation_t *operation,
                             const uint8_t *input_external,
                             size_t input_length,
                             uint8_t *output_external,
                             size_t output_size,
                             size_t *output_length)
{}

static psa_status_t psa_aead_final_checks(const psa_aead_operation_t *operation)
{}

/* Finish encrypting a message in a multipart AEAD operation. */
psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
                             uint8_t *ciphertext_external,
                             size_t ciphertext_size,
                             size_t *ciphertext_length,
                             uint8_t *tag_external,
                             size_t tag_size,
                             size_t *tag_length)
{}

/* Finish authenticating and decrypting a message in a multipart AEAD
   operation.*/
psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
                             uint8_t *plaintext_external,
                             size_t plaintext_size,
                             size_t *plaintext_length,
                             const uint8_t *tag_external,
                             size_t tag_length)
{}

/* Abort an AEAD operation. */
psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
{}

/****************************************************************/
/* Generators */
/****************************************************************/

#if defined(BUILTIN_ALG_ANY_HKDF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS) || \
    defined(PSA_HAVE_SOFT_PBKDF2)
#define AT_LEAST_ONE_BUILTIN_KDF
#endif /* At least one builtin KDF */

#if defined(BUILTIN_ALG_ANY_HKDF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
static psa_status_t psa_key_derivation_start_hmac(
    psa_mac_operation_t *operation,
    psa_algorithm_t hash_alg,
    const uint8_t *hmac_key,
    size_t hmac_key_length)
{}
#endif /* KDF algorithms reliant on HMAC */

#define HKDF_STATE_INIT
#define HKDF_STATE_STARTED
#define HKDF_STATE_KEYED
#define HKDF_STATE_OUTPUT

static psa_algorithm_t psa_key_derivation_get_kdf_alg(
    const psa_key_derivation_operation_t *operation)
{}

psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation)
{}

psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
                                             size_t *capacity)
{}

psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation,
                                             size_t capacity)
{}

#if defined(BUILTIN_ALG_ANY_HKDF)
/* Read some bytes from an HKDF-based operation. */
static psa_status_t psa_key_derivation_hkdf_read(psa_hkdf_key_derivation_t *hkdf,
                                                 psa_algorithm_t kdf_alg,
                                                 uint8_t *output,
                                                 size_t output_length)
{}
#endif /* BUILTIN_ALG_ANY_HKDF */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
    psa_tls12_prf_key_derivation_t *tls12_prf,
    psa_algorithm_t alg)
{}

static psa_status_t psa_key_derivation_tls12_prf_read(
    psa_tls12_prf_key_derivation_t *tls12_prf,
    psa_algorithm_t alg,
    uint8_t *output,
    size_t output_length)
{}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
        * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
static psa_status_t psa_key_derivation_tls12_ecjpake_to_pms_read(
    psa_tls12_ecjpake_to_pms_t *ecjpake,
    uint8_t *output,
    size_t output_length)
{}
#endif

#if defined(PSA_HAVE_SOFT_PBKDF2)
static psa_status_t psa_key_derivation_pbkdf2_generate_block(
    psa_pbkdf2_key_derivation_t *pbkdf2,
    psa_algorithm_t prf_alg,
    uint8_t prf_output_length,
    psa_key_attributes_t *attributes)
{
    psa_status_t status;
    psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
    size_t mac_output_length;
    uint8_t U_i[PSA_MAC_MAX_SIZE];
    uint8_t *U_accumulator = pbkdf2->output_block;
    uint64_t i;
    uint8_t block_counter[4];

    mac_operation.is_sign = 1;
    mac_operation.mac_size = prf_output_length;
    MBEDTLS_PUT_UINT32_BE(pbkdf2->block_number, block_counter, 0);

    status = psa_driver_wrapper_mac_sign_setup(&mac_operation,
                                               attributes,
                                               pbkdf2->password,
                                               pbkdf2->password_length,
                                               prf_alg);
    if (status != PSA_SUCCESS) {
        goto cleanup;
    }
    status = psa_mac_update(&mac_operation, pbkdf2->salt, pbkdf2->salt_length);
    if (status != PSA_SUCCESS) {
        goto cleanup;
    }
    status = psa_mac_update(&mac_operation, block_counter, sizeof(block_counter));
    if (status != PSA_SUCCESS) {
        goto cleanup;
    }
    status = psa_mac_sign_finish(&mac_operation, U_i, sizeof(U_i),
                                 &mac_output_length);
    if (status != PSA_SUCCESS) {
        goto cleanup;
    }

    if (mac_output_length != prf_output_length) {
        status = PSA_ERROR_CORRUPTION_DETECTED;
        goto cleanup;
    }

    memcpy(U_accumulator, U_i, prf_output_length);

    for (i = 1; i < pbkdf2->input_cost; i++) {
        /* We are passing prf_output_length as mac_size because the driver
         * function directly sets mac_output_length as mac_size upon success.
         * See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
        status = psa_driver_wrapper_mac_compute(attributes,
                                                pbkdf2->password,
                                                pbkdf2->password_length,
                                                prf_alg, U_i, prf_output_length,
                                                U_i, prf_output_length,
                                                &mac_output_length);
        if (status != PSA_SUCCESS) {
            goto cleanup;
        }

        mbedtls_xor(U_accumulator, U_accumulator, U_i, prf_output_length);
    }

cleanup:
    /* Zeroise buffers to clear sensitive data from memory. */
    mbedtls_platform_zeroize(U_i, PSA_MAC_MAX_SIZE);
    return status;
}

static psa_status_t psa_key_derivation_pbkdf2_read(
    psa_pbkdf2_key_derivation_t *pbkdf2,
    psa_algorithm_t kdf_alg,
    uint8_t *output,
    size_t output_length)
{
    psa_status_t status;
    psa_algorithm_t prf_alg;
    uint8_t prf_output_length;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(pbkdf2->password_length));
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);

    if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
        prf_alg = PSA_ALG_HMAC(PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg));
        prf_output_length = PSA_HASH_LENGTH(prf_alg);
        psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
    } else if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
        prf_alg = PSA_ALG_CMAC;
        prf_output_length = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
        psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
    } else {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    switch (pbkdf2->state) {
        case PSA_PBKDF2_STATE_PASSWORD_SET:
            /* Initially we need a new block so bytes_used is equal to block size*/
            pbkdf2->bytes_used = prf_output_length;
            pbkdf2->state = PSA_PBKDF2_STATE_OUTPUT;
            break;
        case PSA_PBKDF2_STATE_OUTPUT:
            break;
        default:
            return PSA_ERROR_BAD_STATE;
    }

    while (output_length != 0) {
        uint8_t n = prf_output_length - pbkdf2->bytes_used;
        if (n > output_length) {
            n = (uint8_t) output_length;
        }
        memcpy(output, pbkdf2->output_block + pbkdf2->bytes_used, n);
        output += n;
        output_length -= n;
        pbkdf2->bytes_used += n;

        if (output_length == 0) {
            break;
        }

        /* We need a new block */
        pbkdf2->bytes_used = 0;
        pbkdf2->block_number++;

        status = psa_key_derivation_pbkdf2_generate_block(pbkdf2, prf_alg,
                                                          prf_output_length,
                                                          &attributes);
        if (status != PSA_SUCCESS) {
            return status;
        }
    }

    return PSA_SUCCESS;
}
#endif /* PSA_HAVE_SOFT_PBKDF2 */

psa_status_t psa_key_derivation_output_bytes(
    psa_key_derivation_operation_t *operation,
    uint8_t *output_external,
    size_t output_length)
{}

#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
static void psa_des_set_key_parity(uint8_t *data, size_t data_size)
{
    if (data_size >= 8) {
        mbedtls_des_key_set_parity(data);
    }
    if (data_size >= 16) {
        mbedtls_des_key_set_parity(data + 8);
    }
    if (data_size >= 24) {
        mbedtls_des_key_set_parity(data + 16);
    }
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */

/*
 * ECC keys on a Weierstrass elliptic curve require the generation
 * of a private key which is an integer
 * in the range [1, N - 1], where N is the boundary of the private key domain:
 * N is the prime p for Diffie-Hellman, or the order of the
 * curve’s base point for ECC.
 *
 * Let m be the bit size of N, such that 2^m > N >= 2^(m-1).
 * This function generates the private key using the following process:
 *
 * 1. Draw a byte string of length ceiling(m/8) bytes.
 * 2. If m is not a multiple of 8, set the most significant
 *    (8 * ceiling(m/8) - m) bits of the first byte in the string to zero.
 * 3. Convert the string to integer k by decoding it as a big-endian byte string.
 * 4. If k > N - 2, discard the result and return to step 1.
 * 5. Output k + 1 as the private key.
 *
 * This method allows compliance to NIST standards, specifically the methods titled
 * Key-Pair Generation by Testing Candidates in the following publications:
 * - NIST Special Publication 800-56A: Recommendation for Pair-Wise Key-Establishment
 *   Schemes Using Discrete Logarithm Cryptography [SP800-56A] §5.6.1.1.4 for
 *   Diffie-Hellman keys.
 *
 * - [SP800-56A] §5.6.1.2.2 or FIPS Publication 186-4: Digital Signature
 *   Standard (DSS) [FIPS186-4] §B.4.2 for elliptic curve keys.
 *
 * Note: Function allocates memory for *data buffer, so given *data should be
 *       always NULL.
 */
#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE)
static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
    psa_key_slot_t *slot,
    size_t bits,
    psa_key_derivation_operation_t *operation,
    uint8_t **data
    )
{}

/* ECC keys on a Montgomery elliptic curve draws a byte string whose length
 * is determined by the curve, and sets the mandatory bits accordingly. That is:
 *
 * - Curve25519 (PSA_ECC_FAMILY_MONTGOMERY, 255 bits):
 *   draw a 32-byte string and process it as specified in
 *   Elliptic Curves for Security [RFC7748] §5.
 *
 * - Curve448 (PSA_ECC_FAMILY_MONTGOMERY, 448 bits):
 *   draw a 56-byte string and process it as specified in [RFC7748] §5.
 *
 * Note: Function allocates memory for *data buffer, so given *data should be
 *       always NULL.
 */

static psa_status_t psa_generate_derived_ecc_key_montgomery_helper(
    size_t bits,
    psa_key_derivation_operation_t *operation,
    uint8_t **data
    )
{}
#else /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
static psa_status_t psa_generate_derived_ecc_key_weierstrass_helper(
    psa_key_slot_t *slot, size_t bits,
    psa_key_derivation_operation_t *operation, uint8_t **data)
{
    (void) slot;
    (void) bits;
    (void) operation;
    (void) data;
    return PSA_ERROR_NOT_SUPPORTED;
}

static psa_status_t psa_generate_derived_ecc_key_montgomery_helper(
    size_t bits, psa_key_derivation_operation_t *operation, uint8_t **data)
{
    (void) bits;
    (void) operation;
    (void) data;
    return PSA_ERROR_NOT_SUPPORTED;
}
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE */
#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE */

static psa_status_t psa_generate_derived_key_internal(
    psa_key_slot_t *slot,
    size_t bits,
    psa_key_derivation_operation_t *operation)
{}

static const psa_custom_key_parameters_t default_custom_production =;

int psa_custom_key_parameters_are_default(
    const psa_custom_key_parameters_t *custom,
    size_t custom_data_length)
{}

psa_status_t psa_key_derivation_output_key_custom(
    const psa_key_attributes_t *attributes,
    psa_key_derivation_operation_t *operation,
    const psa_custom_key_parameters_t *custom,
    const uint8_t *custom_data,
    size_t custom_data_length,
    mbedtls_svc_key_id_t *key)
{}

psa_status_t psa_key_derivation_output_key_ext(
    const psa_key_attributes_t *attributes,
    psa_key_derivation_operation_t *operation,
    const psa_key_production_parameters_t *params,
    size_t params_data_length,
    mbedtls_svc_key_id_t *key)
{}

psa_status_t psa_key_derivation_output_key(
    const psa_key_attributes_t *attributes,
    psa_key_derivation_operation_t *operation,
    mbedtls_svc_key_id_t *key)
{}


/****************************************************************/
/* Key derivation */
/****************************************************************/

#if defined(AT_LEAST_ONE_BUILTIN_KDF)
static int is_kdf_alg_supported(psa_algorithm_t kdf_alg)
{}

static psa_status_t psa_hash_try_support(psa_algorithm_t alg)
{}

static psa_status_t psa_key_derivation_set_maximum_capacity(
    psa_key_derivation_operation_t *operation,
    psa_algorithm_t kdf_alg)
{}

static psa_status_t psa_key_derivation_setup_kdf(
    psa_key_derivation_operation_t *operation,
    psa_algorithm_t kdf_alg)
{}

static psa_status_t psa_key_agreement_try_support(psa_algorithm_t alg)
{}

static int psa_key_derivation_allows_free_form_secret_input(
    psa_algorithm_t kdf_alg)
{}
#endif /* AT_LEAST_ONE_BUILTIN_KDF */

psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
                                      psa_algorithm_t alg)
{}

#if defined(BUILTIN_ALG_ANY_HKDF)
static psa_status_t psa_hkdf_input(psa_hkdf_key_derivation_t *hkdf,
                                   psa_algorithm_t kdf_alg,
                                   psa_key_derivation_step_t step,
                                   const uint8_t *data,
                                   size_t data_length)
{}
#endif /* BUILTIN_ALG_ANY_HKDF */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \
    defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
static psa_status_t psa_tls12_prf_set_seed(psa_tls12_prf_key_derivation_t *prf,
                                           const uint8_t *data,
                                           size_t data_length)
{}

static psa_status_t psa_tls12_prf_set_key(psa_tls12_prf_key_derivation_t *prf,
                                          const uint8_t *data,
                                          size_t data_length)
{}

static psa_status_t psa_tls12_prf_set_label(psa_tls12_prf_key_derivation_t *prf,
                                            const uint8_t *data,
                                            size_t data_length)
{}

static psa_status_t psa_tls12_prf_input(psa_tls12_prf_key_derivation_t *prf,
                                        psa_key_derivation_step_t step,
                                        const uint8_t *data,
                                        size_t data_length)
{}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) ||
        * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
    psa_tls12_prf_key_derivation_t *prf,
    const uint8_t *data,
    size_t data_length)
{}

static psa_status_t psa_tls12_prf_psk_to_ms_set_other_key(
    psa_tls12_prf_key_derivation_t *prf,
    const uint8_t *data,
    size_t data_length)
{}

static psa_status_t psa_tls12_prf_psk_to_ms_input(
    psa_tls12_prf_key_derivation_t *prf,
    psa_key_derivation_step_t step,
    const uint8_t *data,
    size_t data_length)
{}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS)
static psa_status_t psa_tls12_ecjpake_to_pms_input(
    psa_tls12_ecjpake_to_pms_t *ecjpake,
    psa_key_derivation_step_t step,
    const uint8_t *data,
    size_t data_length)
{}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS */

#if defined(PSA_HAVE_SOFT_PBKDF2)
static psa_status_t psa_pbkdf2_set_input_cost(
    psa_pbkdf2_key_derivation_t *pbkdf2,
    psa_key_derivation_step_t step,
    uint64_t data)
{
    if (step != PSA_KEY_DERIVATION_INPUT_COST) {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    if (pbkdf2->state != PSA_PBKDF2_STATE_INIT) {
        return PSA_ERROR_BAD_STATE;
    }

    if (data > PSA_VENDOR_PBKDF2_MAX_ITERATIONS) {
        return PSA_ERROR_NOT_SUPPORTED;
    }

    if (data == 0) {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    pbkdf2->input_cost = data;
    pbkdf2->state = PSA_PBKDF2_STATE_INPUT_COST_SET;

    return PSA_SUCCESS;
}

static psa_status_t psa_pbkdf2_set_salt(psa_pbkdf2_key_derivation_t *pbkdf2,
                                        const uint8_t *data,
                                        size_t data_length)
{
    if (pbkdf2->state == PSA_PBKDF2_STATE_INPUT_COST_SET) {
        pbkdf2->state = PSA_PBKDF2_STATE_SALT_SET;
    } else if (pbkdf2->state == PSA_PBKDF2_STATE_SALT_SET) {
        /* Appending to existing salt. No state change. */
    } else {
        return PSA_ERROR_BAD_STATE;
    }

    if (data_length == 0) {
        /* Appending an empty string, nothing to do. */
    } else {
        uint8_t *next_salt;

        next_salt = mbedtls_calloc(1, data_length + pbkdf2->salt_length);
        if (next_salt == NULL) {
            return PSA_ERROR_INSUFFICIENT_MEMORY;
        }

        if (pbkdf2->salt_length != 0) {
            memcpy(next_salt, pbkdf2->salt, pbkdf2->salt_length);
        }
        memcpy(next_salt + pbkdf2->salt_length, data, data_length);
        pbkdf2->salt_length += data_length;
        mbedtls_free(pbkdf2->salt);
        pbkdf2->salt = next_salt;
    }
    return PSA_SUCCESS;
}

#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
static psa_status_t psa_pbkdf2_hmac_set_password(psa_algorithm_t hash_alg,
                                                 const uint8_t *input,
                                                 size_t input_len,
                                                 uint8_t *output,
                                                 size_t *output_len)
{
    psa_status_t status = PSA_SUCCESS;
    if (input_len > PSA_HASH_BLOCK_LENGTH(hash_alg)) {
        return psa_hash_compute(hash_alg, input, input_len, output,
                                PSA_HMAC_MAX_HASH_BLOCK_SIZE, output_len);
    } else if (input_len > 0) {
        memcpy(output, input, input_len);
    }
    *output_len = PSA_HASH_BLOCK_LENGTH(hash_alg);
    return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */

#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
static psa_status_t psa_pbkdf2_cmac_set_password(const uint8_t *input,
                                                 size_t input_len,
                                                 uint8_t *output,
                                                 size_t *output_len)
{
    psa_status_t status = PSA_SUCCESS;
    if (input_len != PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC)) {
        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
        uint8_t zeros[16] = { 0 };
        psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
        psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(sizeof(zeros)));
        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE);
        /* Passing PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC) as
         * mac_size as the driver function sets mac_output_length = mac_size
         * on success. See https://github.com/Mbed-TLS/mbedtls/issues/7801 */
        status = psa_driver_wrapper_mac_compute(&attributes,
                                                zeros, sizeof(zeros),
                                                PSA_ALG_CMAC, input, input_len,
                                                output,
                                                PSA_MAC_LENGTH(PSA_KEY_TYPE_AES,
                                                               128U,
                                                               PSA_ALG_CMAC),
                                                output_len);
    } else {
        memcpy(output, input, input_len);
        *output_len = PSA_MAC_LENGTH(PSA_KEY_TYPE_AES, 128U, PSA_ALG_CMAC);
    }
    return status;
}
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */

static psa_status_t psa_pbkdf2_set_password(psa_pbkdf2_key_derivation_t *pbkdf2,
                                            psa_algorithm_t kdf_alg,
                                            const uint8_t *data,
                                            size_t data_length)
{
    psa_status_t status = PSA_SUCCESS;
    if (pbkdf2->state != PSA_PBKDF2_STATE_SALT_SET) {
        return PSA_ERROR_BAD_STATE;
    }

#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC)
    if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) {
        psa_algorithm_t hash_alg = PSA_ALG_PBKDF2_HMAC_GET_HASH(kdf_alg);
        status = psa_pbkdf2_hmac_set_password(hash_alg, data, data_length,
                                              pbkdf2->password,
                                              &pbkdf2->password_length);
    } else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */
#if defined(MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128)
    if (kdf_alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
        status = psa_pbkdf2_cmac_set_password(data, data_length,
                                              pbkdf2->password,
                                              &pbkdf2->password_length);
    } else
#endif /* MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 */
    {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    pbkdf2->state = PSA_PBKDF2_STATE_PASSWORD_SET;

    return status;
}

static psa_status_t psa_pbkdf2_input(psa_pbkdf2_key_derivation_t *pbkdf2,
                                     psa_algorithm_t kdf_alg,
                                     psa_key_derivation_step_t step,
                                     const uint8_t *data,
                                     size_t data_length)
{
    switch (step) {
        case PSA_KEY_DERIVATION_INPUT_SALT:
            return psa_pbkdf2_set_salt(pbkdf2, data, data_length);
        case PSA_KEY_DERIVATION_INPUT_PASSWORD:
            return psa_pbkdf2_set_password(pbkdf2, kdf_alg, data, data_length);
        default:
            return PSA_ERROR_INVALID_ARGUMENT;
    }
}
#endif /* PSA_HAVE_SOFT_PBKDF2 */

/** Check whether the given key type is acceptable for the given
 * input step of a key derivation.
 *
 * Secret inputs must have the type #PSA_KEY_TYPE_DERIVE.
 * Non-secret inputs must have the type #PSA_KEY_TYPE_RAW_DATA.
 * Both secret and non-secret inputs can alternatively have the type
 * #PSA_KEY_TYPE_NONE, which is never the type of a key object, meaning
 * that the input was passed as a buffer rather than via a key object.
 */
static int psa_key_derivation_check_input_type(
    psa_key_derivation_step_t step,
    psa_key_type_t key_type)
{}

static psa_status_t psa_key_derivation_input_internal(
    psa_key_derivation_operation_t *operation,
    psa_key_derivation_step_t step,
    psa_key_type_t key_type,
    const uint8_t *data,
    size_t data_length)
{}

static psa_status_t psa_key_derivation_input_integer_internal(
    psa_key_derivation_operation_t *operation,
    psa_key_derivation_step_t step,
    uint64_t value)
{}

psa_status_t psa_key_derivation_input_bytes(
    psa_key_derivation_operation_t *operation,
    psa_key_derivation_step_t step,
    const uint8_t *data_external,
    size_t data_length)
{}

psa_status_t psa_key_derivation_input_integer(
    psa_key_derivation_operation_t *operation,
    psa_key_derivation_step_t step,
    uint64_t value)
{}

psa_status_t psa_key_derivation_input_key(
    psa_key_derivation_operation_t *operation,
    psa_key_derivation_step_t step,
    mbedtls_svc_key_id_t key)
{}



/****************************************************************/
/* Key agreement */
/****************************************************************/

psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attributes,
                                           const uint8_t *key_buffer,
                                           size_t key_buffer_size,
                                           psa_algorithm_t alg,
                                           const uint8_t *peer_key,
                                           size_t peer_key_length,
                                           uint8_t *shared_secret,
                                           size_t shared_secret_size,
                                           size_t *shared_secret_length)
{}

/** Internal function for raw key agreement
 *  Calls the driver wrapper which will hand off key agreement task
 *  to the driver's implementation if a driver is present.
 *  Fallback specified in the driver wrapper is built-in raw key agreement
 *  (psa_key_agreement_raw_builtin).
 */
static psa_status_t psa_key_agreement_raw_internal(psa_algorithm_t alg,
                                                   psa_key_slot_t *private_key,
                                                   const uint8_t *peer_key,
                                                   size_t peer_key_length,
                                                   uint8_t *shared_secret,
                                                   size_t shared_secret_size,
                                                   size_t *shared_secret_length)
{}

/* Note that if this function fails, you must call psa_key_derivation_abort()
 * to potentially free embedded data structures and wipe confidential data.
 */
static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *operation,
                                               psa_key_derivation_step_t step,
                                               psa_key_slot_t *private_key,
                                               const uint8_t *peer_key,
                                               size_t peer_key_length)
{}

psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation,
                                              psa_key_derivation_step_t step,
                                              mbedtls_svc_key_id_t private_key,
                                              const uint8_t *peer_key_external,
                                              size_t peer_key_length)
{}

psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
                                   mbedtls_svc_key_id_t private_key,
                                   const uint8_t *peer_key_external,
                                   size_t peer_key_length,
                                   uint8_t *output_external,
                                   size_t output_size,
                                   size_t *output_length)
{}


/****************************************************************/
/* Random generation */
/****************************************************************/

#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
#include "entropy_poll.h"
#endif

/** Initialize the PSA random generator.
 *
 *  Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
 *  this function if mutexes are enabled.
 */
static void mbedtls_psa_random_init(mbedtls_psa_random_context_t *rng)
{}

/** Deinitialize the PSA random generator.
 *
 *  Note: the mbedtls_threading_psa_rngdata_mutex should be held when calling
 *  this function if mutexes are enabled.
 */
static void mbedtls_psa_random_free(mbedtls_psa_random_context_t *rng)
{}

/** Seed the PSA random generator.
 */
static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng)
{}

psa_status_t psa_generate_random(uint8_t *output_external,
                                 size_t output_size)
{}

#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
                                        size_t seed_size)
{
    if (psa_get_initialized()) {
        return PSA_ERROR_NOT_PERMITTED;
    }

    if (((seed_size < MBEDTLS_ENTROPY_MIN_PLATFORM) ||
         (seed_size < MBEDTLS_ENTROPY_BLOCK_SIZE)) ||
        (seed_size > MBEDTLS_ENTROPY_MAX_SEED_SIZE)) {
        return PSA_ERROR_INVALID_ARGUMENT;
    }

    return mbedtls_psa_storage_inject_entropy(seed, seed_size);
}
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */

/** Validate the key type and size for key generation
 *
 * \param  type  The key type
 * \param  bits  The number of bits of the key
 *
 * \retval #PSA_SUCCESS
 *         The key type and size are valid.
 * \retval #PSA_ERROR_INVALID_ARGUMENT
 *         The size in bits of the key is not valid.
 * \retval #PSA_ERROR_NOT_SUPPORTED
 *         The type and/or the size in bits of the key or the combination of
 *         the two is not supported.
 */
static psa_status_t psa_validate_key_type_and_size_for_key_generation(
    psa_key_type_t type, size_t bits)
{}

psa_status_t psa_generate_key_internal(
    const psa_key_attributes_t *attributes,
    const psa_custom_key_parameters_t *custom,
    const uint8_t *custom_data,
    size_t custom_data_length,
    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
{}

psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
                                     const psa_custom_key_parameters_t *custom,
                                     const uint8_t *custom_data,
                                     size_t custom_data_length,
                                     mbedtls_svc_key_id_t *key)
{}

psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes,
                                  const psa_key_production_parameters_t *params,
                                  size_t params_data_length,
                                  mbedtls_svc_key_id_t *key)
{}

psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
                              mbedtls_svc_key_id_t *key)
{}

/****************************************************************/
/* Module setup */
/****************************************************************/

#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
    void (* entropy_init)(mbedtls_entropy_context *ctx),
    void (* entropy_free)(mbedtls_entropy_context *ctx))
{}
#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */

void mbedtls_psa_crypto_free(void)
{}

#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
/** Recover a transaction that was interrupted by a power failure.
 *
 * This function is called during initialization, before psa_crypto_init()
 * returns. If this function returns a failure status, the initialization
 * fails.
 */
static psa_status_t psa_crypto_recover_transaction(
    const psa_crypto_transaction_t *transaction)
{
    switch (transaction->unknown.type) {
        case PSA_CRYPTO_TRANSACTION_CREATE_KEY:
        case PSA_CRYPTO_TRANSACTION_DESTROY_KEY:
        /* TODO - fall through to the failure case until this
         * is implemented.
         * https://github.com/ARMmbed/mbed-crypto/issues/218
         */
        default:
            /* We found an unsupported transaction in the storage.
             * We don't know what state the storage is in. Give up. */
            return PSA_ERROR_DATA_INVALID;
    }
}
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */

static psa_status_t mbedtls_psa_crypto_init_subsystem(mbedtls_psa_crypto_subsystem subsystem)
{}

psa_status_t psa_crypto_init(void)
{}

#if defined(PSA_WANT_ALG_SOME_PAKE)
psa_status_t psa_crypto_driver_pake_get_password_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *password_len)
{}

psa_status_t psa_crypto_driver_pake_get_password(
    const psa_crypto_driver_pake_inputs_t *inputs,
    uint8_t *buffer, size_t buffer_size, size_t *buffer_length)
{}

psa_status_t psa_crypto_driver_pake_get_user_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *user_len)
{}

psa_status_t psa_crypto_driver_pake_get_user(
    const psa_crypto_driver_pake_inputs_t *inputs,
    uint8_t *user_id, size_t user_id_size, size_t *user_id_len)
{}

psa_status_t psa_crypto_driver_pake_get_peer_len(
    const psa_crypto_driver_pake_inputs_t *inputs,
    size_t *peer_len)
{}

psa_status_t psa_crypto_driver_pake_get_peer(
    const psa_crypto_driver_pake_inputs_t *inputs,
    uint8_t *peer_id, size_t peer_id_size, size_t *peer_id_length)
{}

psa_status_t psa_crypto_driver_pake_get_cipher_suite(
    const psa_crypto_driver_pake_inputs_t *inputs,
    psa_pake_cipher_suite_t *cipher_suite)
{}

psa_status_t psa_pake_setup(
    psa_pake_operation_t *operation,
    const psa_pake_cipher_suite_t *cipher_suite)
{}

psa_status_t psa_pake_set_password_key(
    psa_pake_operation_t *operation,
    mbedtls_svc_key_id_t password)
{}

psa_status_t psa_pake_set_user(
    psa_pake_operation_t *operation,
    const uint8_t *user_id_external,
    size_t user_id_len)
{}

psa_status_t psa_pake_set_peer(
    psa_pake_operation_t *operation,
    const uint8_t *peer_id_external,
    size_t peer_id_len)
{}

psa_status_t psa_pake_set_role(
    psa_pake_operation_t *operation,
    psa_pake_role_t role)
{}

/* Auxiliary function to convert core computation stage to single driver step. */
#if defined(PSA_WANT_ALG_JPAKE)
static psa_crypto_driver_pake_step_t convert_jpake_computation_stage_to_driver_step(
    psa_jpake_computation_stage_t *stage)
{}
#endif /* PSA_WANT_ALG_JPAKE */

static psa_status_t psa_pake_complete_inputs(
    psa_pake_operation_t *operation)
{}

#if defined(PSA_WANT_ALG_JPAKE)
static psa_status_t psa_jpake_prologue(
    psa_pake_operation_t *operation,
    psa_pake_step_t step,
    psa_jpake_io_mode_t io_mode)
{}

static psa_status_t psa_jpake_epilogue(
    psa_pake_operation_t *operation,
    psa_jpake_io_mode_t io_mode)
{}

#endif /* PSA_WANT_ALG_JPAKE */

psa_status_t psa_pake_output(
    psa_pake_operation_t *operation,
    psa_pake_step_t step,
    uint8_t *output_external,
    size_t output_size,
    size_t *output_length)
{}

psa_status_t psa_pake_input(
    psa_pake_operation_t *operation,
    psa_pake_step_t step,
    const uint8_t *input_external,
    size_t input_length)
{}

psa_status_t psa_pake_get_implicit_key(
    psa_pake_operation_t *operation,
    psa_key_derivation_operation_t *output)
{}

psa_status_t psa_pake_abort(
    psa_pake_operation_t *operation)
{}
#endif /* PSA_WANT_ALG_SOME_PAKE */

/* Memory copying test hooks. These are called before input copy, after input
 * copy, before output copy and after output copy, respectively.
 * They are used by memory-poisoning tests to temporarily unpoison buffers
 * while they are copied. */
#if defined(MBEDTLS_TEST_HOOKS)
void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL;
void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL;
void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len) = NULL;
void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len) = NULL;
#endif

/** Copy from an input buffer to a local copy.
 *
 * \param[in] input             Pointer to input buffer.
 * \param[in] input_len         Length of the input buffer.
 * \param[out] input_copy       Pointer to a local copy in which to store the input data.
 * \param[out] input_copy_len   Length of the local copy buffer.
 * \return                      #PSA_SUCCESS, if the buffer was successfully
 *                              copied.
 * \return                      #PSA_ERROR_CORRUPTION_DETECTED, if the local
 *                              copy is too small to hold contents of the
 *                              input buffer.
 */
MBEDTLS_STATIC_TESTABLE
psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len,
                                   uint8_t *input_copy, size_t input_copy_len)
{}

/** Copy from a local output buffer into a user-supplied one.
 *
 * \param[in] output_copy       Pointer to a local buffer containing the output.
 * \param[in] output_copy_len   Length of the local buffer.
 * \param[out] output           Pointer to user-supplied output buffer.
 * \param[out] output_len       Length of the user-supplied output buffer.
 * \return                      #PSA_SUCCESS, if the buffer was successfully
 *                              copied.
 * \return                      #PSA_ERROR_BUFFER_TOO_SMALL, if the
 *                              user-supplied output buffer is too small to
 *                              hold the contents of the local buffer.
 */
MBEDTLS_STATIC_TESTABLE
psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len,
                                    uint8_t *output, size_t output_len)
{}

psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len,
                                          psa_crypto_local_input_t *local_input)
{}

void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input)
{}

psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len,
                                           psa_crypto_local_output_t *local_output)
{}

psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output)
{}

#endif /* MBEDTLS_PSA_CRYPTO_C */