/* BEGIN_HEADER */
#include <stdint.h>

#include "psa_crypto_helpers.h"
#include "psa_crypto_storage.h"

typedef enum
{
    CLOSE_BY_CLOSE, /**< Close the handle(s). */
    CLOSE_BY_DESTROY, /**< Destroy the handle(s). */
    CLOSE_BY_SHUTDOWN, /**< Deinit and reinit without closing handles. */
    CLOSE_BY_CLOSE_WITH_SHUTDOWN, /**< Close handle(s) then deinit/reinit. */
    CLOSE_BY_DESTROY_WITH_SHUTDOWN, /**< Destroy handle(s) then deinit/reinit. */
} close_method_t;

typedef enum
{
    KEEP_OPEN,
    CLOSE_BEFORE,
    CLOSE_AFTER,
} reopen_policy_t;

typedef enum
{
    INVALID_HANDLE_0,
    INVALID_HANDLE_UNOPENED,
    INVALID_HANDLE_CLOSED,
    INVALID_HANDLE_HUGE,
} invalid_handle_construction_t;

/* All test functions that create persistent keys must call
 * `TEST_USES_KEY_ID( key_id )` before creating a persistent key with this
 * identifier, and must call psa_purge_key_storage() in their cleanup
 * code. */

#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_key_id_t key_ids_used_in_test[9];
static size_t num_key_ids_used;

/* Record a key id as potentially used in a test case. */
static int test_uses_key_id( psa_key_id_t key_id )
{
    size_t i;
    if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
    {
        /* Don't touch key id values that designate non-key files. */
        return( 1 );
    }
    for( i = 0; i < num_key_ids_used ; i++ )
    {
        if( key_id == key_ids_used_in_test[i] )
            return( 1 );
    }
    if( num_key_ids_used == ARRAY_LENGTH( key_ids_used_in_test ) )
        return( 0 );
    key_ids_used_in_test[num_key_ids_used] = key_id;
    ++num_key_ids_used;
    return( 1 );
}
#define TEST_USES_KEY_ID( key_id )                       \
    TEST_ASSERT( test_uses_key_id( key_id ) )

/* Destroy all key ids that may have been created by the current test case. */
static void psa_purge_key_storage( void )
{
    size_t i;
    for( i = 0; i < num_key_ids_used; i++ )
        psa_destroy_persistent_key( key_ids_used_in_test[i] );
    num_key_ids_used = 0;
}
#else
#define TEST_USES_KEY_ID( key_id ) ( (void) ( key_id ) )
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */

/** Apply \p close_method to invalidate the specified handles:
 * close it, destroy it, or do nothing;
 */
static int invalidate_handle( close_method_t close_method,
                              psa_key_handle_t handle )
{
    switch( close_method )
    {
        case CLOSE_BY_CLOSE:
        case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
            PSA_ASSERT( psa_close_key( handle ) );
            break;
        case CLOSE_BY_DESTROY:
        case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
            PSA_ASSERT( psa_destroy_key( handle ) );
            break;
        case CLOSE_BY_SHUTDOWN:
            break;
    }
    return( 1 );
exit:
    return( 0 );
}

/** Restart the PSA subsystem if \p close_method says so. */
static int invalidate_psa( close_method_t close_method )
{
    switch( close_method )
    {
        case CLOSE_BY_CLOSE:
        case CLOSE_BY_DESTROY:
            return( 1 );
        case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
        case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
            /* All keys must have been closed. */
            PSA_DONE( );
            break;
        case CLOSE_BY_SHUTDOWN:
            /* Some keys may remain behind, and we're testing that this
             * properly closes them. */
            mbedtls_psa_crypto_free( );
            break;
    }

    PSA_ASSERT( psa_crypto_init( ) );
    ASSERT_PSA_PRISTINE( );
    return( 1 );

exit:
    return( 0 );
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_PSA_CRYPTO_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void transient_slot_lifecycle( int usage_arg, int alg_arg,
                               int type_arg, data_t *key_data,
                               int close_method_arg )
{
    psa_algorithm_t alg = alg_arg;
    psa_key_usage_t usage_flags = usage_arg;
    psa_key_type_t type = type_arg;
    close_method_t close_method = close_method_arg;
    psa_key_handle_t handle = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    PSA_ASSERT( psa_crypto_init( ) );

    /* Import a key. */
    psa_set_key_usage_flags( &attributes, usage_flags );
    psa_set_key_algorithm( &attributes, alg );
    psa_set_key_type( &attributes, type );
    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                &handle ) );
    TEST_ASSERT( handle != 0 );
    PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
    TEST_EQUAL( psa_get_key_type( &attributes ), type );

    /* Do something that invalidates the handle. */
    if( ! invalidate_handle( close_method, handle ) )
        goto exit;
    if( ! invalidate_psa( close_method ) )
        goto exit;

    /* Test that the handle is now invalid. */
    TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
                PSA_ERROR_INVALID_HANDLE );
    TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );

