/*
 *  PSA crypto layer on top of Mbed TLS crypto
 */
/*  Copyright (C) 2018, ARM Limited, All Rights Reserved
 *  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.
 *
 *  This file is part of mbed TLS (https://tls.mbed.org)
 */

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#if defined(MBEDTLS_PSA_CRYPTO_C)
/*
 * In case MBEDTLS_PSA_CRYPTO_SPM is defined the code is built for SPM (Secure
 * Partition Manager) integration which separate the code into two parts
 * NSPE (Non-Secure Process Environment) and SPE (Secure Process Environment).
 * In this mode an additional header file should be included.
 */
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
/*
 * PSA_CRYPTO_SECURE means that this file is compiled to the SPE side.
 * some headers will be affected by this flag.
 */
#define PSA_CRYPTO_SECURE 1
#include "crypto_spe.h"
#endif

#include "psa/crypto.h"

#include "psa_crypto_core.h"
#include "psa_crypto_invasive.h"
#include "psa_crypto_slot_management.h"
/* Include internal declarations that are useful for implementing persistently
 * stored keys. */
#include "psa_crypto_storage.h"

#include <stdlib.h>
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#define mbedtls_calloc calloc
#define mbedtls_free   free
#endif

#include "mbedtls/arc4.h"
#include "mbedtls/asn1.h"
#include "mbedtls/bignum.h"
#include "mbedtls/blowfish.h"
#include "mbedtls/camellia.h"
#include "mbedtls/cipher.h"
#include "mbedtls/ccm.h"
#include "mbedtls/cmac.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/des.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecp.h"
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#include "mbedtls/error.h"
#include "mbedtls/gcm.h"
#include "mbedtls/md2.h"
#include "mbedtls/md4.h"
#include "mbedtls/md5.h"
#include "mbedtls/md.h"
#include "mbedtls/md_internal.h"
#include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/ripemd160.h"
#include "mbedtls/rsa.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/xtea.h"

#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )
#include "psa_prot_internal_storage.h"
#endif

#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )

/* constant-time buffer comparison */
static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
{
    size_t i;
    unsigned char diff = 0;

    for( i = 0; i < n; i++ )
        diff |= a[i] ^ b[i];

    return( diff );
}



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

static int key_type_is_raw_bytes( psa_key_type_t type )
{
    return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) );
}

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

typedef struct
{
    void (* entropy_init )( mbedtls_entropy_context *ctx );
    void (* entropy_free )( mbedtls_entropy_context *ctx );
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    unsigned initialized : 1;
    unsigned rng_state : 2;
} psa_global_data_t;

static psa_global_data_t global_data;

#define GUARD_MODULE_INITIALIZED        \
    if( global_data.initialized == 0 )  \
        return( PSA_ERROR_BAD_STATE );

static psa_status_t mbedtls_to_psa_error( int ret )
{
    /* If there's both a high-level code and low-level code, dispatch on
     * the high-level code. */
    switch( ret < -0x7f ? - ( -ret & 0x7f80 ) : ret )
    {
        case 0:
            return( PSA_SUCCESS );

        case MBEDTLS_ERR_AES_INVALID_KEY_LENGTH:
        case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
        case MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_AES_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
        case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
        case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
        case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
        case MBEDTLS_ERR_ASN1_INVALID_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
            return( PSA_ERROR_BUFFER_TOO_SMALL );

        case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
        case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH:
        case MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_CCM_BAD_INPUT:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_CCM_AUTH_FAILED:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_CCM_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_CIPHER_INVALID_PADDING:
            return( PSA_ERROR_INVALID_PADDING );
        case MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED:
            return( PSA_ERROR_BAD_STATE );
        case MBEDTLS_ERR_CIPHER_AUTH_FAILED:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_CIPHER_INVALID_CONTEXT:
            return( PSA_ERROR_TAMPERING_DETECTED );
        case MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
            return( PSA_ERROR_INSUFFICIENT_ENTROPY );
        case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
        case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR:
            return( PSA_ERROR_INSUFFICIENT_ENTROPY );

        case MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_DES_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
        case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
        case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
            return( PSA_ERROR_INSUFFICIENT_ENTROPY );

        case MBEDTLS_ERR_GCM_AUTH_FAILED:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_GCM_BAD_INPUT:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_MD2_HW_ACCEL_FAILED:
        case MBEDTLS_ERR_MD4_HW_ACCEL_FAILED:
        case MBEDTLS_ERR_MD5_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MD_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_MD_FILE_IO_ERROR:
            return( PSA_ERROR_STORAGE_FAILURE );
        case MBEDTLS_ERR_MD_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_MPI_FILE_IO_ERROR:
            return( PSA_ERROR_STORAGE_FAILURE );
        case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
            return( PSA_ERROR_BUFFER_TOO_SMALL );
        case MBEDTLS_ERR_MPI_NEGATIVE_VALUE:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MPI_DIVISION_BY_ZERO:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_MPI_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );

        case MBEDTLS_ERR_PK_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_PK_TYPE_MISMATCH:
        case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_PK_FILE_IO_ERROR:
            return( PSA_ERROR_STORAGE_FAILURE );
        case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
        case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
        case MBEDTLS_ERR_PK_PASSWORD_MISMATCH:
            return( PSA_ERROR_NOT_PERMITTED );
        case MBEDTLS_ERR_PK_INVALID_PUBKEY:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_PK_INVALID_ALG:
        case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
        case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_PK_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_RSA_BAD_INPUT_DATA:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_RSA_INVALID_PADDING:
            return( PSA_ERROR_INVALID_PADDING );
        case MBEDTLS_ERR_RSA_KEY_GEN_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );
        case MBEDTLS_ERR_RSA_KEY_CHECK_FAILED:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_RSA_PUBLIC_FAILED:
        case MBEDTLS_ERR_RSA_PRIVATE_FAILED:
            return( PSA_ERROR_TAMPERING_DETECTED );
        case MBEDTLS_ERR_RSA_VERIFY_FAILED:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE:
            return( PSA_ERROR_BUFFER_TOO_SMALL );
        case MBEDTLS_ERR_RSA_RNG_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_RSA_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED:
        case MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED:
        case MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
        case MBEDTLS_ERR_ECP_INVALID_KEY:
            return( PSA_ERROR_INVALID_ARGUMENT );
        case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
            return( PSA_ERROR_BUFFER_TOO_SMALL );
        case MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE:
            return( PSA_ERROR_NOT_SUPPORTED );
        case MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH:
        case MBEDTLS_ERR_ECP_VERIFY_FAILED:
            return( PSA_ERROR_INVALID_SIGNATURE );
        case MBEDTLS_ERR_ECP_ALLOC_FAILED:
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        case MBEDTLS_ERR_ECP_HW_ACCEL_FAILED:
            return( PSA_ERROR_HARDWARE_FAILURE );

        default:
            return( PSA_ERROR_UNKNOWN_ERROR );
    }
}




/****************************************************************/
/* Key management */
/****************************************************************/

#if defined(MBEDTLS_ECP_C)
static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid )
{
    switch( grpid )
    {
        case MBEDTLS_ECP_DP_SECP192R1:
            return( PSA_ECC_CURVE_SECP192R1 );
        case MBEDTLS_ECP_DP_SECP224R1:
            return( PSA_ECC_CURVE_SECP224R1 );
        case MBEDTLS_ECP_DP_SECP256R1:
            return( PSA_ECC_CURVE_SECP256R1 );
        case MBEDTLS_ECP_DP_SECP384R1:
            return( PSA_ECC_CURVE_SECP384R1 );
        case MBEDTLS_ECP_DP_SECP521R1:
            return( PSA_ECC_CURVE_SECP521R1 );
        case MBEDTLS_ECP_DP_BP256R1:
            return( PSA_ECC_CURVE_BRAINPOOL_P256R1 );
        case MBEDTLS_ECP_DP_BP384R1:
            return( PSA_ECC_CURVE_BRAINPOOL_P384R1 );
        case MBEDTLS_ECP_DP_BP512R1:
            return( PSA_ECC_CURVE_BRAINPOOL_P512R1 );
        case MBEDTLS_ECP_DP_CURVE25519:
            return( PSA_ECC_CURVE_CURVE25519 );
        case MBEDTLS_ECP_DP_SECP192K1:
            return( PSA_ECC_CURVE_SECP192K1 );
        case MBEDTLS_ECP_DP_SECP224K1:
            return( PSA_ECC_CURVE_SECP224K1 );
        case MBEDTLS_ECP_DP_SECP256K1:
            return( PSA_ECC_CURVE_SECP256K1 );
        case MBEDTLS_ECP_DP_CURVE448:
            return( PSA_ECC_CURVE_CURVE448 );
        default:
            return( 0 );
    }
}

static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
{
    switch( curve )
    {
        case PSA_ECC_CURVE_SECP192R1:
            return( MBEDTLS_ECP_DP_SECP192R1 );
        case PSA_ECC_CURVE_SECP224R1:
            return( MBEDTLS_ECP_DP_SECP224R1 );
        case PSA_ECC_CURVE_SECP256R1:
            return( MBEDTLS_ECP_DP_SECP256R1 );
        case PSA_ECC_CURVE_SECP384R1:
            return( MBEDTLS_ECP_DP_SECP384R1 );
        case PSA_ECC_CURVE_SECP521R1:
            return( MBEDTLS_ECP_DP_SECP521R1 );
        case PSA_ECC_CURVE_BRAINPOOL_P256R1:
            return( MBEDTLS_ECP_DP_BP256R1 );
        case PSA_ECC_CURVE_BRAINPOOL_P384R1:
            return( MBEDTLS_ECP_DP_BP384R1 );
        case PSA_ECC_CURVE_BRAINPOOL_P512R1:
            return( MBEDTLS_ECP_DP_BP512R1 );
        case PSA_ECC_CURVE_CURVE25519:
            return( MBEDTLS_ECP_DP_CURVE25519 );
        case PSA_ECC_CURVE_SECP192K1:
            return( MBEDTLS_ECP_DP_SECP192K1 );
        case PSA_ECC_CURVE_SECP224K1:
            return( MBEDTLS_ECP_DP_SECP224K1 );
        case PSA_ECC_CURVE_SECP256K1:
            return( MBEDTLS_ECP_DP_SECP256K1 );
        case PSA_ECC_CURVE_CURVE448:
            return( MBEDTLS_ECP_DP_CURVE448 );
        default:
            return( MBEDTLS_ECP_DP_NONE );
    }
}
#endif /* defined(MBEDTLS_ECP_C) */

static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
                                           size_t bits,
                                           struct raw_data *raw )
{
    /* Check that the bit size is acceptable for the key type */
    switch( type )
    {
        case PSA_KEY_TYPE_RAW_DATA:
            if( bits == 0 )
            {
                raw->bytes = 0;
                raw->data = NULL;
                return( PSA_SUCCESS );
            }
            break;
#if defined(MBEDTLS_MD_C)
        case PSA_KEY_TYPE_HMAC:
#endif
        case PSA_KEY_TYPE_DERIVE:
            break;
#if defined(MBEDTLS_AES_C)
        case PSA_KEY_TYPE_AES:
            if( bits != 128 && bits != 192 && bits != 256 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            break;
#endif
#if defined(MBEDTLS_CAMELLIA_C)
        case PSA_KEY_TYPE_CAMELLIA:
            if( bits != 128 && bits != 192 && bits != 256 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            break;
#endif
#if defined(MBEDTLS_DES_C)
        case PSA_KEY_TYPE_DES:
            if( bits != 64 && bits != 128 && bits != 192 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            break;
#endif
#if defined(MBEDTLS_ARC4_C)
        case PSA_KEY_TYPE_ARC4:
            if( bits < 8 || bits > 2048 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            break;
#endif
        default:
            return( PSA_ERROR_NOT_SUPPORTED );
    }
    if( bits % 8 != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );

    /* Allocate memory for the key */
    raw->bytes = PSA_BITS_TO_BYTES( bits );
    raw->data = mbedtls_calloc( 1, raw->bytes );
    if( raw->data == NULL )
    {
        raw->bytes = 0;
        return( PSA_ERROR_INSUFFICIENT_MEMORY );
    }
    return( PSA_SUCCESS );
}

#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
/* Mbed TLS doesn't support non-byte-aligned key sizes (i.e. key sizes
 * that are not a multiple of 8) well. For example, there is only
 * mbedtls_rsa_get_len(), which returns a number of bytes, and no
 * way to return the exact bit size of a key.
 * To keep things simple, reject non-byte-aligned key sizes. */
static psa_status_t psa_check_rsa_key_byte_aligned(
    const mbedtls_rsa_context *rsa )
{
    mbedtls_mpi n;
    psa_status_t status;
    mbedtls_mpi_init( &n );
    status = mbedtls_to_psa_error(
        mbedtls_rsa_export( rsa, &n, NULL, NULL, NULL, NULL ) );
    if( status == PSA_SUCCESS )
    {
        if( mbedtls_mpi_bitlen( &n ) % 8 != 0 )
            status = PSA_ERROR_NOT_SUPPORTED;
    }
    mbedtls_mpi_free( &n );
    return( status );
}

static psa_status_t psa_import_rsa_key( mbedtls_pk_context *pk,
                                        mbedtls_rsa_context **p_rsa )
{
    if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_RSA )
        return( PSA_ERROR_INVALID_ARGUMENT );
    else
    {
        mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *pk );
        /* The size of an RSA key doesn't have to be a multiple of 8.
         * Mbed TLS supports non-byte-aligned key sizes, but not well.
         * For example, mbedtls_rsa_get_len() returns the key size in
         * bytes, not in bits. */
        size_t bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( rsa ) );
        psa_status_t status;
        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
            return( PSA_ERROR_NOT_SUPPORTED );
        status = psa_check_rsa_key_byte_aligned( rsa );
        if( status != PSA_SUCCESS )
            return( status );
        *p_rsa = rsa;
        return( PSA_SUCCESS );
    }
}
#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */

#if defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C)
/* Import an elliptic curve parsed by the mbedtls pk module. */
static psa_status_t psa_import_ecp_key( psa_ecc_curve_t expected_curve,
                                        mbedtls_pk_context *pk,
                                        mbedtls_ecp_keypair **p_ecp )
{
    if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
        return( PSA_ERROR_INVALID_ARGUMENT );
    else
    {
        mbedtls_ecp_keypair *ecp = mbedtls_pk_ec( *pk );
        psa_ecc_curve_t actual_curve = mbedtls_ecc_group_to_psa( ecp->grp.id );
        if( actual_curve != expected_curve )
            return( PSA_ERROR_INVALID_ARGUMENT );
        *p_ecp = ecp;
        return( PSA_SUCCESS );
    }
}
#endif /* defined(MBEDTLS_ECP_C) && defined(MBEDTLS_PK_PARSE_C) */

#if defined(MBEDTLS_ECP_C)
/* Import a private key given as a byte string which is the private value
 * in big-endian order. */
static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
                                               const uint8_t *data,
                                               size_t data_length,
                                               mbedtls_ecp_keypair **p_ecp )
{
    psa_status_t status = PSA_ERROR_TAMPERING_DETECTED;
    mbedtls_ecp_keypair *ecp = NULL;
    mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );

    *p_ecp = NULL;
    ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
    if( ecp == NULL )
        return( PSA_ERROR_INSUFFICIENT_MEMORY );

    /* Load the group. */
    status = mbedtls_to_psa_error(
        mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
    if( status != PSA_SUCCESS )
        goto exit;
    /* Load the secret value. */
    status = mbedtls_to_psa_error(
        mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
    if( status != PSA_SUCCESS )
        goto exit;
    /* Validate the private key. */
    status = mbedtls_to_psa_error(
        mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) );
    if( status != PSA_SUCCESS )
        goto exit;
    /* Calculate the public key from the private key. */
    status = mbedtls_to_psa_error(
        mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
                         mbedtls_ctr_drbg_random, &global_data.ctr_drbg ) );
    if( status != PSA_SUCCESS )
        goto exit;

    *p_ecp = ecp;
    return( PSA_SUCCESS );

