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

#include "test/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,
                                            NULL, 0,
                                            &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 */