exit:
    PSA_DONE( );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
                                int usage_arg, int alg_arg, int alg2_arg,
                                int type_arg, data_t *key_data,
                                int close_method_arg )
{
    psa_key_lifetime_t lifetime = lifetime_arg;
    psa_key_id_t id = id_arg;
    psa_algorithm_t alg = alg_arg;
    psa_algorithm_t alg2 = alg2_arg;
    psa_key_usage_t usage_flags = usage_arg;
    psa_key_type_t type = type_arg;
    close_method_t close_method = close_method_arg;
    psa_key_handle_t handle = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_attributes_t read_attributes = PSA_KEY_ATTRIBUTES_INIT;
    uint8_t *reexported = NULL;
    size_t reexported_length = -1;

    TEST_USES_KEY_ID( id );

    PSA_ASSERT( psa_crypto_init( ) );

    /* Get a handle and import a key. */
    psa_set_key_id( &attributes, id );
    psa_set_key_lifetime( &attributes, lifetime );
    psa_set_key_type( &attributes, type );
    psa_set_key_usage_flags( &attributes, usage_flags );
    psa_set_key_algorithm( &attributes, alg );
    psa_set_key_enrollment_algorithm( &attributes, alg2 );
    PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
                                &handle ) );
    TEST_ASSERT( handle != 0 );
    PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
    TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
    TEST_EQUAL( psa_get_key_id( &attributes ), id );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
    TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
    TEST_EQUAL( psa_get_key_type( &attributes ), type );

    /* Close the key and reopen it. */
    PSA_ASSERT( psa_close_key( handle ) );
    PSA_ASSERT( psa_open_key( id, &handle ) );
    PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
    TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
    TEST_EQUAL( psa_get_key_id( &attributes ), id );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
    TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
    TEST_EQUAL( psa_get_key_type( &attributes ), type );

    /* Do something that invalidates the handle. */
    if( ! invalidate_handle( close_method, handle ) )
        goto exit;
    if( ! invalidate_psa( close_method ) )
        goto exit;

    /* Test that the handle is now invalid. */
    TEST_EQUAL( psa_get_key_attributes( handle, &read_attributes ),
                PSA_ERROR_INVALID_HANDLE );
    psa_reset_key_attributes( &read_attributes );
    TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );

    /* Try to reopen the key. If we destroyed it, check that it doesn't
     * exist. Otherwise check that it still exists and has the expected
     * content. */
    switch( close_method )
    {
        case CLOSE_BY_CLOSE:
        case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
        case CLOSE_BY_SHUTDOWN:
            PSA_ASSERT( psa_open_key( id, &handle ) );
            PSA_ASSERT( psa_get_key_attributes( handle, &read_attributes ) );
            TEST_EQUAL( psa_get_key_lifetime( &attributes ),
                        psa_get_key_lifetime( &read_attributes ) );
            TEST_EQUAL( psa_get_key_id( &attributes ),
                        psa_get_key_id( &read_attributes ) );
            TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
            TEST_EQUAL( psa_get_key_algorithm( &attributes ),
                        psa_get_key_algorithm( &read_attributes ) );
            TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ),
                        psa_get_key_enrollment_algorithm( &read_attributes ) );
            TEST_EQUAL( psa_get_key_type( &attributes ),
                        psa_get_key_type( &read_attributes ) );
            TEST_EQUAL( psa_get_key_bits( &attributes ),
                        psa_get_key_bits( &read_attributes ) );
            if( usage_flags & PSA_KEY_USAGE_EXPORT )
            {
                ASSERT_ALLOC( reexported, key_data->len );
                PSA_ASSERT( psa_export_key( handle,
                                            reexported, key_data->len,
                                            &reexported_length ) );
                ASSERT_COMPARE( key_data->x, key_data->len,
                                reexported, reexported_length );
            }
            else
            {
                TEST_EQUAL( psa_export_key( handle,
                                            reexported, sizeof( reexported ),
                                            &reexported_length ),
                            PSA_ERROR_NOT_PERMITTED );
            }
            PSA_ASSERT( psa_close_key( handle ) );
            break;

        case CLOSE_BY_DESTROY:
        case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
            TEST_EQUAL( psa_open_key( id, &handle ),
                        PSA_ERROR_DOES_NOT_EXIST );
            break;
    }