exit:
    if( ecp != NULL )
    {
        mbedtls_ecp_keypair_free( ecp );
        mbedtls_free( ecp );
    }
    return( status );
}
#endif /* defined(MBEDTLS_ECP_C) */

/** Import key data into a slot. `slot->type` must have been set
 * previously. This function assumes that the slot does not contain
 * any key material yet. On failure, the slot content is unchanged. */
psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot,
                                       const uint8_t *data,
                                       size_t data_length )
{
    psa_status_t status = PSA_SUCCESS;

    if( key_type_is_raw_bytes( slot->type ) )
    {
        /* Ensure that a bytes-to-bit conversion won't overflow. */
        if( data_length > SIZE_MAX / 8 )
            return( PSA_ERROR_NOT_SUPPORTED );
        status = prepare_raw_data_slot( slot->type,
                                        PSA_BYTES_TO_BITS( data_length ),
                                        &slot->data.raw );
        if( status != PSA_SUCCESS )
            return( status );
        if( data_length != 0 )
            memcpy( slot->data.raw.data, data, data_length );
    }
    else
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) )
    {
        status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
                                            data, data_length,
                                            &slot->data.ecp );
        if( status != PSA_SUCCESS )
            return( status );
    }
    else
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_PK_PARSE_C)
    if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
        PSA_KEY_TYPE_IS_ECC( slot->type ) )
    {
        int ret;
        mbedtls_pk_context pk;
        mbedtls_pk_init( &pk );

        /* Parse the data. */
        if( PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
            ret = mbedtls_pk_parse_key( &pk, data, data_length, NULL, 0 );
        else
            ret = mbedtls_pk_parse_public_key( &pk, data, data_length );
        if( ret != 0 )
            return( mbedtls_to_psa_error( ret ) );

        /* We have something that the pkparse module recognizes.
         * If it has the expected type and passes any type-specific
         * checks, store it. */
#if defined(MBEDTLS_RSA_C)
        if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
            status = psa_import_rsa_key( &pk, &slot->data.rsa );
        else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_ECP_C)
        if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
            status = psa_import_ecp_key( PSA_KEY_TYPE_GET_CURVE( slot->type ),
                                         &pk, &slot->data.ecp );
        else
#endif /* MBEDTLS_ECP_C */
        {
            status = PSA_ERROR_NOT_SUPPORTED;
        }

        /* Free the content of the pk object only on error. On success,
         * the content of the object has been stored in the slot. */
        if( status != PSA_SUCCESS )
        {
            mbedtls_pk_free( &pk );
            return( status );
        }
    }
    else
#endif /* defined(MBEDTLS_PK_PARSE_C) */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }
    return( PSA_SUCCESS );
}

/* Retrieve an empty key slot (slot with no key data, but possibly
 * with some metadata such as a policy). */
static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle,
                                            psa_key_slot_t **p_slot )
{
    psa_status_t status;
    psa_key_slot_t *slot = NULL;

    *p_slot = NULL;

    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    if( slot->type != PSA_KEY_TYPE_NONE )
        return( PSA_ERROR_OCCUPIED_SLOT );

    *p_slot = slot;
    return( status );
}

/** Test whether a policy permits an algorithm.
 *
 * The caller must test usage flags separately.
 */
static int psa_key_policy_permits( const psa_key_policy_t *policy,
                                   psa_algorithm_t alg )
{
    /* Common case: the policy only allows alg. */
    if( alg == policy->alg )
        return( 1 );
    /* If policy->alg is a hash-and-sign with a wildcard for the hash,
     * and alg is the same hash-and-sign family with any hash,
     * then alg is compliant with policy->alg. */
    if( PSA_ALG_IS_HASH_AND_SIGN( alg ) &&
        PSA_ALG_SIGN_GET_HASH( policy->alg ) == PSA_ALG_ANY_HASH )
    {
        return( ( policy->alg & ~PSA_ALG_HASH_MASK ) ==
                (         alg & ~PSA_ALG_HASH_MASK ) );
    }
    /* If it isn't permitted, it's forbidden. */
    return( 0 );
}

/** Retrieve a slot which must contain a key. 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. */
static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle,
                                           psa_key_slot_t **p_slot,
                                           psa_key_usage_t usage,
                                           psa_algorithm_t alg )
{
    psa_status_t status;
    psa_key_slot_t *slot = NULL;

    *p_slot = NULL;

    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );
    if( slot->type == PSA_KEY_TYPE_NONE )
        return( PSA_ERROR_EMPTY_SLOT );

    /* Enforce that usage policy for the key slot contains all the flags
     * required by the usage parameter. There is one exception: public
     * keys can always be exported, so we treat public key objects as
     * if they had the export flag. */
    if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
        usage &= ~PSA_KEY_USAGE_EXPORT;
    if( ( slot->policy.usage & usage ) != usage )
        return( PSA_ERROR_NOT_PERMITTED );

    /* Enforce that the usage policy permits the requested algortihm. */
    if( alg != 0 && ! psa_key_policy_permits( &slot->policy, alg ) )
        return( PSA_ERROR_NOT_PERMITTED );

    *p_slot = slot;
    return( PSA_SUCCESS );
}

/** Wipe key data from a slot. Preserve metadata such as the policy. */
static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot )
{
    if( slot->type == PSA_KEY_TYPE_NONE )
    {
        /* No key material to clean. */
    }
    else if( key_type_is_raw_bytes( slot->type ) )
    {
        mbedtls_free( slot->data.raw.data );
    }
    else
#if defined(MBEDTLS_RSA_C)
    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
    {
        mbedtls_rsa_free( slot->data.rsa );
        mbedtls_free( slot->data.rsa );
    }
    else
#endif /* defined(MBEDTLS_RSA_C) */
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
    {
        mbedtls_ecp_keypair_free( slot->data.ecp );
        mbedtls_free( slot->data.ecp );
    }
    else
#endif /* defined(MBEDTLS_ECP_C) */
    {
        /* Shouldn't happen: the key type is not any type that we
         * put in. */
        return( PSA_ERROR_TAMPERING_DETECTED );
    }

    return( PSA_SUCCESS );
}

/** 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 status = psa_remove_key_data_from_memory( slot );
    /* At this point, key material and other type-specific content has
     * been wiped. Clear remaining metadata. We can call memset and not
     * zeroize because the metadata is not particularly sensitive. */
    memset( slot, 0, sizeof( *slot ) );
    return( status );
}

psa_status_t psa_import_key( psa_key_handle_t handle,
                             psa_key_type_t type,
                             const uint8_t *data,
                             size_t data_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    status = psa_get_empty_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    slot->type = type;

    status = psa_import_key_into_slot( slot, data, data_length );
    if( status != PSA_SUCCESS )
    {
        slot->type = PSA_KEY_TYPE_NONE;
        return( status );
    }

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
    {
        /* Store in file location */
        status = psa_save_persistent_key( slot->persistent_storage_id,
                                          slot->type, &slot->policy, data,
                                          data_length );
        if( status != PSA_SUCCESS )
        {
            (void) psa_remove_key_data_from_memory( slot );
            slot->type = PSA_KEY_TYPE_NONE;
        }
    }
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */

    return( status );
}

psa_status_t psa_destroy_key( psa_key_handle_t handle )
{
    psa_key_slot_t *slot;
    psa_status_t status = PSA_SUCCESS;
    psa_status_t storage_status = PSA_SUCCESS;

    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
    {
        storage_status =
            psa_destroy_persistent_key( slot->persistent_storage_id );
    }
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
    status = psa_wipe_key_slot( slot );
    if( status != PSA_SUCCESS )
        return( status );
    return( storage_status );
}

/* Return the size of the key in the given slot, in bits. */
static size_t psa_get_key_bits( const psa_key_slot_t *slot )
{
    if( key_type_is_raw_bytes( slot->type ) )
        return( slot->data.raw.bytes * 8 );
#if defined(MBEDTLS_RSA_C)
    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
        return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) );
#endif /* defined(MBEDTLS_RSA_C) */
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
        return( slot->data.ecp->grp.pbits );
#endif /* defined(MBEDTLS_ECP_C) */
    /* Shouldn't happen except on an empty slot. */
    return( 0 );
}

psa_status_t psa_get_key_information( psa_key_handle_t handle,
                                      psa_key_type_t *type,
                                      size_t *bits )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    if( type != NULL )
        *type = 0;
    if( bits != NULL )
        *bits = 0;
    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    if( slot->type == PSA_KEY_TYPE_NONE )
        return( PSA_ERROR_EMPTY_SLOT );
    if( type != NULL )
        *type = slot->type;
    if( bits != NULL )
        *bits = psa_get_key_bits( slot );
    return( PSA_SUCCESS );
}

static  psa_status_t psa_internal_export_key( psa_key_slot_t *slot,
                                              uint8_t *data,
                                              size_t data_size,
                                              size_t *data_length,
                                              int export_public_key )
{
    *data_length = 0;

    if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) )
        return( PSA_ERROR_INVALID_ARGUMENT );

    if( key_type_is_raw_bytes( slot->type ) )
    {
        if( slot->data.raw.bytes > data_size )
            return( PSA_ERROR_BUFFER_TOO_SMALL );
        if( data_size != 0 )
        {
            memcpy( data, slot->data.raw.data, slot->data.raw.bytes );
            memset( data + slot->data.raw.bytes, 0,
                    data_size - slot->data.raw.bytes );
        }
        *data_length = slot->data.raw.bytes;
        return( PSA_SUCCESS );
    }
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( slot->type ) && !export_public_key )
    {
        psa_status_t status;

        size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( slot ) );
        if( bytes > data_size )
            return( PSA_ERROR_BUFFER_TOO_SMALL );
        status = mbedtls_to_psa_error(
            mbedtls_mpi_write_binary( &slot->data.ecp->d, data, bytes ) );
        if( status != PSA_SUCCESS )
            return( status );
        memset( data + bytes, 0, data_size - bytes );
        *data_length = bytes;
        return( PSA_SUCCESS );
    }
#endif
    else
    {
#if defined(MBEDTLS_PK_WRITE_C)
        if( PSA_KEY_TYPE_IS_RSA( slot->type ) ||
            PSA_KEY_TYPE_IS_ECC( slot->type ) )
        {
            mbedtls_pk_context pk;
            int ret;
            if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
            {
#if defined(MBEDTLS_RSA_C)
                mbedtls_pk_init( &pk );
                pk.pk_info = &mbedtls_rsa_info;
                pk.pk_ctx = slot->data.rsa;
#else
                return( PSA_ERROR_NOT_SUPPORTED );
#endif
            }
            else
            {
#if defined(MBEDTLS_ECP_C)
                mbedtls_pk_init( &pk );
                pk.pk_info = &mbedtls_eckey_info;
                pk.pk_ctx = slot->data.ecp;
#else
                return( PSA_ERROR_NOT_SUPPORTED );
#endif
            }
            if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) )
                ret = mbedtls_pk_write_pubkey_der( &pk, data, data_size );
            else
                ret = mbedtls_pk_write_key_der( &pk, data, data_size );
            if( ret < 0 )
            {
                /* If data_size is 0 then data may be NULL and then the
                 * call to memset would have undefined behavior. */
                if( data_size != 0 )
                    memset( data, 0, data_size );
                return( mbedtls_to_psa_error( ret ) );
            }
            /* The mbedtls_pk_xxx functions write to the end of the buffer.
             * Move the data to the beginning and erase remaining data
             * at the original location. */
            if( 2 * (size_t) ret <= data_size )
            {
                memcpy( data, data + data_size - ret, ret );
                memset( data + data_size - ret, 0, ret );
            }
            else if( (size_t) ret < data_size )
            {
                memmove( data, data + data_size - ret, ret );
                memset( data + ret, 0, data_size - ret );
            }
            *data_length = ret;
            return( PSA_SUCCESS );
        }
        else
#endif /* defined(MBEDTLS_PK_WRITE_C) */
        {
            /* This shouldn't happen in the reference implementation, but
               it is valid for a special-purpose implementation to omit
               support for exporting certain key types. */
            return( PSA_ERROR_NOT_SUPPORTED );
        }
    }
}

psa_status_t psa_export_key( psa_key_handle_t handle,
                             uint8_t *data,
                             size_t data_size,
                             size_t *data_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    /* Set the key to empty now, so that even when there are errors, we always
     * set data_length to a value between 0 and data_size. On error, setting
     * the key to empty is a good choice because an empty key representation is
     * unlikely to be accepted anywhere. */
    *data_length = 0;

    /* Export requires the EXPORT flag. There is an exception for public keys,
     * which don't require any flag, but psa_get_key_from_slot takes
     * care of this. */
    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 );
    if( status != PSA_SUCCESS )
        return( status );
    return( psa_internal_export_key( slot, data, data_size,
                                     data_length, 0 ) );
}