exit:
    PSA_DONE( );
    psa_purge_key_storage( );
    mbedtls_free( reexported );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
void create_existent( int lifetime_arg, int id_arg,
                      int reopen_policy_arg )
{
    psa_key_lifetime_t lifetime = lifetime_arg;
    psa_key_id_t id = id_arg;
    psa_key_handle_t handle1 = 0, handle2 = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
    const uint8_t material1[5] = "a key";
    const uint8_t material2[5] = "b key";
    size_t bits1 = PSA_BYTES_TO_BITS( sizeof( material1 ) );
    uint8_t reexported[sizeof( material1 )];
    size_t reexported_length;
    reopen_policy_t reopen_policy = reopen_policy_arg;

    TEST_USES_KEY_ID( id );

    PSA_ASSERT( psa_crypto_init( ) );

    /* Create a key. */
    psa_set_key_id( &attributes, id );
    psa_set_key_lifetime( &attributes, lifetime );
    psa_set_key_type( &attributes, type1 );
    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
    psa_set_key_algorithm( &attributes, 0 );
    PSA_ASSERT( psa_import_key( &attributes, material1, sizeof( material1 ),
                                &handle1 ) );
    TEST_ASSERT( handle1 != 0 );

    if( reopen_policy == CLOSE_BEFORE )
        PSA_ASSERT( psa_close_key( handle1 ) );

    /* Attempt to create a new key in the same slot. */
    TEST_EQUAL( psa_import_key( &attributes, material2, sizeof( material2 ),
                                &handle2 ),
                PSA_ERROR_ALREADY_EXISTS );
    TEST_EQUAL( handle2, 0 );

    if( reopen_policy == CLOSE_AFTER )
        PSA_ASSERT( psa_close_key( handle1 ) );
    if( reopen_policy == CLOSE_BEFORE || reopen_policy == CLOSE_AFTER )
        PSA_ASSERT( psa_open_key( id, &handle1 ) );

    /* Check that the original key hasn't changed. */
    psa_reset_key_attributes( &attributes );
    PSA_ASSERT( psa_get_key_attributes( handle1, &attributes ) );
    TEST_EQUAL( psa_get_key_id( &attributes ), id );
    TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
    TEST_EQUAL( psa_get_key_type( &attributes ), type1 );
    TEST_EQUAL( psa_get_key_bits( &attributes ), bits1 );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), PSA_KEY_USAGE_EXPORT );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );

    PSA_ASSERT( psa_export_key( handle1,
                                reexported, sizeof( reexported ),
                                &reexported_length ) );
    ASSERT_COMPARE( material1, sizeof( material1 ),
                    reexported, reexported_length );

    PSA_ASSERT( psa_close_key( handle1 ) );

exit:
    PSA_DONE( );
    psa_purge_key_storage( );
}
/* END_CASE */

/* BEGIN_CASE */
void open_fail( int id_arg,
                int expected_status_arg )
{
    psa_key_id_t id = id_arg;
    psa_status_t expected_status = expected_status_arg;
    psa_key_handle_t handle = 0xdead;

    PSA_ASSERT( psa_crypto_init( ) );

    TEST_EQUAL( psa_open_key( id, &handle ), expected_status );
    TEST_EQUAL( handle, 0 );

exit:
    PSA_DONE( );
}
/* END_CASE */

/* BEGIN_CASE */
void create_fail( int lifetime_arg, int id_arg,
                  int expected_status_arg )
{
    psa_key_lifetime_t lifetime = lifetime_arg;
    psa_key_id_t id = id_arg;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_status_t expected_status = expected_status_arg;
    psa_key_handle_t handle = 0xdead;
    uint8_t material[1] = {'k'};

    TEST_USES_KEY_ID( id );

    PSA_ASSERT( psa_crypto_init( ) );

    psa_set_key_id( &attributes, id );
    psa_set_key_lifetime( &attributes, lifetime );
    psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
    TEST_EQUAL( psa_import_key( &attributes, material, sizeof( material ),
                                &handle ),
                expected_status );
    TEST_EQUAL( handle, 0 );

exit:
    PSA_DONE( );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    psa_purge_key_storage( );
#endif
}
/* END_CASE */