psa_status_t psa_export_public_key( psa_key_handle_t handle,
                                    uint8_t *data,
                                    size_t data_size,
                                    size_t *data_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    /* Set the key to empty now, so that even when there are errors, we always
     * set data_length to a value between 0 and data_size. On error, setting
     * the key to empty is a good choice because an empty key representation is
     * unlikely to be accepted anywhere. */
    *data_length = 0;

    /* Exporting a public key doesn't require a usage flag. */
    status = psa_get_key_from_slot( handle, &slot, 0, 0 );
    if( status != PSA_SUCCESS )
        return( status );
    return( psa_internal_export_key( slot, data, data_size,
                                     data_length, 1 ) );
}

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot,
                                                       size_t bits )
{
    psa_status_t status;
    uint8_t *data;
    size_t key_length;
    size_t data_size = PSA_KEY_EXPORT_MAX_SIZE( slot->type, bits );
    data = mbedtls_calloc( 1, data_size );
    if( data == NULL )
        return( PSA_ERROR_INSUFFICIENT_MEMORY );
    /* Get key data in export format */
    status = psa_internal_export_key( slot, data, data_size, &key_length, 0 );
    if( status != PSA_SUCCESS )
    {
        slot->type = PSA_KEY_TYPE_NONE;
        goto exit;
    }
    /* Store in file location */
    status = psa_save_persistent_key( slot->persistent_storage_id,
                                      slot->type, &slot->policy,
                                      data, key_length );
    if( status != PSA_SUCCESS )
    {
        slot->type = PSA_KEY_TYPE_NONE;
    }
exit:
    mbedtls_platform_zeroize( data, key_length );
    mbedtls_free( data );
    return( status );
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */



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

static const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
{
    switch( alg )
    {
#if defined(MBEDTLS_MD2_C)
        case PSA_ALG_MD2:
            return( &mbedtls_md2_info );
#endif
#if defined(MBEDTLS_MD4_C)
        case PSA_ALG_MD4:
            return( &mbedtls_md4_info );
#endif
#if defined(MBEDTLS_MD5_C)
        case PSA_ALG_MD5:
            return( &mbedtls_md5_info );
#endif
#if defined(MBEDTLS_RIPEMD160_C)
        case PSA_ALG_RIPEMD160:
            return( &mbedtls_ripemd160_info );
#endif
#if defined(MBEDTLS_SHA1_C)
        case PSA_ALG_SHA_1:
            return( &mbedtls_sha1_info );
#endif
#if defined(MBEDTLS_SHA256_C)
        case PSA_ALG_SHA_224:
            return( &mbedtls_sha224_info );
        case PSA_ALG_SHA_256:
            return( &mbedtls_sha256_info );
#endif
#if defined(MBEDTLS_SHA512_C)
        case PSA_ALG_SHA_384:
            return( &mbedtls_sha384_info );
        case PSA_ALG_SHA_512:
            return( &mbedtls_sha512_info );
#endif
        default:
            return( NULL );
    }
}

psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
{
    switch( operation->alg )
    {
        case 0:
            /* The object has (apparently) been initialized but it is not
             * in use. It's ok to call abort on such an object, and there's
             * nothing to do. */
            break;
#if defined(MBEDTLS_MD2_C)
        case PSA_ALG_MD2:
            mbedtls_md2_free( &operation->ctx.md2 );
            break;
#endif
#if defined(MBEDTLS_MD4_C)
        case PSA_ALG_MD4:
            mbedtls_md4_free( &operation->ctx.md4 );
            break;
#endif
#if defined(MBEDTLS_MD5_C)
        case PSA_ALG_MD5:
            mbedtls_md5_free( &operation->ctx.md5 );
            break;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
        case PSA_ALG_RIPEMD160:
            mbedtls_ripemd160_free( &operation->ctx.ripemd160 );
            break;
#endif
#if defined(MBEDTLS_SHA1_C)
        case PSA_ALG_SHA_1:
            mbedtls_sha1_free( &operation->ctx.sha1 );
            break;
#endif
#if defined(MBEDTLS_SHA256_C)
        case PSA_ALG_SHA_224:
        case PSA_ALG_SHA_256:
            mbedtls_sha256_free( &operation->ctx.sha256 );
            break;
#endif
#if defined(MBEDTLS_SHA512_C)
        case PSA_ALG_SHA_384:
        case PSA_ALG_SHA_512:
            mbedtls_sha512_free( &operation->ctx.sha512 );
            break;
#endif
        default:
            return( PSA_ERROR_BAD_STATE );
    }
    operation->alg = 0;
    return( PSA_SUCCESS );
}

psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
                             psa_algorithm_t alg )
{
    int ret;
    operation->alg = 0;
    switch( alg )
    {
#if defined(MBEDTLS_MD2_C)
        case PSA_ALG_MD2:
            mbedtls_md2_init( &operation->ctx.md2 );
            ret = mbedtls_md2_starts_ret( &operation->ctx.md2 );
            break;
#endif
#if defined(MBEDTLS_MD4_C)
        case PSA_ALG_MD4:
            mbedtls_md4_init( &operation->ctx.md4 );
            ret = mbedtls_md4_starts_ret( &operation->ctx.md4 );
            break;
#endif
#if defined(MBEDTLS_MD5_C)
        case PSA_ALG_MD5:
            mbedtls_md5_init( &operation->ctx.md5 );
            ret = mbedtls_md5_starts_ret( &operation->ctx.md5 );
            break;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
        case PSA_ALG_RIPEMD160:
            mbedtls_ripemd160_init( &operation->ctx.ripemd160 );
            ret = mbedtls_ripemd160_starts_ret( &operation->ctx.ripemd160 );
            break;
#endif
#if defined(MBEDTLS_SHA1_C)
        case PSA_ALG_SHA_1:
            mbedtls_sha1_init( &operation->ctx.sha1 );
            ret = mbedtls_sha1_starts_ret( &operation->ctx.sha1 );
            break;
#endif
#if defined(MBEDTLS_SHA256_C)
        case PSA_ALG_SHA_224:
            mbedtls_sha256_init( &operation->ctx.sha256 );
            ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 1 );
            break;
        case PSA_ALG_SHA_256:
            mbedtls_sha256_init( &operation->ctx.sha256 );
            ret = mbedtls_sha256_starts_ret( &operation->ctx.sha256, 0 );
            break;
#endif
#if defined(MBEDTLS_SHA512_C)
        case PSA_ALG_SHA_384:
            mbedtls_sha512_init( &operation->ctx.sha512 );
            ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 1 );
            break;
        case PSA_ALG_SHA_512:
            mbedtls_sha512_init( &operation->ctx.sha512 );
            ret = mbedtls_sha512_starts_ret( &operation->ctx.sha512, 0 );
            break;
#endif
        default:
            return( PSA_ALG_IS_HASH( alg ) ?
                    PSA_ERROR_NOT_SUPPORTED :
                    PSA_ERROR_INVALID_ARGUMENT );
    }
    if( ret == 0 )
        operation->alg = alg;
    else
        psa_hash_abort( operation );
    return( mbedtls_to_psa_error( ret ) );
}

psa_status_t psa_hash_update( psa_hash_operation_t *operation,
                              const uint8_t *input,
                              size_t input_length )
{
    int ret;

    /* Don't require hash implementations to behave correctly on a
     * zero-length input, which may have an invalid pointer. */
    if( input_length == 0 )
        return( PSA_SUCCESS );

    switch( operation->alg )
    {
#if defined(MBEDTLS_MD2_C)
        case PSA_ALG_MD2:
            ret = mbedtls_md2_update_ret( &operation->ctx.md2,
                                          input, input_length );
            break;
#endif
#if defined(MBEDTLS_MD4_C)
        case PSA_ALG_MD4:
            ret = mbedtls_md4_update_ret( &operation->ctx.md4,
                                          input, input_length );
            break;
#endif
#if defined(MBEDTLS_MD5_C)
        case PSA_ALG_MD5:
            ret = mbedtls_md5_update_ret( &operation->ctx.md5,
                                          input, input_length );
            break;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
        case PSA_ALG_RIPEMD160:
            ret = mbedtls_ripemd160_update_ret( &operation->ctx.ripemd160,
                                                input, input_length );
            break;
#endif
#if defined(MBEDTLS_SHA1_C)
        case PSA_ALG_SHA_1:
            ret = mbedtls_sha1_update_ret( &operation->ctx.sha1,
                                           input, input_length );
            break;
#endif
#if defined(MBEDTLS_SHA256_C)
        case PSA_ALG_SHA_224:
        case PSA_ALG_SHA_256:
            ret = mbedtls_sha256_update_ret( &operation->ctx.sha256,
                                             input, input_length );
            break;
#endif
#if defined(MBEDTLS_SHA512_C)
        case PSA_ALG_SHA_384:
        case PSA_ALG_SHA_512:
            ret = mbedtls_sha512_update_ret( &operation->ctx.sha512,
                                             input, input_length );
            break;
#endif
        default:
            ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
            break;
    }

    if( ret != 0 )
        psa_hash_abort( operation );
    return( mbedtls_to_psa_error( ret ) );
}

psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
                              uint8_t *hash,
                              size_t hash_size,
                              size_t *hash_length )
{
    psa_status_t status;
    int ret;
    size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );

    /* Fill the output buffer with something that isn't a valid hash
     * (barring an attack on the hash and deliberately-crafted input),
     * in case the caller doesn't check the return status properly. */
    *hash_length = hash_size;
    /* If hash_size is 0 then hash may be NULL and then the
     * call to memset would have undefined behavior. */
    if( hash_size != 0 )
        memset( hash, '!', hash_size );

    if( hash_size < actual_hash_length )
    {
        status = PSA_ERROR_BUFFER_TOO_SMALL;
        goto exit;
    }

    switch( operation->alg )
    {
#if defined(MBEDTLS_MD2_C)
        case PSA_ALG_MD2:
            ret = mbedtls_md2_finish_ret( &operation->ctx.md2, hash );
            break;
#endif
#if defined(MBEDTLS_MD4_C)
        case PSA_ALG_MD4:
            ret = mbedtls_md4_finish_ret( &operation->ctx.md4, hash );
            break;
#endif
#if defined(MBEDTLS_MD5_C)
        case PSA_ALG_MD5:
            ret = mbedtls_md5_finish_ret( &operation->ctx.md5, hash );
            break;
#endif
#if defined(MBEDTLS_RIPEMD160_C)
        case PSA_ALG_RIPEMD160:
            ret = mbedtls_ripemd160_finish_ret( &operation->ctx.ripemd160, hash );
            break;
#endif
#if defined(MBEDTLS_SHA1_C)
        case PSA_ALG_SHA_1:
            ret = mbedtls_sha1_finish_ret( &operation->ctx.sha1, hash );
            break;
#endif
#if defined(MBEDTLS_SHA256_C)
        case PSA_ALG_SHA_224:
        case PSA_ALG_SHA_256:
            ret = mbedtls_sha256_finish_ret( &operation->ctx.sha256, hash );
            break;
#endif
#if defined(MBEDTLS_SHA512_C)
        case PSA_ALG_SHA_384:
        case PSA_ALG_SHA_512:
            ret = mbedtls_sha512_finish_ret( &operation->ctx.sha512, hash );
            break;
#endif
        default:
            ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
            break;
    }
    status = mbedtls_to_psa_error( ret );

exit:
    if( status == PSA_SUCCESS )
    {
        *hash_length = actual_hash_length;
        return( psa_hash_abort( operation ) );
    }
    else
    {
        psa_hash_abort( operation );
        return( status );
    }
}

psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
                              const uint8_t *hash,
                              size_t hash_length )
{
    uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
    size_t actual_hash_length;
    psa_status_t status = psa_hash_finish( operation,
                                           actual_hash, sizeof( actual_hash ),
                                           &actual_hash_length );
    if( status != PSA_SUCCESS )
        return( status );
    if( actual_hash_length != hash_length )
        return( PSA_ERROR_INVALID_SIGNATURE );
    if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 )
        return( PSA_ERROR_INVALID_SIGNATURE );
    return( PSA_SUCCESS );
}



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

static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
    psa_algorithm_t alg,
    psa_key_type_t key_type,
    size_t key_bits,
    mbedtls_cipher_id_t* cipher_id )
{
    mbedtls_cipher_mode_t mode;
    mbedtls_cipher_id_t cipher_id_tmp;

    if( PSA_ALG_IS_AEAD( alg ) )
        alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );

    if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
    {
        switch( alg )
        {
            case PSA_ALG_ARC4:
                mode = MBEDTLS_MODE_STREAM;
                break;
            case PSA_ALG_CTR:
                mode = MBEDTLS_MODE_CTR;
                break;
            case PSA_ALG_CFB:
                mode = MBEDTLS_MODE_CFB;
                break;
            case PSA_ALG_OFB:
                mode = MBEDTLS_MODE_OFB;
                break;
            case PSA_ALG_CBC_NO_PADDING:
                mode = MBEDTLS_MODE_CBC;
                break;
            case PSA_ALG_CBC_PKCS7:
                mode = MBEDTLS_MODE_CBC;
                break;
            case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
                mode = MBEDTLS_MODE_CCM;
                break;
            case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
                mode = MBEDTLS_MODE_GCM;
                break;
            default:
                return( NULL );
        }
    }
    else if( alg == PSA_ALG_CMAC )
        mode = MBEDTLS_MODE_ECB;
    else if( alg == PSA_ALG_GMAC )
        mode = MBEDTLS_MODE_GCM;
    else
        return( NULL );

    switch( key_type )
    {
        case PSA_KEY_TYPE_AES:
            cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
            break;
        case PSA_KEY_TYPE_DES:
            /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
             * and 192 for three-key Triple-DES. */
            if( key_bits == 64 )
                cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
            else
                cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
            /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
             * but two-key Triple-DES is functionally three-key Triple-DES
             * with K1=K3, so that's how we present it to mbedtls. */
            if( key_bits == 128 )
                key_bits = 192;
            break;
        case PSA_KEY_TYPE_CAMELLIA:
            cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
            break;
        case PSA_KEY_TYPE_ARC4:
            cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
            break;
        default:
            return( NULL );
    }
    if( cipher_id != NULL )
        *cipher_id = cipher_id_tmp;

    return( mbedtls_cipher_info_from_values( cipher_id_tmp,
                                             (int) key_bits, mode ) );
}

#if defined(MBEDTLS_MD_C)
static size_t psa_get_hash_block_size( psa_algorithm_t alg )
{
    switch( alg )
    {
        case PSA_ALG_MD2:
            return( 16 );
        case PSA_ALG_MD4:
            return( 64 );
        case PSA_ALG_MD5:
            return( 64 );
        case PSA_ALG_RIPEMD160:
            return( 64 );
        case PSA_ALG_SHA_1:
            return( 64 );
        case PSA_ALG_SHA_224:
            return( 64 );
        case PSA_ALG_SHA_256:
            return( 64 );
        case PSA_ALG_SHA_384:
            return( 128 );
        case PSA_ALG_SHA_512:
            return( 128 );
        default:
            return( 0 );
    }
}
#endif /* MBEDTLS_MD_C */

/* Initialize the MAC operation structure. Once this function has been
 * called, psa_mac_abort can run and will do the right thing. */
static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
                                  psa_algorithm_t alg )
{
    psa_status_t status = PSA_ERROR_NOT_SUPPORTED;

    operation->alg = alg;
    operation->key_set = 0;
    operation->iv_set = 0;
    operation->iv_required = 0;
    operation->has_input = 0;
    operation->is_sign = 0;

#if defined(MBEDTLS_CMAC_C)
    if( alg == PSA_ALG_CMAC )
    {
        operation->iv_required = 0;
        mbedtls_cipher_init( &operation->ctx.cmac );
        status = PSA_SUCCESS;
    }
    else
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HMAC( operation->alg ) )
    {
        /* We'll set up the hash operation later in psa_hmac_setup_internal. */
        operation->ctx.hmac.hash_ctx.alg = 0;
        status = PSA_SUCCESS;
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        if( ! PSA_ALG_IS_MAC( alg ) )
            status = PSA_ERROR_INVALID_ARGUMENT;
    }

    if( status != PSA_SUCCESS )
        memset( operation, 0, sizeof( *operation ) );
    return( status );
}

#if defined(MBEDTLS_MD_C)
static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac )
{
    mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
    return( psa_hash_abort( &hmac->hash_ctx ) );
}

static void psa_hmac_init_internal( psa_hmac_internal_data *hmac )
{
    /* Instances of psa_hash_operation_s can be initialized by zeroization. */
    memset( hmac, 0, sizeof( *hmac ) );
}
#endif /* MBEDTLS_MD_C */

psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
{
    if( operation->alg == 0 )
    {
        /* The object has (apparently) been initialized but it is not
         * in use. It's ok to call abort on such an object, and there's
         * nothing to do. */
        return( PSA_SUCCESS );
    }
    else
#if defined(MBEDTLS_CMAC_C)
    if( operation->alg == PSA_ALG_CMAC )
    {
        mbedtls_cipher_free( &operation->ctx.cmac );
    }
    else
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HMAC( operation->alg ) )
    {
        psa_hmac_abort_internal( &operation->ctx.hmac );
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        /* Sanity check (shouldn't happen: operation->alg should
         * always have been initialized to a valid value). */
        goto bad_state;
    }

    operation->alg = 0;
    operation->key_set = 0;
    operation->iv_set = 0;
    operation->iv_required = 0;
    operation->has_input = 0;
    operation->is_sign = 0;

    return( PSA_SUCCESS );

bad_state:
    /* If abort is called on an uninitialized object, we can't trust
     * anything. Wipe the object in case it contains confidential data.
     * This may result in a memory leak if a pointer gets overwritten,
     * but it's too late to do anything about this. */
    memset( operation, 0, sizeof( *operation ) );
    return( PSA_ERROR_BAD_STATE );
}

#if defined(MBEDTLS_CMAC_C)
static int psa_cmac_setup( psa_mac_operation_t *operation,
                           size_t key_bits,
                           psa_key_slot_t *slot,
                           const mbedtls_cipher_info_t *cipher_info )
{
    int ret;

    operation->mac_size = cipher_info->block_size;

    ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
    if( ret != 0 )
        return( ret );

    ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac,
                                      slot->data.raw.data,
                                      key_bits );
    return( ret );
}
#endif /* MBEDTLS_CMAC_C */

#if defined(MBEDTLS_MD_C)
static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac,
                                             const uint8_t *key,
                                             size_t key_length,
                                             psa_algorithm_t hash_alg )
{
    unsigned char ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
    size_t i;
    size_t hash_size = PSA_HASH_SIZE( hash_alg );
    size_t block_size = psa_get_hash_block_size( hash_alg );
    psa_status_t status;

    /* Sanity checks on block_size, to guarantee that there won't be a buffer
     * overflow below. This should never trigger if the hash algorithm
     * is implemented correctly. */
    /* The size checks against the ipad and opad buffers cannot be written
     * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
     * because that triggers -Wlogical-op on GCC 7.3. */
    if( block_size > sizeof( ipad ) )
        return( PSA_ERROR_NOT_SUPPORTED );
    if( block_size > sizeof( hmac->opad ) )
        return( PSA_ERROR_NOT_SUPPORTED );
    if( block_size < hash_size )
        return( PSA_ERROR_NOT_SUPPORTED );

    if( key_length > block_size )
    {
        status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
        if( status != PSA_SUCCESS )
            goto cleanup;
        status = psa_hash_update( &hmac->hash_ctx, key, key_length );
        if( status != PSA_SUCCESS )
            goto cleanup;
        status = psa_hash_finish( &hmac->hash_ctx,
                                  ipad, sizeof( ipad ), &key_length );
        if( status != PSA_SUCCESS )
            goto cleanup;
    }
    /* A 0-length key is not commonly used in HMAC when used as a MAC,
     * but it is permitted. It is common when HMAC is used in HKDF, for
     * example. Don't call `memcpy` in the 0-length because `key` could be
     * an invalid pointer which would make the behavior undefined. */
    else if( key_length != 0 )
        memcpy( ipad, key, key_length );

    /* ipad contains the key followed by garbage. Xor and fill with 0x36
     * to create the ipad value. */
    for( i = 0; i < key_length; i++ )
        ipad[i] ^= 0x36;
    memset( ipad + key_length, 0x36, block_size - key_length );

    /* Copy the key material from ipad to opad, flipping the requisite bits,
     * and filling the rest of opad with the requisite constant. */
    for( i = 0; i < key_length; i++ )
        hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
    memset( hmac->opad + key_length, 0x5C, block_size - key_length );

    status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
    if( status != PSA_SUCCESS )
        goto cleanup;

    status = psa_hash_update( &hmac->hash_ctx, ipad, block_size );

cleanup:
    mbedtls_platform_zeroize( ipad, key_length );

    return( status );
}
#endif /* MBEDTLS_MD_C */

static psa_status_t psa_mac_setup( psa_mac_operation_t *operation,
                                   psa_key_handle_t handle,
                                   psa_algorithm_t alg,
                                   int is_sign )
{
    psa_status_t status;
    psa_key_slot_t *slot;
    size_t key_bits;
    psa_key_usage_t usage =
        is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
    unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
    psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );

    status = psa_mac_init( operation, full_length_alg );
    if( status != PSA_SUCCESS )
        return( status );
    if( is_sign )
        operation->is_sign = 1;

    status = psa_get_key_from_slot( handle, &slot, usage, alg );
    if( status != PSA_SUCCESS )
        goto exit;
    key_bits = psa_get_key_bits( slot );

#if defined(MBEDTLS_CMAC_C)
    if( full_length_alg == PSA_ALG_CMAC )
    {
        const mbedtls_cipher_info_t *cipher_info =
            mbedtls_cipher_info_from_psa( full_length_alg,
                                          slot->type, key_bits, NULL );
        int ret;
        if( cipher_info == NULL )
        {
            status = PSA_ERROR_NOT_SUPPORTED;
            goto exit;
        }
        operation->mac_size = cipher_info->block_size;
        ret = psa_cmac_setup( operation, key_bits, slot, cipher_info );
        status = mbedtls_to_psa_error( ret );
    }
    else
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HMAC( full_length_alg ) )
    {
        psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
        if( hash_alg == 0 )
        {
            status = PSA_ERROR_NOT_SUPPORTED;
            goto exit;
        }

        operation->mac_size = PSA_HASH_SIZE( hash_alg );
        /* Sanity check. This shouldn't fail on a valid configuration. */
        if( operation->mac_size == 0 ||
            operation->mac_size > sizeof( operation->ctx.hmac.opad ) )
        {
            status = PSA_ERROR_NOT_SUPPORTED;
            goto exit;
        }

        if( slot->type != PSA_KEY_TYPE_HMAC )
        {
            status = PSA_ERROR_INVALID_ARGUMENT;
            goto exit;
        }

        status = psa_hmac_setup_internal( &operation->ctx.hmac,
                                          slot->data.raw.data,
                                          slot->data.raw.bytes,
                                          hash_alg );
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        (void) key_bits;
        status = PSA_ERROR_NOT_SUPPORTED;
    }

    if( truncated == 0 )
    {
        /* The "normal" case: untruncated algorithm. Nothing to do. */
    }
    else if( truncated < 4 )
    {
        /* A very short MAC is too short for security since it can be
         * brute-forced. Ancient protocols with 32-bit MACs do exist,
         * so we make this our minimum, even though 32 bits is still
         * too small for security. */
        status = PSA_ERROR_NOT_SUPPORTED;
    }
    else if( truncated > operation->mac_size )
    {
        /* It's impossible to "truncate" to a larger length. */
        status = PSA_ERROR_INVALID_ARGUMENT;
    }
    else
        operation->mac_size = truncated;

exit:
    if( status != PSA_SUCCESS )
    {
        psa_mac_abort( operation );
    }
    else
    {
        operation->key_set = 1;
    }
    return( status );
}

psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation,
                                 psa_key_handle_t handle,
                                 psa_algorithm_t alg )
{
    return( psa_mac_setup( operation, handle, alg, 1 ) );
}

psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation,
                                   psa_key_handle_t handle,
                                   psa_algorithm_t alg )
{
    return( psa_mac_setup( operation, handle, alg, 0 ) );
}

psa_status_t psa_mac_update( psa_mac_operation_t *operation,
                             const uint8_t *input,
                             size_t input_length )
{
    psa_status_t status = PSA_ERROR_BAD_STATE;
    if( ! operation->key_set )
        goto cleanup;
    if( operation->iv_required && ! operation->iv_set )
        goto cleanup;
    operation->has_input = 1;

#if defined(MBEDTLS_CMAC_C)
    if( operation->alg == PSA_ALG_CMAC )
    {
        int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac,
                                              input, input_length );
        status = mbedtls_to_psa_error( ret );
    }
    else
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HMAC( operation->alg ) )
    {
        status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
                                  input_length );
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        /* This shouldn't happen if `operation` was initialized by
         * a setup function. */
        status = PSA_ERROR_BAD_STATE;
    }

cleanup:
    if( status != PSA_SUCCESS )
        psa_mac_abort( operation );
    return( status );
}

#if defined(MBEDTLS_MD_C)
static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac,
                                              uint8_t *mac,
                                              size_t mac_size )
{
    unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
    psa_algorithm_t hash_alg = hmac->hash_ctx.alg;
    size_t hash_size = 0;
    size_t block_size = psa_get_hash_block_size( hash_alg );
    psa_status_t status;

    status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
    if( status != PSA_SUCCESS )
        return( status );
    /* From here on, tmp needs to be wiped. */

    status = psa_hash_setup( &hmac->hash_ctx, hash_alg );
    if( status != PSA_SUCCESS )
        goto exit;

    status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size );
    if( status != PSA_SUCCESS )
        goto exit;

    status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size );
    if( status != PSA_SUCCESS )
        goto exit;

    status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
    if( status != PSA_SUCCESS )
        goto exit;

    memcpy( mac, tmp, mac_size );

exit:
    mbedtls_platform_zeroize( tmp, hash_size );
    return( status );
}
#endif /* MBEDTLS_MD_C */

static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation,
                                             uint8_t *mac,
                                             size_t mac_size )
{
    if( ! operation->key_set )
        return( PSA_ERROR_BAD_STATE );
    if( operation->iv_required && ! operation->iv_set )
        return( PSA_ERROR_BAD_STATE );

    if( mac_size < operation->mac_size )
        return( PSA_ERROR_BUFFER_TOO_SMALL );

#if defined(MBEDTLS_CMAC_C)
    if( operation->alg == PSA_ALG_CMAC )
    {
        uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
        int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
        if( ret == 0 )
            memcpy( mac, tmp, operation->mac_size );
        mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
        return( mbedtls_to_psa_error( ret ) );
    }
    else
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HMAC( operation->alg ) )
    {
        return( psa_hmac_finish_internal( &operation->ctx.hmac,
                                          mac, operation->mac_size ) );
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        /* This shouldn't happen if `operation` was initialized by
         * a setup function. */
        return( PSA_ERROR_BAD_STATE );
    }
}

psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation,
                                  uint8_t *mac,
                                  size_t mac_size,
                                  size_t *mac_length )
{
    psa_status_t status;

    /* Fill the output buffer with something that isn't a valid mac
     * (barring an attack on the mac and deliberately-crafted input),
     * in case the caller doesn't check the return status properly. */
    *mac_length = mac_size;
    /* If mac_size is 0 then mac may be NULL and then the
     * call to memset would have undefined behavior. */
    if( mac_size != 0 )
        memset( mac, '!', mac_size );

    if( ! operation->is_sign )
    {
        status = PSA_ERROR_BAD_STATE;
        goto cleanup;
    }

    status = psa_mac_finish_internal( operation, mac, mac_size );

cleanup:
    if( status == PSA_SUCCESS )
    {
        status = psa_mac_abort( operation );
        if( status == PSA_SUCCESS )
            *mac_length = operation->mac_size;
        else
            memset( mac, '!', mac_size );
    }
    else
        psa_mac_abort( operation );
    return( status );
}

psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation,
                                    const uint8_t *mac,
                                    size_t mac_length )
{
    uint8_t actual_mac[PSA_MAC_MAX_SIZE];
    psa_status_t status;

    if( operation->is_sign )
    {
        status = PSA_ERROR_BAD_STATE;
        goto cleanup;
    }
    if( operation->mac_size != mac_length )
    {
        status = PSA_ERROR_INVALID_SIGNATURE;
        goto cleanup;
    }

    status = psa_mac_finish_internal( operation,
                                      actual_mac, sizeof( actual_mac ) );

    if( safer_memcmp( mac, actual_mac, mac_length ) != 0 )
        status = PSA_ERROR_INVALID_SIGNATURE;

cleanup:
    if( status == PSA_SUCCESS )
        status = psa_mac_abort( operation );
    else
        psa_mac_abort( operation );

    mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) );

    return( status );
}



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

#if defined(MBEDTLS_RSA_C)
/* Decode the hash algorithm from alg and store the mbedtls encoding in
 * md_alg. Verify that the hash length is acceptable. */
static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg,
                                            size_t hash_length,
                                            mbedtls_md_type_t *md_alg )
{
    psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
    *md_alg = mbedtls_md_get_type( md_info );

    /* The Mbed TLS RSA module uses an unsigned int for hash length
     * parameters. Validate that it fits so that we don't risk an
     * overflow later. */
#if SIZE_MAX > UINT_MAX
    if( hash_length > UINT_MAX )
        return( PSA_ERROR_INVALID_ARGUMENT );
#endif

#if defined(MBEDTLS_PKCS1_V15)
    /* For PKCS#1 v1.5 signature, if using a hash, the hash length
     * must be correct. */
    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) &&
        alg != PSA_ALG_RSA_PKCS1V15_SIGN_RAW )
    {
        if( md_info == NULL )
            return( PSA_ERROR_NOT_SUPPORTED );
        if( mbedtls_md_get_size( md_info ) != hash_length )
            return( PSA_ERROR_INVALID_ARGUMENT );
    }
#endif /* MBEDTLS_PKCS1_V15 */

#if defined(MBEDTLS_PKCS1_V21)
    /* PSS requires a hash internally. */
    if( PSA_ALG_IS_RSA_PSS( alg ) )
    {
        if( md_info == NULL )
            return( PSA_ERROR_NOT_SUPPORTED );
    }
#endif /* MBEDTLS_PKCS1_V21 */

    return( PSA_SUCCESS );
}

static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa,
                                  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 status;
    int ret;
    mbedtls_md_type_t md_alg;

    status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
    if( status != PSA_SUCCESS )
        return( status );

    if( signature_size < mbedtls_rsa_get_len( rsa ) )
        return( PSA_ERROR_BUFFER_TOO_SMALL );

#if defined(MBEDTLS_PKCS1_V15)
    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
    {
        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
                                 MBEDTLS_MD_NONE );
        ret = mbedtls_rsa_pkcs1_sign( rsa,
                                      mbedtls_ctr_drbg_random,
                                      &global_data.ctr_drbg,
                                      MBEDTLS_RSA_PRIVATE,
                                      md_alg,
                                      (unsigned int) hash_length,
                                      hash,
                                      signature );
    }
    else
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
    if( PSA_ALG_IS_RSA_PSS( alg ) )
    {
        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
        ret = mbedtls_rsa_rsassa_pss_sign( rsa,
                                           mbedtls_ctr_drbg_random,
                                           &global_data.ctr_drbg,
                                           MBEDTLS_RSA_PRIVATE,
                                           MBEDTLS_MD_NONE,
                                           (unsigned int) hash_length,
                                           hash,
                                           signature );
    }
    else
#endif /* MBEDTLS_PKCS1_V21 */
    {
        return( PSA_ERROR_INVALID_ARGUMENT );
    }

    if( ret == 0 )
        *signature_length = mbedtls_rsa_get_len( rsa );
    return( mbedtls_to_psa_error( ret ) );
}