/* BEGIN_CASE */
void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
                            int source_usage_arg,
                            int source_alg_arg, int source_alg2_arg,
                            int type_arg, data_t *material,
                            int target_lifetime_arg, int target_id_arg,
                            int target_usage_arg,
                            int target_alg_arg, int target_alg2_arg,
                            int expected_usage_arg,
                            int expected_alg_arg, int expected_alg2_arg )
{
    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
    psa_key_id_t source_id = source_id_arg;
    psa_key_usage_t source_usage = source_usage_arg;
    psa_algorithm_t source_alg = source_alg_arg;
    psa_key_handle_t source_handle = 0;
    psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_type_t source_type = type_arg;
    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
    psa_key_id_t target_id = target_id_arg;
    psa_key_usage_t target_usage = target_usage_arg;
    psa_algorithm_t target_alg = target_alg_arg;
    psa_key_handle_t target_handle = 0;
    psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_usage_t expected_usage = expected_usage_arg;
    psa_algorithm_t expected_alg = expected_alg_arg;
    psa_algorithm_t expected_alg2 = expected_alg2_arg;
    uint8_t *export_buffer = NULL;

    TEST_USES_KEY_ID( source_id );
    TEST_USES_KEY_ID( target_id );

    PSA_ASSERT( psa_crypto_init( ) );

    /* Populate the source slot. */
    if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE )
    {
        psa_set_key_id( &source_attributes, source_id );
        psa_set_key_lifetime( &source_attributes, source_lifetime );
    }
    psa_set_key_type( &source_attributes, source_type );
    psa_set_key_usage_flags( &source_attributes, source_usage );
    psa_set_key_algorithm( &source_attributes, source_alg );
    psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
    PSA_ASSERT( psa_import_key( &source_attributes,
                                material->x, material->len,
                                &source_handle ) );
    /* Update the attributes with the bit size. */
    PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );

    /* Prepare the target slot. */
    if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
    {
        psa_set_key_id( &target_attributes, target_id );
        psa_set_key_lifetime( &target_attributes, target_lifetime );
    }
    psa_set_key_usage_flags( &target_attributes, target_usage );
    psa_set_key_algorithm( &target_attributes, target_alg );
    psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );

    /* Copy the key. */
    PSA_ASSERT( psa_copy_key( source_handle,
                              &target_attributes, &target_handle ) );

    /* Destroy the source to ensure that this doesn't affect the target. */
    PSA_ASSERT( psa_destroy_key( source_handle ) );

    /* If the target key is persistent, restart the system to make
     * sure that the material is still alive. */
    if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
    {
        mbedtls_psa_crypto_free( );
        PSA_ASSERT( psa_crypto_init( ) );
        PSA_ASSERT( psa_open_key( target_id, &target_handle ) );
    }

    /* Test that the target slot has the expected content. */
    psa_reset_key_attributes( &target_attributes );
    PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
    TEST_EQUAL( target_id, psa_get_key_id( &target_attributes ) );
    TEST_EQUAL( target_lifetime, psa_get_key_lifetime( &target_attributes ) );
    TEST_EQUAL( source_type, psa_get_key_type( &target_attributes ) );
    TEST_EQUAL( psa_get_key_bits( &source_attributes ),
                psa_get_key_bits( &target_attributes ) );
    TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
    TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
    TEST_EQUAL( expected_alg2,
                psa_get_key_enrollment_algorithm( &target_attributes ) );
    if( expected_usage & PSA_KEY_USAGE_EXPORT )
    {
        size_t length;
        ASSERT_ALLOC( export_buffer, material->len );
        PSA_ASSERT( psa_export_key( target_handle, export_buffer,
                                    material->len, &length ) );
        ASSERT_COMPARE( material->x, material->len,
                        export_buffer, length );
    }
    else
    {
        size_t length;
        /* Check that the key is actually non-exportable. */
        TEST_EQUAL( psa_export_key( target_handle, export_buffer,
                                    material->len, &length ),
                    PSA_ERROR_NOT_PERMITTED );
    }

    PSA_ASSERT( psa_destroy_key( target_handle ) );