static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa,
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
                                    const uint8_t *signature,
                                    size_t signature_length )
{
    psa_status_t status;
    int ret;
    mbedtls_md_type_t md_alg;

    status = psa_rsa_decode_md_type( alg, hash_length, &md_alg );
    if( status != PSA_SUCCESS )
        return( status );

    if( signature_length < mbedtls_rsa_get_len( rsa ) )
        return( PSA_ERROR_BUFFER_TOO_SMALL );

#if defined(MBEDTLS_PKCS1_V15)
    if( PSA_ALG_IS_RSA_PKCS1V15_SIGN( alg ) )
    {
        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V15,
                                 MBEDTLS_MD_NONE );
        ret = mbedtls_rsa_pkcs1_verify( rsa,
                                        mbedtls_ctr_drbg_random,
                                        &global_data.ctr_drbg,
                                        MBEDTLS_RSA_PUBLIC,
                                        md_alg,
                                        (unsigned int) hash_length,
                                        hash,
                                        signature );
    }
    else
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
    if( PSA_ALG_IS_RSA_PSS( alg ) )
    {
        mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
        ret = mbedtls_rsa_rsassa_pss_verify( rsa,
                                             mbedtls_ctr_drbg_random,
                                             &global_data.ctr_drbg,
                                             MBEDTLS_RSA_PUBLIC,
                                             MBEDTLS_MD_NONE,
                                             (unsigned int) hash_length,
                                             hash,
                                             signature );
    }
    else
#endif /* MBEDTLS_PKCS1_V21 */
    {
        return( PSA_ERROR_INVALID_ARGUMENT );
    }

    /* Mbed TLS distinguishes "invalid padding" from "valid padding but
     * the rest of the signature is invalid". This has little use in
     * practice and PSA doesn't report this distinction. */
    if( ret == MBEDTLS_ERR_RSA_INVALID_PADDING )
        return( PSA_ERROR_INVALID_SIGNATURE );
    return( mbedtls_to_psa_error( ret ) );
}
#endif /* MBEDTLS_RSA_C */

#if defined(MBEDTLS_ECDSA_C)
/* `ecp` cannot be const because `ecp->grp` needs to be non-const
 * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det()
 * (even though these functions don't modify it). */
static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp,
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
                                    uint8_t *signature,
                                    size_t signature_size,
                                    size_t *signature_length )
{
    int ret;
    mbedtls_mpi r, s;
    size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
    mbedtls_mpi_init( &r );
    mbedtls_mpi_init( &s );

    if( signature_size < 2 * curve_bytes )
    {
        ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
        goto cleanup;
    }

#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
    if( PSA_ALG_DSA_IS_DETERMINISTIC( alg ) )
    {
        psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
        const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
        mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
        MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ecp->grp, &r, &s, &ecp->d,
                                                 hash, hash_length,
                                                 md_alg ) );
    }
    else
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
    {
        (void) alg;
        MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
                                             hash, hash_length,
                                             mbedtls_ctr_drbg_random,
                                             &global_data.ctr_drbg ) );
    }

    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
                                               signature,
                                               curve_bytes ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
                                               signature + curve_bytes,
                                               curve_bytes ) );

cleanup:
    mbedtls_mpi_free( &r );
    mbedtls_mpi_free( &s );
    if( ret == 0 )
        *signature_length = 2 * curve_bytes;
    return( mbedtls_to_psa_error( ret ) );
}

static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp,
                                      const uint8_t *hash,
                                      size_t hash_length,
                                      const uint8_t *signature,
                                      size_t signature_length )
{
    int ret;
    mbedtls_mpi r, s;
    size_t curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
    mbedtls_mpi_init( &r );
    mbedtls_mpi_init( &s );

    if( signature_length != 2 * curve_bytes )
        return( PSA_ERROR_INVALID_SIGNATURE );

    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
                                              signature,
                                              curve_bytes ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
                                              signature + curve_bytes,
                                              curve_bytes ) );

    ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
                                &ecp->Q, &r, &s );

cleanup:
    mbedtls_mpi_free( &r );
    mbedtls_mpi_free( &s );
    return( mbedtls_to_psa_error( ret ) );
}
#endif /* MBEDTLS_ECDSA_C */

psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
                                  psa_algorithm_t alg,
                                  const uint8_t *hash,
                                  size_t hash_length,
                                  uint8_t *signature,
                                  size_t signature_size,
                                  size_t *signature_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    *signature_length = signature_size;

    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
    if( status != PSA_SUCCESS )
        goto exit;
    if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
    {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto exit;
    }

#if defined(MBEDTLS_RSA_C)
    if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
    {
        status = psa_rsa_sign( slot->data.rsa,
                               alg,
                               hash, hash_length,
                               signature, signature_size,
                               signature_length );
    }
    else
#endif /* defined(MBEDTLS_RSA_C) */
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
    {
#if defined(MBEDTLS_ECDSA_C)
        if(
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
            PSA_ALG_IS_ECDSA( alg )
#else
            PSA_ALG_IS_RANDOMIZED_ECDSA( alg )
#endif
            )
            status = psa_ecdsa_sign( slot->data.ecp,
                                     alg,
                                     hash, hash_length,
                                     signature, signature_size,
                                     signature_length );
        else
#endif /* defined(MBEDTLS_ECDSA_C) */
        {
            status = PSA_ERROR_INVALID_ARGUMENT;
        }
    }
    else
#endif /* defined(MBEDTLS_ECP_C) */
    {
        status = PSA_ERROR_NOT_SUPPORTED;
    }

exit:
    /* 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 mac
     * (barring an attack on the mac and deliberately-crafted input),
     * in case the caller doesn't check the return status properly. */
    if( status == PSA_SUCCESS )
        memset( signature + *signature_length, '!',
                signature_size - *signature_length );
    else if( signature_size != 0 )
        memset( signature, '!', signature_size );
    /* If signature_size is 0 then we have nothing to do. We must not call
     * memset because signature may be NULL in this case. */
    return( status );
}

psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
                                    psa_algorithm_t alg,
                                    const uint8_t *hash,
                                    size_t hash_length,
                                    const uint8_t *signature,
                                    size_t signature_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
    if( status != PSA_SUCCESS )
        return( status );

#if defined(MBEDTLS_RSA_C)
    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
    {
        return( psa_rsa_verify( slot->data.rsa,
                                alg,
                                hash, hash_length,
                                signature, signature_length ) );
    }
    else
#endif /* defined(MBEDTLS_RSA_C) */
#if defined(MBEDTLS_ECP_C)
    if( PSA_KEY_TYPE_IS_ECC( slot->type ) )
    {
#if defined(MBEDTLS_ECDSA_C)
        if( PSA_ALG_IS_ECDSA( alg ) )
            return( psa_ecdsa_verify( slot->data.ecp,
                                      hash, hash_length,
                                      signature, signature_length ) );
        else
#endif /* defined(MBEDTLS_ECDSA_C) */
        {
            return( PSA_ERROR_INVALID_ARGUMENT );
        }
    }
    else
#endif /* defined(MBEDTLS_ECP_C) */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }
}

#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg,
                                           mbedtls_rsa_context *rsa )
{
    psa_algorithm_t hash_alg = PSA_ALG_RSA_OAEP_GET_HASH( alg );
    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
    mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
    mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
}
#endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */

psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
                                     const uint8_t *salt,
                                     size_t salt_length,
                                     uint8_t *output,
                                     size_t output_size,
                                     size_t *output_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    (void) input;
    (void) input_length;
    (void) salt;
    (void) output;
    (void) output_size;

    *output_length = 0;

    if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
    if( status != PSA_SUCCESS )
        return( status );
    if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ||
            PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) )
        return( PSA_ERROR_INVALID_ARGUMENT );

#if defined(MBEDTLS_RSA_C)
    if( PSA_KEY_TYPE_IS_RSA( slot->type ) )
    {
        mbedtls_rsa_context *rsa = slot->data.rsa;
        int ret;
        if( output_size < mbedtls_rsa_get_len( rsa ) )
            return( PSA_ERROR_INVALID_ARGUMENT );
#if defined(MBEDTLS_PKCS1_V15)
        if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
        {
            ret = mbedtls_rsa_pkcs1_encrypt( rsa,
                                             mbedtls_ctr_drbg_random,
                                             &global_data.ctr_drbg,
                                             MBEDTLS_RSA_PUBLIC,
                                             input_length,
                                             input,
                                             output );
        }
        else
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
        if( PSA_ALG_IS_RSA_OAEP( alg ) )
        {
            psa_rsa_oaep_set_padding_mode( alg, rsa );
            ret = mbedtls_rsa_rsaes_oaep_encrypt( rsa,
                                                  mbedtls_ctr_drbg_random,
                                                  &global_data.ctr_drbg,
                                                  MBEDTLS_RSA_PUBLIC,
                                                  salt, salt_length,
                                                  input_length,
                                                  input,
                                                  output );
        }
        else
#endif /* MBEDTLS_PKCS1_V21 */
        {
            return( PSA_ERROR_INVALID_ARGUMENT );
        }
        if( ret == 0 )
            *output_length = mbedtls_rsa_get_len( rsa );
        return( mbedtls_to_psa_error( ret ) );
    }
    else
#endif /* defined(MBEDTLS_RSA_C) */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }
}

psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle,
                                     psa_algorithm_t alg,
                                     const uint8_t *input,
                                     size_t input_length,
                                     const uint8_t *salt,
                                     size_t salt_length,
                                     uint8_t *output,
                                     size_t output_size,
                                     size_t *output_length )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    (void) input;
    (void) input_length;
    (void) salt;
    (void) output;
    (void) output_size;

    *output_length = 0;

    if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg );
    if( status != PSA_SUCCESS )
        return( status );
    if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) )
        return( PSA_ERROR_INVALID_ARGUMENT );

#if defined(MBEDTLS_RSA_C)
    if( slot->type == PSA_KEY_TYPE_RSA_KEYPAIR )
    {
        mbedtls_rsa_context *rsa = slot->data.rsa;
        int ret;

        if( input_length != mbedtls_rsa_get_len( rsa ) )
            return( PSA_ERROR_INVALID_ARGUMENT );

#if defined(MBEDTLS_PKCS1_V15)
        if( alg == PSA_ALG_RSA_PKCS1V15_CRYPT )
        {
            ret = mbedtls_rsa_pkcs1_decrypt( rsa,
                                             mbedtls_ctr_drbg_random,
                                             &global_data.ctr_drbg,
                                             MBEDTLS_RSA_PRIVATE,
                                             output_length,
                                             input,
                                             output,
                                             output_size );
        }
        else
#endif /* MBEDTLS_PKCS1_V15 */
#if defined(MBEDTLS_PKCS1_V21)
        if( PSA_ALG_IS_RSA_OAEP( alg ) )
        {
            psa_rsa_oaep_set_padding_mode( alg, rsa );
            ret = mbedtls_rsa_rsaes_oaep_decrypt( rsa,
                                                  mbedtls_ctr_drbg_random,
                                                  &global_data.ctr_drbg,
                                                  MBEDTLS_RSA_PRIVATE,
                                                  salt, salt_length,
                                                  output_length,
                                                  input,
                                                  output,
                                                  output_size );
        }
        else
#endif /* MBEDTLS_PKCS1_V21 */
        {
            return( PSA_ERROR_INVALID_ARGUMENT );
        }

        return( mbedtls_to_psa_error( ret ) );
    }
    else
#endif /* defined(MBEDTLS_RSA_C) */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }
}



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

/* Initialize the cipher operation structure. Once this function has been
 * called, psa_cipher_abort can run and will do the right thing. */
static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
                                     psa_algorithm_t alg )
{
    if( ! PSA_ALG_IS_CIPHER( alg ) )
    {
        memset( operation, 0, sizeof( *operation ) );
        return( PSA_ERROR_INVALID_ARGUMENT );
    }

    operation->alg = alg;
    operation->key_set = 0;
    operation->iv_set = 0;
    operation->iv_required = 1;
    operation->iv_size = 0;
    operation->block_size = 0;
    mbedtls_cipher_init( &operation->ctx.cipher );
    return( PSA_SUCCESS );
}

static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
                                      psa_key_handle_t handle,
                                      psa_algorithm_t alg,
                                      mbedtls_operation_t cipher_operation )
{
    int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    psa_status_t status;
    psa_key_slot_t *slot;
    size_t key_bits;
    const mbedtls_cipher_info_t *cipher_info = NULL;
    psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ?
                              PSA_KEY_USAGE_ENCRYPT :
                              PSA_KEY_USAGE_DECRYPT );

    status = psa_cipher_init( operation, alg );
    if( status != PSA_SUCCESS )
        return( status );

    status = psa_get_key_from_slot( handle, &slot, usage, alg);
    if( status != PSA_SUCCESS )
        return( status );
    key_bits = psa_get_key_bits( slot );

    cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
    if( cipher_info == NULL )
        return( PSA_ERROR_NOT_SUPPORTED );

    ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
    if( ret != 0 )
    {
        psa_cipher_abort( operation );
        return( mbedtls_to_psa_error( ret ) );
    }

#if defined(MBEDTLS_DES_C)
    if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 )
    {
        /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
        unsigned char keys[24];
        memcpy( keys, slot->data.raw.data, 16 );
        memcpy( keys + 16, slot->data.raw.data, 8 );
        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
                                     keys,
                                     192, cipher_operation );
    }
    else
#endif
    {
        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
                                     slot->data.raw.data,
                                     (int) key_bits, cipher_operation );
    }
    if( ret != 0 )
    {
        psa_cipher_abort( operation );
        return( mbedtls_to_psa_error( ret ) );
    }

#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
    switch( alg )
    {
        case PSA_ALG_CBC_NO_PADDING:
            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                   MBEDTLS_PADDING_NONE );
            break;
        case PSA_ALG_CBC_PKCS7:
            ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
                                                   MBEDTLS_PADDING_PKCS7 );
            break;
        default:
            /* The algorithm doesn't involve padding. */
            ret = 0;
            break;
    }
    if( ret != 0 )
    {
        psa_cipher_abort( operation );
        return( mbedtls_to_psa_error( ret ) );
    }
#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING

    operation->key_set = 1;
    operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
                              PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) );
    if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG )
    {
        operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type );
    }

    return( PSA_SUCCESS );
}

psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation,
                                       psa_key_handle_t handle,
                                       psa_algorithm_t alg )
{
    return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) );
}

psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation,
                                       psa_key_handle_t handle,
                                       psa_algorithm_t alg )
{
    return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) );
}

psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
                                     unsigned char *iv,
                                     size_t iv_size,
                                     size_t *iv_length )
{
    psa_status_t status;
    int ret;
    if( operation->iv_set || ! operation->iv_required )
    {
        status = PSA_ERROR_BAD_STATE;
        goto exit;
    }
    if( iv_size < operation->iv_size )
    {
        status = PSA_ERROR_BUFFER_TOO_SMALL;
        goto exit;
    }
    ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
                                   iv, operation->iv_size );
    if( ret != 0 )
    {
        status = mbedtls_to_psa_error( ret );
        goto exit;
    }

    *iv_length = operation->iv_size;
    status = psa_cipher_set_iv( operation, iv, *iv_length );

exit:
    if( status != PSA_SUCCESS )
        psa_cipher_abort( operation );
    return( status );
}

psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
                                const unsigned char *iv,
                                size_t iv_length )
{
    psa_status_t status;
    int ret;
    if( operation->iv_set || ! operation->iv_required )
    {
        status = PSA_ERROR_BAD_STATE;
        goto exit;
    }
    if( iv_length != operation->iv_size )
    {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto exit;
    }
    ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
    status = mbedtls_to_psa_error( ret );
exit:
    if( status == PSA_SUCCESS )
        operation->iv_set = 1;
    else
        psa_cipher_abort( operation );
    return( status );
}

psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
                                const uint8_t *input,
                                size_t input_length,
                                unsigned char *output,
                                size_t output_size,
                                size_t *output_length )
{
    psa_status_t status;
    int ret;
    size_t expected_output_size;
    if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
    {
        /* Take the unprocessed partial block left over from previous
         * update calls, if any, plus the input to this call. Remove
         * the last partial block, if any. You get the data that will be
         * output in this call. */
        expected_output_size =
            ( operation->ctx.cipher.unprocessed_len + input_length )
            / operation->block_size * operation->block_size;
    }
    else
    {
        expected_output_size = input_length;
    }

    if( output_size < expected_output_size )
    {
        status = PSA_ERROR_BUFFER_TOO_SMALL;
        goto exit;
    }

    ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
                                 input_length, output, output_length );
    status = mbedtls_to_psa_error( ret );
exit:
    if( status != PSA_SUCCESS )
        psa_cipher_abort( operation );
    return( status );
}

psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
                                uint8_t *output,
                                size_t output_size,
                                size_t *output_length )
{
    psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
    int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
    uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];

    if( ! operation->key_set )
    {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }
    if( operation->iv_required && ! operation->iv_set )
    {
        status = PSA_ERROR_BAD_STATE;
        goto error;
    }

    if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
        operation->alg == PSA_ALG_CBC_NO_PADDING &&
        operation->ctx.cipher.unprocessed_len != 0 )
    {
            status = PSA_ERROR_INVALID_ARGUMENT;
            goto error;
    }

    cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
                                        temp_output_buffer,
                                        output_length );
    if( cipher_ret != 0 )
    {
        status = mbedtls_to_psa_error( cipher_ret );
        goto error;
    }

    if( *output_length == 0 )
        ; /* Nothing to copy. Note that output may be NULL in this case. */
    else if( output_size >= *output_length )
        memcpy( output, temp_output_buffer, *output_length );
    else
    {
        status = PSA_ERROR_BUFFER_TOO_SMALL;
        goto error;
    }

    mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
    status = psa_cipher_abort( operation );

    return( status );

error:

    *output_length = 0;

    mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
    (void) psa_cipher_abort( operation );

    return( status );
}

psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
{
    if( operation->alg == 0 )
    {
        /* The object has (apparently) been initialized but it is not
         * in use. It's ok to call abort on such an object, and there's
         * nothing to do. */
        return( PSA_SUCCESS );
    }

    /* Sanity check (shouldn't happen: operation->alg should
     * always have been initialized to a valid value). */
    if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
        return( PSA_ERROR_BAD_STATE );

    mbedtls_cipher_free( &operation->ctx.cipher );

    operation->alg = 0;
    operation->key_set = 0;
    operation->iv_set = 0;
    operation->iv_size = 0;
    operation->block_size = 0;
    operation->iv_required = 0;

    return( PSA_SUCCESS );
}



/****************************************************************/
/* Key Policy */
/****************************************************************/

#if !defined(MBEDTLS_PSA_CRYPTO_SPM)
void psa_key_policy_set_usage( psa_key_policy_t *policy,
                               psa_key_usage_t usage,
                               psa_algorithm_t alg )
{
    policy->usage = usage;
    policy->alg = alg;
}

psa_key_usage_t psa_key_policy_get_usage( const psa_key_policy_t *policy )
{
    return( policy->usage );
}

psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy )
{
    return( policy->alg );
}
#endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */

psa_status_t psa_set_key_policy( psa_key_handle_t handle,
                                 const psa_key_policy_t *policy )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    if( policy == NULL )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_empty_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT |
                             PSA_KEY_USAGE_ENCRYPT |
                             PSA_KEY_USAGE_DECRYPT |
                             PSA_KEY_USAGE_SIGN |
                             PSA_KEY_USAGE_VERIFY |
                             PSA_KEY_USAGE_DERIVE ) ) != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );

    slot->policy = *policy;

    return( PSA_SUCCESS );
}

psa_status_t psa_get_key_policy( psa_key_handle_t handle,
                                 psa_key_policy_t *policy )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    if( policy == NULL )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    *policy = slot->policy;

    return( PSA_SUCCESS );
}



/****************************************************************/
/* Key Lifetime */
/****************************************************************/

psa_status_t psa_get_key_lifetime( psa_key_handle_t handle,
                                   psa_key_lifetime_t *lifetime )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    status = psa_get_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    *lifetime = slot->lifetime;

    return( PSA_SUCCESS );
}



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

typedef struct
{
    psa_key_slot_t *slot;
    const mbedtls_cipher_info_t *cipher_info;
    union
    {
#if defined(MBEDTLS_CCM_C)
        mbedtls_ccm_context ccm;
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_GCM_C)
        mbedtls_gcm_context gcm;
#endif /* MBEDTLS_GCM_C */
    } ctx;
    psa_algorithm_t core_alg;
    uint8_t full_tag_length;
    uint8_t tag_length;
} aead_operation_t;

static void psa_aead_abort( aead_operation_t *operation )
{
    switch( operation->core_alg )
    {
#if defined(MBEDTLS_CCM_C)
        case PSA_ALG_CCM:
            mbedtls_ccm_free( &operation->ctx.ccm );
            break;
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_GCM_C)
        case PSA_ALG_GCM:
            mbedtls_gcm_free( &operation->ctx.gcm );
            break;
#endif /* MBEDTLS_GCM_C */
    }
}

static psa_status_t psa_aead_setup( aead_operation_t *operation,
                                    psa_key_handle_t handle,
                                    psa_key_usage_t usage,
                                    psa_algorithm_t alg )
{
    psa_status_t status;
    size_t key_bits;
    mbedtls_cipher_id_t cipher_id;

    status = psa_get_key_from_slot( handle, &operation->slot, usage, alg );
    if( status != PSA_SUCCESS )
        return( status );

    key_bits = psa_get_key_bits( operation->slot );

    operation->cipher_info =
        mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
                                      &cipher_id );
    if( operation->cipher_info == NULL )
        return( PSA_ERROR_NOT_SUPPORTED );

    switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
    {
#if defined(MBEDTLS_CCM_C)
        case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
            operation->core_alg = PSA_ALG_CCM;
            operation->full_tag_length = 16;
            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            mbedtls_ccm_init( &operation->ctx.ccm );
            status = mbedtls_to_psa_error(
                mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
                                    operation->slot->data.raw.data,
                                    (unsigned int) key_bits ) );
            if( status != 0 )
                goto cleanup;
            break;
#endif /* MBEDTLS_CCM_C */

#if defined(MBEDTLS_GCM_C)
        case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
            operation->core_alg = PSA_ALG_GCM;
            operation->full_tag_length = 16;
            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
                return( PSA_ERROR_INVALID_ARGUMENT );
            mbedtls_gcm_init( &operation->ctx.gcm );
            status = mbedtls_to_psa_error(
                mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
                                    operation->slot->data.raw.data,
                                    (unsigned int) key_bits ) );
            break;
#endif /* MBEDTLS_GCM_C */

        default:
            return( PSA_ERROR_NOT_SUPPORTED );
    }

    if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
    {
        status = PSA_ERROR_INVALID_ARGUMENT;
        goto cleanup;
    }
    operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
    /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
     * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
     * In both cases, mbedtls_xxx will validate the tag length below. */

    return( PSA_SUCCESS );

cleanup:
    psa_aead_abort( operation );
    return( status );
}

psa_status_t psa_aead_encrypt( psa_key_handle_t handle,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
                               const uint8_t *additional_data,
                               size_t additional_data_length,
                               const uint8_t *plaintext,
                               size_t plaintext_length,
                               uint8_t *ciphertext,
                               size_t ciphertext_size,
                               size_t *ciphertext_length )
{
    psa_status_t status;
    aead_operation_t operation;
    uint8_t *tag;

    *ciphertext_length = 0;

    status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg );
    if( status != PSA_SUCCESS )
        return( status );

    /* For all currently supported modes, the tag is at the end of the
     * ciphertext. */
    if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
    {
        status = PSA_ERROR_BUFFER_TOO_SMALL;
        goto exit;
    }
    tag = ciphertext + plaintext_length;

#if defined(MBEDTLS_GCM_C)
    if( operation.core_alg == PSA_ALG_GCM )
    {
        status = mbedtls_to_psa_error(
            mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
                                       MBEDTLS_GCM_ENCRYPT,
                                       plaintext_length,
                                       nonce, nonce_length,
                                       additional_data, additional_data_length,
                                       plaintext, ciphertext,
                                       operation.tag_length, tag ) );
    }
    else
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C)
    if( operation.core_alg == PSA_ALG_CCM )
    {
        status = mbedtls_to_psa_error(
            mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
                                         plaintext_length,
                                         nonce, nonce_length,
                                         additional_data,
                                         additional_data_length,
                                         plaintext, ciphertext,
                                         tag, operation.tag_length ) );
    }
    else
#endif /* MBEDTLS_CCM_C */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }

    if( status != PSA_SUCCESS && ciphertext_size != 0 )
        memset( ciphertext, 0, ciphertext_size );

exit:
    psa_aead_abort( &operation );
    if( status == PSA_SUCCESS )
        *ciphertext_length = plaintext_length + operation.tag_length;
    return( status );
}

/* Locate the tag in a ciphertext buffer containing the encrypted data
 * followed by the tag. Return the length of the part preceding the tag in
 * *plaintext_length. This is the size of the plaintext in modes where
 * the encrypted data has the same size as the plaintext, such as
 * CCM and GCM. */
static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
                                                  const uint8_t *ciphertext,
                                                  size_t ciphertext_length,
                                                  size_t plaintext_size,
                                                  const uint8_t **p_tag )
{
    size_t payload_length;
    if( tag_length > ciphertext_length )
        return( PSA_ERROR_INVALID_ARGUMENT );
    payload_length = ciphertext_length - tag_length;
    if( payload_length > plaintext_size )
        return( PSA_ERROR_BUFFER_TOO_SMALL );
    *p_tag = ciphertext + payload_length;
    return( PSA_SUCCESS );
}

psa_status_t psa_aead_decrypt( psa_key_handle_t handle,
                               psa_algorithm_t alg,
                               const uint8_t *nonce,
                               size_t nonce_length,
                               const uint8_t *additional_data,
                               size_t additional_data_length,
                               const uint8_t *ciphertext,
                               size_t ciphertext_length,
                               uint8_t *plaintext,
                               size_t plaintext_size,
                               size_t *plaintext_length )
{
    psa_status_t status;
    aead_operation_t operation;
    const uint8_t *tag = NULL;

    *plaintext_length = 0;

    status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg );
    if( status != PSA_SUCCESS )
        return( status );

#if defined(MBEDTLS_GCM_C)
    if( operation.core_alg == PSA_ALG_GCM )
    {
        status = psa_aead_unpadded_locate_tag( operation.tag_length,
                                               ciphertext, ciphertext_length,
                                               plaintext_size, &tag );
        if( status != PSA_SUCCESS )
            goto exit;

        status = mbedtls_to_psa_error(
            mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
                                      ciphertext_length - operation.tag_length,
                                      nonce, nonce_length,
                                      additional_data,
                                      additional_data_length,
                                      tag, operation.tag_length,
                                      ciphertext, plaintext ) );
    }
    else
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C)
    if( operation.core_alg == PSA_ALG_CCM )
    {
        status = psa_aead_unpadded_locate_tag( operation.tag_length,
                                               ciphertext, ciphertext_length,
                                               plaintext_size, &tag );
        if( status != PSA_SUCCESS )
            goto exit;

        status = mbedtls_to_psa_error(
            mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
                                      ciphertext_length - operation.tag_length,
                                      nonce, nonce_length,
                                      additional_data,
                                      additional_data_length,
                                      ciphertext, plaintext,
                                      tag, operation.tag_length ) );
    }
    else
#endif /* MBEDTLS_CCM_C */
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }

    if( status != PSA_SUCCESS && plaintext_size != 0 )
        memset( plaintext, 0, plaintext_size );

exit:
    psa_aead_abort( &operation );
    if( status == PSA_SUCCESS )
        *plaintext_length = ciphertext_length - operation.tag_length;
    return( status );
}



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

psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
{
    psa_status_t status = PSA_SUCCESS;
    if( generator->alg == 0 )
    {
        /* The object has (apparently) been initialized but it is not
         * in use. It's ok to call abort on such an object, and there's
         * nothing to do. */
    }
    else
    if( generator->alg == PSA_ALG_SELECT_RAW )
    {
        if( generator->ctx.buffer.data != NULL )
        {
            mbedtls_platform_zeroize( generator->ctx.buffer.data,
                             generator->ctx.buffer.size );
            mbedtls_free( generator->ctx.buffer.data );
        }
    }
    else
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HKDF( generator->alg ) )
    {
        mbedtls_free( generator->ctx.hkdf.info );
        status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
    }
    else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
             /* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
             PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
    {
        if( generator->ctx.tls12_prf.key != NULL )
        {
            mbedtls_platform_zeroize( generator->ctx.tls12_prf.key,
                             generator->ctx.tls12_prf.key_len );
            mbedtls_free( generator->ctx.tls12_prf.key );
        }

        if( generator->ctx.tls12_prf.Ai_with_seed != NULL )
        {
            mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed,
                             generator->ctx.tls12_prf.Ai_with_seed_len );
            mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed );
        }
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        status = PSA_ERROR_BAD_STATE;
    }
    memset( generator, 0, sizeof( *generator ) );
    return( status );
}


psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
                                        size_t *capacity)
{
    *capacity = generator->capacity;
    return( PSA_SUCCESS );
}

#if defined(MBEDTLS_MD_C)
/* Read some bytes from an HKDF-based generator. This performs a chunk
 * of the expand phase of the HKDF algorithm. */
static psa_status_t psa_generator_hkdf_read( psa_hkdf_generator_t *hkdf,
                                             psa_algorithm_t hash_alg,
                                             uint8_t *output,
                                             size_t output_length )
{
    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
    psa_status_t status;

    while( output_length != 0 )
    {
        /* Copy what remains of the current block */
        uint8_t n = hash_length - hkdf->offset_in_block;
        if( n > output_length )
            n = (uint8_t) output_length;
        memcpy( output, hkdf->output_block + hkdf->offset_in_block, n );
        output += n;
        output_length -= n;
        hkdf->offset_in_block += n;
        if( output_length == 0 )
            break;
        /* We can't be wanting more output after block 0xff, otherwise
         * the capacity check in psa_generator_read() would have
         * prevented this call. It could happen only if the generator
         * object was corrupted or if this function is called directly
         * inside the library. */
        if( hkdf->block_number == 0xff )
            return( PSA_ERROR_BAD_STATE );

        /* We need a new block */
        ++hkdf->block_number;
        hkdf->offset_in_block = 0;
        status = psa_hmac_setup_internal( &hkdf->hmac,
                                          hkdf->prk, hash_length,
                                          hash_alg );
        if( status != PSA_SUCCESS )
            return( status );
        if( hkdf->block_number != 1 )
        {
            status = psa_hash_update( &hkdf->hmac.hash_ctx,
                                      hkdf->output_block,
                                      hash_length );
            if( status != PSA_SUCCESS )
                return( status );
        }
        status = psa_hash_update( &hkdf->hmac.hash_ctx,
                                  hkdf->info,
                                  hkdf->info_length );
        if( status != PSA_SUCCESS )
            return( status );
        status = psa_hash_update( &hkdf->hmac.hash_ctx,
                                  &hkdf->block_number, 1 );
        if( status != PSA_SUCCESS )
            return( status );
        status = psa_hmac_finish_internal( &hkdf->hmac,
                                           hkdf->output_block,
                                           sizeof( hkdf->output_block ) );
        if( status != PSA_SUCCESS )
            return( status );
    }

    return( PSA_SUCCESS );
}