exit:
    PSA_DONE( );
    mbedtls_free( export_buffer );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    psa_purge_key_storage( );
#endif
}
/* END_CASE */

/* BEGIN_CASE */
void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
                       int source_usage_arg, int source_alg_arg,
                       int source_type_arg, data_t *source_material,
                       int target_lifetime_arg, int target_id_arg,
                       int target_usage_arg, int target_alg_arg,
                       int target_type_arg, data_t *target_material )
{
    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
    psa_key_id_t source_id = source_id_arg;
    psa_key_usage_t source_usage = source_usage_arg;
    psa_algorithm_t source_alg = source_alg_arg;
    psa_key_handle_t source_handle = 0;
    psa_key_type_t source_type = source_type_arg;
    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
    psa_key_id_t target_id = target_id_arg;
    psa_key_usage_t target_usage = target_usage_arg;
    psa_algorithm_t target_alg = target_alg_arg;
    psa_key_handle_t target_handle = 0;
    psa_key_type_t target_type = target_type_arg;
    psa_key_handle_t new_handle = 0xdead;
    uint8_t *export_buffer = NULL;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
    psa_key_attributes_t attributes2 = PSA_KEY_ATTRIBUTES_INIT;

    TEST_USES_KEY_ID( source_id );
    TEST_USES_KEY_ID( target_id );

    PSA_ASSERT( psa_crypto_init( ) );

    /* Populate the source slot. */
    if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE )
    {
        psa_set_key_id( &attributes, source_id );
        psa_set_key_lifetime( &attributes, source_lifetime );
    }
    psa_set_key_type( &attributes, source_type );
    psa_set_key_usage_flags( &attributes, source_usage );
    psa_set_key_algorithm( &attributes, source_alg );
    PSA_ASSERT( psa_import_key( &attributes,
                                source_material->x, source_material->len,
                                &source_handle ) );

    /* Populate the target slot. */
    if( target_id == source_id )
    {
        target_handle = source_handle;
    }
    else
    {
        psa_set_key_id( &attributes1, target_id );
        psa_set_key_lifetime( &attributes1, target_lifetime );
        psa_set_key_type( &attributes1, target_type );
        psa_set_key_usage_flags( &attributes1, target_usage );
        psa_set_key_algorithm( &attributes1, target_alg );
        PSA_ASSERT( psa_import_key( &attributes1,
                                    target_material->x, target_material->len,
                                    &target_handle ) );
    }
    PSA_ASSERT( psa_get_key_attributes( target_handle, &attributes1 ) );

    /* Make a copy attempt. */
    psa_set_key_id( &attributes, target_id );
    psa_set_key_lifetime( &attributes, target_lifetime );
    TEST_EQUAL( psa_copy_key( source_handle,
                              &attributes, &new_handle ),
                PSA_ERROR_ALREADY_EXISTS );
    TEST_EQUAL( new_handle , 0 );

    /* Test that the target slot is unaffected. */
    PSA_ASSERT( psa_get_key_attributes( target_handle, &attributes2 ) );
    TEST_EQUAL( psa_get_key_id( &attributes1 ),
                psa_get_key_id( &attributes2 ) );
    TEST_EQUAL( psa_get_key_lifetime( &attributes1 ),
                psa_get_key_lifetime( &attributes2 ) );
    TEST_EQUAL( psa_get_key_type( &attributes1 ),
                psa_get_key_type( &attributes2 ) );
    TEST_EQUAL( psa_get_key_bits( &attributes1 ),
                psa_get_key_bits( &attributes2 ) );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes1 ),
                psa_get_key_usage_flags( &attributes2 ) );
    TEST_EQUAL( psa_get_key_algorithm( &attributes1 ),
                psa_get_key_algorithm( &attributes2 ) );
    if( target_usage & PSA_KEY_USAGE_EXPORT )
    {
        size_t length;
        ASSERT_ALLOC( export_buffer, target_material->len );
        PSA_ASSERT( psa_export_key( target_handle, export_buffer,
                                    target_material->len, &length ) );
        ASSERT_COMPARE( target_material->x, target_material->len,
                        export_buffer, length );
    }

    PSA_ASSERT( psa_destroy_key( source_handle ) );
    if( target_handle != source_handle )
        PSA_ASSERT( psa_destroy_key( target_handle ) );