static psa_status_t psa_generator_tls12_prf_generate_next_block(
    psa_tls12_prf_generator_t *tls12_prf,
    psa_algorithm_t alg )
{
    psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
    psa_hmac_internal_data hmac;
    psa_status_t status, cleanup_status;

    unsigned char *Ai;
    size_t Ai_len;

    /* We can't be wanting more output after block 0xff, otherwise
     * the capacity check in psa_generator_read() would have
     * prevented this call. It could happen only if the generator
     * object was corrupted or if this function is called directly
     * inside the library. */
    if( tls12_prf->block_number == 0xff )
        return( PSA_ERROR_BAD_STATE );

    /* We need a new block */
    ++tls12_prf->block_number;
    tls12_prf->offset_in_block = 0;

    /* Recall the definition of the TLS-1.2-PRF from RFC 5246:
     *
     * PRF(secret, label, seed) = P_<hash>(secret, label + seed)
     *
     * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
     *                        HMAC_hash(secret, A(2) + seed) +
     *                        HMAC_hash(secret, A(3) + seed) + ...
     *
     * A(0) = seed
     * A(i) = HMAC_hash( secret, A(i-1) )
     *
     * The `psa_tls12_prf_generator` structures saves the block
     * `HMAC_hash(secret, A(i) + seed)` from which the output
     * is currently extracted as `output_block`, while
     * `A(i) + seed` is stored in `Ai_with_seed`.
     *
     * Generating a new block means recalculating `Ai_with_seed`
     * from the A(i)-part of it, and afterwards recalculating
     * `output_block`.
     *
     * A(0) is computed at setup time.
     *
     */

    psa_hmac_init_internal( &hmac );

    /* We must distinguish the calculation of A(1) from those
     * of A(2) and higher, because A(0)=seed has a different
     * length than the other A(i). */
    if( tls12_prf->block_number == 1 )
    {
        Ai     = tls12_prf->Ai_with_seed + hash_length;
        Ai_len = tls12_prf->Ai_with_seed_len - hash_length;
    }
    else
    {
        Ai     = tls12_prf->Ai_with_seed;
        Ai_len = hash_length;
    }

    /* Compute A(i+1) = HMAC_hash(secret, A(i)) */
    status = psa_hmac_setup_internal( &hmac,
                                      tls12_prf->key,
                                      tls12_prf->key_len,
                                      hash_alg );
    if( status != PSA_SUCCESS )
        goto cleanup;

    status = psa_hash_update( &hmac.hash_ctx,
                              Ai, Ai_len );
    if( status != PSA_SUCCESS )
        goto cleanup;

    status = psa_hmac_finish_internal( &hmac,
                                       tls12_prf->Ai_with_seed,
                                       hash_length );
    if( status != PSA_SUCCESS )
        goto cleanup;

    /* Compute the next block `HMAC_hash(secret, A(i+1) + seed)`. */
    status = psa_hmac_setup_internal( &hmac,
                                      tls12_prf->key,
                                      tls12_prf->key_len,
                                      hash_alg );
    if( status != PSA_SUCCESS )
        goto cleanup;

    status = psa_hash_update( &hmac.hash_ctx,
                              tls12_prf->Ai_with_seed,
                              tls12_prf->Ai_with_seed_len );
    if( status != PSA_SUCCESS )
        goto cleanup;

    status = psa_hmac_finish_internal( &hmac,
                                       tls12_prf->output_block,
                                       hash_length );
    if( status != PSA_SUCCESS )
        goto cleanup;

cleanup:

    cleanup_status = psa_hmac_abort_internal( &hmac );
    if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
        status = cleanup_status;

    return( status );
}

/* Read some bytes from an TLS-1.2-PRF-based generator.
 * See Section 5 of RFC 5246. */
static psa_status_t psa_generator_tls12_prf_read(
                                        psa_tls12_prf_generator_t *tls12_prf,
                                        psa_algorithm_t alg,
                                        uint8_t *output,
                                        size_t output_length )
{
    psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
    psa_status_t status;

    while( output_length != 0 )
    {
        /* Copy what remains of the current block */
        uint8_t n = hash_length - tls12_prf->offset_in_block;

        /* Check if we have fully processed the current block. */
        if( n == 0 )
        {
            status = psa_generator_tls12_prf_generate_next_block( tls12_prf,
                                                                  alg );
            if( status != PSA_SUCCESS )
                return( status );

            continue;
        }

        if( n > output_length )
            n = (uint8_t) output_length;
        memcpy( output, tls12_prf->output_block + tls12_prf->offset_in_block,
                n );
        output += n;
        output_length -= n;
        tls12_prf->offset_in_block += n;
    }

    return( PSA_SUCCESS );
}
#endif /* MBEDTLS_MD_C */

psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
                                 uint8_t *output,
                                 size_t output_length )
{
    psa_status_t status;

    if( output_length > generator->capacity )
    {
        generator->capacity = 0;
        /* Go through the error path to wipe all confidential data now
         * that the generator object is useless. */
        status = PSA_ERROR_INSUFFICIENT_CAPACITY;
        goto exit;
    }
    if( output_length == 0 &&
        generator->capacity == 0 && generator->alg == 0 )
    {
        /* Edge case: this is a blank or finished generator, and 0
         * bytes were requested. The right error in this case could
         * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
         * INSUFFICIENT_CAPACITY, which is right for a finished
         * generator, for consistency with the case when
         * output_length > 0. */
        return( PSA_ERROR_INSUFFICIENT_CAPACITY );
    }
    generator->capacity -= output_length;

    if( generator->alg == PSA_ALG_SELECT_RAW )
    {
        /* Initially, the capacity of a selection generator is always
         * the size of the buffer, i.e. `generator->ctx.buffer.size`,
         * abbreviated in this comment as `size`. When the remaining
         * capacity is `c`, the next bytes to serve start `c` bytes
         * from the end of the buffer, i.e. `size - c` from the
         * beginning of the buffer. Since `generator->capacity` was just
         * decremented above, we need to serve the bytes from
         * `size - generator->capacity - output_length` to
         * `size - generator->capacity`. */
        size_t offset =
            generator->ctx.buffer.size - generator->capacity - output_length;
        memcpy( output, generator->ctx.buffer.data + offset, output_length );
        status = PSA_SUCCESS;
    }
    else
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HKDF( generator->alg ) )
    {
        psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( generator->alg );
        status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
                                          output, output_length );
    }
    else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
             PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
    {
        status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
                                               generator->alg, output,
                                               output_length );
    }
    else
#endif /* MBEDTLS_MD_C */
    {
        return( PSA_ERROR_BAD_STATE );
    }

exit:
    if( status != PSA_SUCCESS )
    {
        psa_generator_abort( generator );
        memset( output, '!', output_length );
    }
    return( status );
}

#if defined(MBEDTLS_DES_C)
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_DES_C */

psa_status_t psa_generator_import_key( psa_key_handle_t handle,
                                       psa_key_type_t type,
                                       size_t bits,
                                       psa_crypto_generator_t *generator )
{
    uint8_t *data = NULL;
    size_t bytes = PSA_BITS_TO_BYTES( bits );
    psa_status_t status;

    if( ! key_type_is_raw_bytes( type ) )
        return( PSA_ERROR_INVALID_ARGUMENT );
    if( bits % 8 != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );
    data = mbedtls_calloc( 1, bytes );
    if( data == NULL )
        return( PSA_ERROR_INSUFFICIENT_MEMORY );

    status = psa_generator_read( generator, data, bytes );
    if( status != PSA_SUCCESS )
        goto exit;
#if defined(MBEDTLS_DES_C)
    if( type == PSA_KEY_TYPE_DES )
        psa_des_set_key_parity( data, bytes );
#endif /* MBEDTLS_DES_C */
    status = psa_import_key( handle, type, data, bytes );

exit:
    mbedtls_free( data );
    return( status );
}



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

#if defined(MBEDTLS_MD_C)
/* Set up an HKDF-based generator. This is exactly the extract phase
 * of the HKDF algorithm.
 *
 * Note that if this function fails, you must call psa_generator_abort()
 * to potentially free embedded data structures and wipe confidential data.
 */
static psa_status_t psa_generator_hkdf_setup( psa_hkdf_generator_t *hkdf,
                                              const uint8_t *secret,
                                              size_t secret_length,
                                              psa_algorithm_t hash_alg,
                                              const uint8_t *salt,
                                              size_t salt_length,
                                              const uint8_t *label,
                                              size_t label_length )
{
    psa_status_t status;
    status = psa_hmac_setup_internal( &hkdf->hmac,
                                      salt, salt_length,
                                      PSA_ALG_HMAC_GET_HASH( hash_alg ) );
    if( status != PSA_SUCCESS )
        return( status );
    status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length );
    if( status != PSA_SUCCESS )
        return( status );
    status = psa_hmac_finish_internal( &hkdf->hmac,
                                       hkdf->prk,
                                       sizeof( hkdf->prk ) );
    if( status != PSA_SUCCESS )
        return( status );
    hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg );
    hkdf->block_number = 0;
    hkdf->info_length = label_length;
    if( label_length != 0 )
    {
        hkdf->info = mbedtls_calloc( 1, label_length );
        if( hkdf->info == NULL )
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        memcpy( hkdf->info, label, label_length );
    }
    return( PSA_SUCCESS );
}
#endif /* MBEDTLS_MD_C */

#if defined(MBEDTLS_MD_C)
/* Set up a TLS-1.2-prf-based generator (see RFC 5246, Section 5).
 *
 * Note that if this function fails, you must call psa_generator_abort()
 * to potentially free embedded data structures and wipe confidential data.
 */
static psa_status_t psa_generator_tls12_prf_setup(
    psa_tls12_prf_generator_t *tls12_prf,
    const unsigned char *key,
    size_t key_len,
    psa_algorithm_t hash_alg,
    const uint8_t *salt,
    size_t salt_length,
    const uint8_t *label,
    size_t label_length )
{
    uint8_t hash_length = PSA_HASH_SIZE( hash_alg );
    size_t Ai_with_seed_len = hash_length + salt_length + label_length;
    int overflow;

    tls12_prf->key = mbedtls_calloc( 1, key_len );
    if( tls12_prf->key == NULL )
        return( PSA_ERROR_INSUFFICIENT_MEMORY );
    tls12_prf->key_len = key_len;
    memcpy( tls12_prf->key, key, key_len );

    overflow = ( salt_length + label_length               < salt_length ) ||
               ( salt_length + label_length + hash_length < hash_length );
    if( overflow )
        return( PSA_ERROR_INVALID_ARGUMENT );

    tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len );
    if( tls12_prf->Ai_with_seed == NULL )
        return( PSA_ERROR_INSUFFICIENT_MEMORY );
    tls12_prf->Ai_with_seed_len = Ai_with_seed_len;

    /* Write `label + seed' at the end of the `A(i) + seed` buffer,
     * leaving the initial `hash_length` bytes unspecified for now. */
    if( label_length != 0 )
    {
        memcpy( tls12_prf->Ai_with_seed + hash_length,
                label, label_length );
    }

    if( salt_length != 0 )
    {
        memcpy( tls12_prf->Ai_with_seed + hash_length + label_length,
                salt, salt_length );
    }

    /* The first block gets generated when
     * psa_generator_read() is called. */
    tls12_prf->block_number    = 0;
    tls12_prf->offset_in_block = hash_length;

    return( PSA_SUCCESS );
}

/* Set up a TLS-1.2-PSK-to-MS-based generator. */
static psa_status_t psa_generator_tls12_psk_to_ms_setup(
    psa_tls12_prf_generator_t *tls12_prf,
    const unsigned char *psk,
    size_t psk_len,
    psa_algorithm_t hash_alg,
    const uint8_t *salt,
    size_t salt_length,
    const uint8_t *label,
    size_t label_length )
{
    psa_status_t status;
    unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];

    if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
        return( PSA_ERROR_INVALID_ARGUMENT );

    /* Quoting RFC 4279, Section 2:
     *
     * The premaster secret is formed as follows: if the PSK is N octets
     * long, concatenate a uint16 with the value N, N zero octets, a second
     * uint16 with the value N, and the PSK itself.
     */

    pms[0] = ( psk_len >> 8 ) & 0xff;
    pms[1] = ( psk_len >> 0 ) & 0xff;
    memset( pms + 2, 0, psk_len );
    pms[2 + psk_len + 0] = pms[0];
    pms[2 + psk_len + 1] = pms[1];
    memcpy( pms + 4 + psk_len, psk, psk_len );

    status = psa_generator_tls12_prf_setup( tls12_prf,
                                            pms, 4 + 2 * psk_len,
                                            hash_alg,
                                            salt, salt_length,
                                            label, label_length );

    mbedtls_platform_zeroize( pms, sizeof( pms ) );
    return( status );
}
#endif /* MBEDTLS_MD_C */

/* Note that if this function fails, you must call psa_generator_abort()
 * to potentially free embedded data structures and wipe confidential data.
 */
static psa_status_t psa_key_derivation_internal(
    psa_crypto_generator_t *generator,
    const uint8_t *secret, size_t secret_length,
    psa_algorithm_t alg,
    const uint8_t *salt, size_t salt_length,
    const uint8_t *label, size_t label_length,
    size_t capacity )
{
    psa_status_t status;
    size_t max_capacity;

    /* Set generator->alg even on failure so that abort knows what to do. */
    generator->alg = alg;

    if( alg == PSA_ALG_SELECT_RAW )
    {
        (void) salt;
        if( salt_length != 0 )
            return( PSA_ERROR_INVALID_ARGUMENT );
        (void) label;
        if( label_length != 0 )
            return( PSA_ERROR_INVALID_ARGUMENT );
        generator->ctx.buffer.data = mbedtls_calloc( 1, secret_length );
        if( generator->ctx.buffer.data == NULL )
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        memcpy( generator->ctx.buffer.data, secret, secret_length );
        generator->ctx.buffer.size = secret_length;
        max_capacity = secret_length;
        status = PSA_SUCCESS;
    }
    else
#if defined(MBEDTLS_MD_C)
    if( PSA_ALG_IS_HKDF( alg ) )
    {
        psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
        size_t hash_size = PSA_HASH_SIZE( hash_alg );
        if( hash_size == 0 )
            return( PSA_ERROR_NOT_SUPPORTED );
        max_capacity = 255 * hash_size;
        status = psa_generator_hkdf_setup( &generator->ctx.hkdf,
                                           secret, secret_length,
                                           hash_alg,
                                           salt, salt_length,
                                           label, label_length );
    }
    /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
    else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
             PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
    {
        psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
        size_t hash_size = PSA_HASH_SIZE( hash_alg );

        /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */
        if( hash_alg != PSA_ALG_SHA_256 &&
            hash_alg != PSA_ALG_SHA_384 )
        {
            return( PSA_ERROR_NOT_SUPPORTED );
        }

        max_capacity = 255 * hash_size;

        if( PSA_ALG_IS_TLS12_PRF( alg ) )
        {
            status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
                                                    secret, secret_length,
                                                    hash_alg, salt, salt_length,
                                                    label, label_length );
        }
        else
        {
            status = psa_generator_tls12_psk_to_ms_setup(
                &generator->ctx.tls12_prf,
                secret, secret_length,
                hash_alg, salt, salt_length,
                label, label_length );
        }
    }
    else
#endif
    {
        return( PSA_ERROR_NOT_SUPPORTED );
    }

    if( status != PSA_SUCCESS )
        return( status );

    if( capacity <= max_capacity )
        generator->capacity = capacity;
    else if( capacity == PSA_GENERATOR_UNBRIDLED_CAPACITY )
        generator->capacity = max_capacity;
    else
        return( PSA_ERROR_INVALID_ARGUMENT );

    return( PSA_SUCCESS );
}

psa_status_t psa_key_derivation( psa_crypto_generator_t *generator,
                                 psa_key_handle_t handle,
                                 psa_algorithm_t alg,
                                 const uint8_t *salt,
                                 size_t salt_length,
                                 const uint8_t *label,
                                 size_t label_length,
                                 size_t capacity )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    if( generator->alg != 0 )
        return( PSA_ERROR_BAD_STATE );

    /* Make sure that alg is a key derivation algorithm. This prevents
     * key selection algorithms, which psa_key_derivation_internal
     * accepts for the sake of key agreement. */
    if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg );
    if( status != PSA_SUCCESS )
        return( status );

    if( slot->type != PSA_KEY_TYPE_DERIVE )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_key_derivation_internal( generator,
                                          slot->data.raw.data,
                                          slot->data.raw.bytes,
                                          alg,
                                          salt, salt_length,
                                          label, label_length,
                                          capacity );
    if( status != PSA_SUCCESS )
        psa_generator_abort( generator );
    return( status );
}



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

#if defined(MBEDTLS_ECDH_C)
static psa_status_t psa_key_agreement_ecdh( const uint8_t *peer_key,
                                            size_t peer_key_length,
                                            const mbedtls_ecp_keypair *our_key,
                                            uint8_t *shared_secret,
                                            size_t shared_secret_size,
                                            size_t *shared_secret_length )
{
    mbedtls_pk_context pk;
    mbedtls_ecp_keypair *their_key = NULL;
    mbedtls_ecdh_context ecdh;
    int ret;
    mbedtls_ecdh_init( &ecdh );
    mbedtls_pk_init( &pk );

    ret = mbedtls_pk_parse_public_key( &pk, peer_key, peer_key_length );
    if( ret != 0 )
        goto exit;
    switch( mbedtls_pk_get_type( &pk ) )
    {
        case MBEDTLS_PK_ECKEY:
        case MBEDTLS_PK_ECKEY_DH:
            break;
        default:
            ret = MBEDTLS_ERR_ECP_INVALID_KEY;
            goto exit;
    }
    their_key = mbedtls_pk_ec( pk );
    if( their_key->grp.id != our_key->grp.id )
    {
        ret = MBEDTLS_ERR_ECP_INVALID_KEY;
        goto exit;
    }

    ret = mbedtls_ecdh_get_params( &ecdh, their_key, MBEDTLS_ECDH_THEIRS );
    if( ret != 0 )
        goto exit;
    ret = mbedtls_ecdh_get_params( &ecdh, our_key, MBEDTLS_ECDH_OURS );
    if( ret != 0 )
        goto exit;

    ret = mbedtls_ecdh_calc_secret( &ecdh,
                                    shared_secret_length,
                                    shared_secret, shared_secret_size,
                                    mbedtls_ctr_drbg_random,
                                    &global_data.ctr_drbg );

exit:
    mbedtls_pk_free( &pk );
    mbedtls_ecdh_free( &ecdh );
    return( mbedtls_to_psa_error( ret ) );
}
#endif /* MBEDTLS_ECDH_C */

#define PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE MBEDTLS_ECP_MAX_BYTES

/* Note that if this function fails, you must call psa_generator_abort()
 * to potentially free embedded data structures and wipe confidential data.
 */
static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator,
                                                psa_key_slot_t *private_key,
                                                const uint8_t *peer_key,
                                                size_t peer_key_length,
                                                psa_algorithm_t alg )
{
    psa_status_t status;
    uint8_t shared_secret[PSA_KEY_AGREEMENT_MAX_SHARED_SECRET_SIZE];
    size_t shared_secret_length = 0;

    /* Step 1: run the secret agreement algorithm to generate the shared
     * secret. */
    switch( PSA_ALG_KEY_AGREEMENT_GET_BASE( alg ) )
    {
#if defined(MBEDTLS_ECDH_C)
        case PSA_ALG_ECDH_BASE:
            if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( private_key->type ) )
                return( PSA_ERROR_INVALID_ARGUMENT );
            status = psa_key_agreement_ecdh( peer_key, peer_key_length,
                                             private_key->data.ecp,
                                             shared_secret,
                                             sizeof( shared_secret ),
                                             &shared_secret_length );
            break;
#endif /* MBEDTLS_ECDH_C */
        default:
            (void) private_key;
            (void) peer_key;
            (void) peer_key_length;
            return( PSA_ERROR_NOT_SUPPORTED );
    }
    if( status != PSA_SUCCESS )
        goto exit;

    /* Step 2: set up the key derivation to generate key material from
     * the shared secret. */
    status = psa_key_derivation_internal( generator,
                                          shared_secret, shared_secret_length,
                                          PSA_ALG_KEY_AGREEMENT_GET_KDF( alg ),
                                          NULL, 0, NULL, 0,
                                          PSA_GENERATOR_UNBRIDLED_CAPACITY );
exit:
    mbedtls_platform_zeroize( shared_secret, shared_secret_length );
    return( status );
}

psa_status_t psa_key_agreement( psa_crypto_generator_t *generator,
                                psa_key_handle_t private_key,
                                const uint8_t *peer_key,
                                size_t peer_key_length,
                                psa_algorithm_t alg )
{
    psa_key_slot_t *slot;
    psa_status_t status;
    if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) )
        return( PSA_ERROR_INVALID_ARGUMENT );
    status = psa_get_key_from_slot( private_key, &slot,
                                    PSA_KEY_USAGE_DERIVE, alg );
    if( status != PSA_SUCCESS )
        return( status );
    status = psa_key_agreement_internal( generator,
                                         slot,
                                         peer_key, peer_key_length,
                                         alg );
    if( status != PSA_SUCCESS )
        psa_generator_abort( generator );
    return( status );
}



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

psa_status_t psa_generate_random( uint8_t *output,
                                  size_t output_size )
{
    int ret;
    GUARD_MODULE_INITIALIZED;

    ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size );
    return( mbedtls_to_psa_error( ret ) );
}

#if ( defined(MBEDTLS_ENTROPY_NV_SEED) && defined(MBEDTLS_PSA_HAS_ITS_IO) )

/* Support function for error conversion between psa_its error codes to psa crypto */
static psa_status_t its_to_psa_error( psa_its_status_t ret )
{
    switch( ret )
    {
        case PSA_ITS_SUCCESS:
            return( PSA_SUCCESS );

        case PSA_ITS_ERROR_KEY_NOT_FOUND:
            return( PSA_ERROR_EMPTY_SLOT );

        case PSA_ITS_ERROR_STORAGE_FAILURE:
            return( PSA_ERROR_STORAGE_FAILURE );

        case PSA_ITS_ERROR_INSUFFICIENT_SPACE:
            return( PSA_ERROR_INSUFFICIENT_STORAGE );

        case PSA_ITS_ERROR_INVALID_KEY:
        case PSA_ITS_ERROR_OFFSET_INVALID:
        case PSA_ITS_ERROR_INCORRECT_SIZE:
        case PSA_ITS_ERROR_BAD_POINTER:
            return( PSA_ERROR_INVALID_ARGUMENT );

        case PSA_ITS_ERROR_FLAGS_NOT_SUPPORTED:
            return( PSA_ERROR_NOT_SUPPORTED );

        case PSA_ITS_ERROR_WRITE_ONCE:
            return( PSA_ERROR_OCCUPIED_SLOT );

        default:
            return( PSA_ERROR_UNKNOWN_ERROR );
    }
}

psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed,
                                         size_t seed_size )
{
    psa_status_t status;
    psa_its_status_t its_status;
    struct psa_its_info_t p_info;
    if( global_data.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 );

    its_status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
    status = its_to_psa_error( its_status );

    if( PSA_ITS_ERROR_KEY_NOT_FOUND == its_status ) /* No seed exists */
    {
        its_status = psa_its_set( PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0 );
        status = its_to_psa_error( its_status );
    }
    else if( PSA_ITS_SUCCESS == its_status )
    {
        /* You should not be here. Seed needs to be injected only once */
        status = PSA_ERROR_NOT_PERMITTED;
    }
    return( status );
}
#endif

psa_status_t psa_generate_key( psa_key_handle_t handle,
                               psa_key_type_t type,
                               size_t bits,
                               const void *extra,
                               size_t extra_size )
{
    psa_key_slot_t *slot;
    psa_status_t status;

    if( extra == NULL && extra_size != 0 )
        return( PSA_ERROR_INVALID_ARGUMENT );

    status = psa_get_empty_key_slot( handle, &slot );
    if( status != PSA_SUCCESS )
        return( status );

    if( key_type_is_raw_bytes( type ) )
    {
        status = prepare_raw_data_slot( type, bits, &slot->data.raw );
        if( status != PSA_SUCCESS )
            return( status );
        status = psa_generate_random( slot->data.raw.data,
                                      slot->data.raw.bytes );
        if( status != PSA_SUCCESS )
        {
            mbedtls_free( slot->data.raw.data );
            return( status );
        }
#if defined(MBEDTLS_DES_C)
        if( type == PSA_KEY_TYPE_DES )
            psa_des_set_key_parity( slot->data.raw.data,
                                    slot->data.raw.bytes );
#endif /* MBEDTLS_DES_C */
    }
    else

#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
    if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
    {
        mbedtls_rsa_context *rsa;
        int ret;
        int exponent = 65537;
        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
            return( PSA_ERROR_NOT_SUPPORTED );
        /* Accept only byte-aligned keys, for the same reasons as
         * in psa_import_rsa_key(). */
        if( bits % 8 != 0 )
            return( PSA_ERROR_NOT_SUPPORTED );
        if( extra != NULL )
        {
            const psa_generate_key_extra_rsa *p = extra;
            if( extra_size != sizeof( *p ) )
                return( PSA_ERROR_INVALID_ARGUMENT );
#if INT_MAX < 0xffffffff
            /* Check that the uint32_t value passed by the caller fits
             * in the range supported by this implementation. */
            if( p->e > INT_MAX )
                return( PSA_ERROR_NOT_SUPPORTED );
#endif
            exponent = p->e;
        }
        rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
        if( rsa == NULL )
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
        ret = mbedtls_rsa_gen_key( rsa,
                                   mbedtls_ctr_drbg_random,
                                   &global_data.ctr_drbg,
                                   (unsigned int) bits,
                                   exponent );
        if( ret != 0 )
        {
            mbedtls_rsa_free( rsa );
            mbedtls_free( rsa );
            return( mbedtls_to_psa_error( ret ) );
        }
        slot->data.rsa = rsa;
    }
    else
#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */

#if defined(MBEDTLS_ECP_C)
    if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
    {
        psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
        mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
        const mbedtls_ecp_curve_info *curve_info =
            mbedtls_ecp_curve_info_from_grp_id( grp_id );
        mbedtls_ecp_keypair *ecp;
        int ret;
        if( extra != NULL )
            return( PSA_ERROR_NOT_SUPPORTED );
        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
            return( PSA_ERROR_NOT_SUPPORTED );
        if( curve_info->bit_size != bits )
            return( PSA_ERROR_INVALID_ARGUMENT );
        ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
        if( ecp == NULL )
            return( PSA_ERROR_INSUFFICIENT_MEMORY );
        mbedtls_ecp_keypair_init( ecp );
        ret = mbedtls_ecp_gen_key( grp_id, ecp,
                                   mbedtls_ctr_drbg_random,
                                   &global_data.ctr_drbg );
        if( ret != 0 )
        {
            mbedtls_ecp_keypair_free( ecp );
            mbedtls_free( ecp );
            return( mbedtls_to_psa_error( ret ) );
        }
        slot->data.ecp = ecp;
    }
    else
#endif /* MBEDTLS_ECP_C */

        return( PSA_ERROR_NOT_SUPPORTED );

    slot->type = type;

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT )
    {
        return( psa_save_generated_persistent_key( slot, bits ) );
    }
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */

    return( status );
}


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

psa_status_t mbedtls_psa_crypto_configure_entropy_sources(
    void (* entropy_init )( mbedtls_entropy_context *ctx ),
    void (* entropy_free )( mbedtls_entropy_context *ctx ) )
{
    if( global_data.rng_state != RNG_NOT_INITIALIZED )
        return( PSA_ERROR_BAD_STATE );
    global_data.entropy_init = entropy_init;
    global_data.entropy_free = entropy_free;
    return( PSA_SUCCESS );
}

void mbedtls_psa_crypto_free( void )
{
    psa_wipe_all_key_slots( );
    if( global_data.rng_state != RNG_NOT_INITIALIZED )
    {
        mbedtls_ctr_drbg_free( &global_data.ctr_drbg );
        global_data.entropy_free( &global_data.entropy );
    }
    /* Wipe all remaining data, including configuration.
     * In particular, this sets all state indicator to the value
     * indicating "uninitialized". */
    mbedtls_platform_zeroize( &global_data, sizeof( global_data ) );
}

psa_status_t psa_crypto_init( void )
{
    psa_status_t status;
    const unsigned char drbg_seed[] = "PSA";

    /* Double initialization is explicitly allowed. */
    if( global_data.initialized != 0 )
        return( PSA_SUCCESS );

    /* Set default configuration if
     * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */
    if( global_data.entropy_init == NULL )
        global_data.entropy_init = mbedtls_entropy_init;
    if( global_data.entropy_free == NULL )
        global_data.entropy_free = mbedtls_entropy_free;

    /* Initialize the random generator. */
    global_data.entropy_init( &global_data.entropy );
    mbedtls_ctr_drbg_init( &global_data.ctr_drbg );
    global_data.rng_state = RNG_INITIALIZED;
    status = mbedtls_to_psa_error(
        mbedtls_ctr_drbg_seed( &global_data.ctr_drbg,
                               mbedtls_entropy_func,
                               &global_data.entropy,
                               drbg_seed, sizeof( drbg_seed ) - 1 ) );
    if( status != PSA_SUCCESS )
        goto exit;
    global_data.rng_state = RNG_SEEDED;

    status = psa_initialize_key_slots( );
    if( status != PSA_SUCCESS )
        goto exit;

    /* All done. */
    global_data.initialized = 1;

exit:
    if( status != PSA_SUCCESS )
        mbedtls_psa_crypto_free( );
    return( status );
}

#endif /* MBEDTLS_PSA_CRYPTO_C */