exit:
    PSA_DONE( );
    mbedtls_free( export_buffer );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
    psa_purge_key_storage( );
#endif
}
/* END_CASE */

/* BEGIN_CASE */
void invalid_handle( int handle_construction,
                     int close_status_arg, int usage_status_arg )
{
    psa_key_handle_t valid_handle = 0;
    psa_key_handle_t invalid_handle = 0;
    psa_status_t close_status = close_status_arg;
    psa_status_t usage_status = usage_status_arg;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    uint8_t material[1] = "a";

    PSA_ASSERT( psa_crypto_init( ) );

    /* Allocate a handle and store a key in it. */
    psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
    psa_set_key_usage_flags( &attributes, 0 );
    psa_set_key_algorithm( &attributes, 0 );
    PSA_ASSERT( psa_import_key( &attributes,
                                material, sizeof( material ),
                                &valid_handle ) );
    TEST_ASSERT( valid_handle != 0 );

    /* Construct an invalid handle as specified in the test case data. */
    switch( handle_construction )
    {
        case INVALID_HANDLE_0:
            invalid_handle = 0;
            break;
        case INVALID_HANDLE_UNOPENED:
            /* We can't easily construct a handle that's never been opened
             * without knowing how the implementation constructs handle
             * values. The current test code assumes that valid handles
             * are in a range between 1 and some maximum. */
            if( valid_handle == 1 )
                invalid_handle = 2;
            else
                invalid_handle = valid_handle - 1;
            break;
        case INVALID_HANDLE_CLOSED:
            PSA_ASSERT( psa_import_key( &attributes,
                                        material, sizeof( material ),
                                        &invalid_handle ) );
            PSA_ASSERT( psa_destroy_key( invalid_handle ) );
            break;
        case INVALID_HANDLE_HUGE:
            invalid_handle = (psa_key_handle_t) ( -1 );
            break;
        default:
            TEST_ASSERT( ! "unknown handle construction" );
    }

    /* Attempt to use the invalid handle. */
    TEST_EQUAL( psa_get_key_attributes( invalid_handle, &attributes ),
                usage_status );
    TEST_EQUAL( psa_close_key( invalid_handle ), close_status );
    TEST_EQUAL( psa_destroy_key( invalid_handle ), close_status );

    /* After all this, check that the original handle is intact. */
    PSA_ASSERT( psa_get_key_attributes( valid_handle, &attributes ) );
    TEST_EQUAL( psa_get_key_type( &attributes ), PSA_KEY_TYPE_RAW_DATA );
    TEST_EQUAL( psa_get_key_bits( &attributes ),
                PSA_BYTES_TO_BITS( sizeof( material ) ) );
    PSA_ASSERT( psa_close_key( valid_handle ) );

exit:
    PSA_DONE( );
}
/* END_CASE */

/* BEGIN_CASE */
void many_transient_handles( int max_handles_arg )
{
    psa_key_handle_t *handles = NULL;
    size_t max_handles = max_handles_arg;
    size_t i, j;
    psa_status_t status;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    uint8_t exported[sizeof( size_t )];
    size_t exported_length;

    ASSERT_ALLOC( handles, max_handles );
    PSA_ASSERT( psa_crypto_init( ) );

    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
    psa_set_key_algorithm( &attributes, 0 );
    psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );

    for( i = 0; i < max_handles; i++ )
    {
        status = psa_import_key( &attributes,
                                 (uint8_t *) &i, sizeof( i ),
                                 &handles[i] );
        if( status == PSA_ERROR_INSUFFICIENT_MEMORY )
            break;
        PSA_ASSERT( status );
        TEST_ASSERT( handles[i] != 0 );
        for( j = 0; j < i; j++ )
            TEST_ASSERT( handles[i] != handles[j] );
    }
    max_handles = i;

    for( i = 1; i < max_handles; i++ )
    {
        PSA_ASSERT( psa_close_key( handles[i - 1] ) );
        PSA_ASSERT( psa_export_key( handles[i],
                                    exported, sizeof( exported ),
                                    &exported_length ) );
        ASSERT_COMPARE( exported, exported_length,
                        (uint8_t *) &i, sizeof( i ) );
    }
    PSA_ASSERT( psa_close_key( handles[i - 1] ) );

exit:
    PSA_DONE( );
    mbedtls_free( handles );
}
/* END_CASE */

