/* BEGIN_HEADER */

/* The tests in this module verify the contents of key store files. They
 * access internal key storage functions directly. Some of the tests depend
 * on the the storage format. On the other hand, these tests treat the storage
 * subsystem as a black box, and in particular have no reliance on the
 * internals of the ITS implementation.
 */

#include <stdint.h>

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

#include "mbedtls/md.h"

#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )

/* Enforce the storage format for keys. The storage format is not a public
 * documented interface, but it must be preserved between versions so that
 * upgrades work smoothly, so it's a stable interface nonetheless.
 */
typedef struct {
    uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
    uint8_t version[4];
    uint8_t lifetime[sizeof( psa_key_lifetime_t )];
    uint8_t type[4];
    uint8_t policy[sizeof( psa_key_policy_t )];
    uint8_t data_len[4];
    uint8_t key_data[];
} psa_persistent_key_storage_format;

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void format_storage_data_check( data_t *key_data,
                                data_t *expected_file_data,
                                int key_lifetime, int key_type,
                                int key_usage, int key_alg, int key_alg2 )
{
    uint8_t *file_data = NULL;
    size_t file_data_length =
        key_data->len + sizeof( psa_persistent_key_storage_format );
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    psa_set_key_lifetime( &attributes, key_lifetime );
    psa_set_key_type( &attributes, key_type );
    psa_set_key_usage_flags( &attributes, key_usage );
    psa_set_key_algorithm( &attributes, key_alg );
    psa_set_key_enrollment_algorithm( &attributes, key_alg2 );

    ASSERT_ALLOC( file_data, file_data_length );
    psa_format_key_data_for_storage( key_data->x, key_data->len,
                                     &attributes.core,
                                     file_data );

    ASSERT_COMPARE( expected_file_data->x, expected_file_data->len,
                    file_data, file_data_length );

exit:
    mbedtls_free( file_data );
}
/* END_CASE */

/* BEGIN_CASE */
void parse_storage_data_check( data_t *file_data,
                               data_t *expected_key_data,
                               int expected_key_lifetime,
                               int expected_key_type,
                               int expected_key_usage,
                               int expected_key_alg,
                               int expected_key_alg2,
                               int expected_status )
{
    uint8_t *key_data = NULL;
    size_t key_data_length = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_status_t status;

    status = psa_parse_key_data_from_storage( file_data->x, file_data->len,
                                              &key_data, &key_data_length,
                                              &attributes.core );

    TEST_EQUAL( status, expected_status );
    if( status != PSA_SUCCESS )
        goto exit;

    TEST_EQUAL( psa_get_key_lifetime( &attributes ),
                (psa_key_type_t) expected_key_lifetime );
    TEST_EQUAL( psa_get_key_type( &attributes ),
                (psa_key_type_t) expected_key_type );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
                (uint32_t) expected_key_usage );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ),
                (uint32_t) expected_key_alg );
    TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ),
                (uint32_t) expected_key_alg2 );
    ASSERT_COMPARE( expected_key_data->x, expected_key_data->len,
                    key_data, key_data_length );

exit:
    mbedtls_free( key_data );
}
/* END_CASE */

/* BEGIN_CASE */
void save_large_persistent_key( int data_length_arg, int expected_status )
{
    psa_key_id_t key_id = 42;
    psa_key_handle_t handle = 0;
    uint8_t *data = NULL;
    size_t data_length = data_length_arg;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    ASSERT_ALLOC( data, data_length );

    PSA_ASSERT( psa_crypto_init() );

    psa_set_key_id( &attributes, key_id );
    psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );

    TEST_EQUAL( psa_import_key( &attributes, data, data_length, &handle ),
                expected_status );

    if( expected_status == PSA_SUCCESS )
        PSA_ASSERT( psa_destroy_key( handle ) );

exit:
    mbedtls_free( data );
    PSA_DONE();
    psa_destroy_persistent_key( key_id );
}
/* END_CASE */

/* BEGIN_CASE */
void persistent_key_destroy( int key_id_arg, int restart,
                             int first_type_arg, data_t *first_data,
                             int second_type_arg, data_t *second_data )
{
    psa_key_id_t key_id = key_id_arg;
    psa_key_handle_t handle = 0;
    psa_key_type_t first_type = (psa_key_type_t) first_type_arg;
    psa_key_type_t second_type = (psa_key_type_t) second_type_arg;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    PSA_ASSERT( psa_crypto_init() );

    psa_set_key_id( &attributes, key_id );
    psa_set_key_type( &attributes, first_type );

    PSA_ASSERT( psa_import_key( &attributes, first_data->x, first_data->len,
                                &handle ) );

    if( restart )
    {
        psa_close_key( handle );
        PSA_DONE();
        PSA_ASSERT( psa_crypto_init() );
        PSA_ASSERT( psa_open_key( key_id, &handle ) );
    }
    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 1 );

    /* Destroy the key */
    PSA_ASSERT( psa_destroy_key( handle ) );

    /* Check key slot storage is removed */
    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
    TEST_EQUAL( psa_open_key( key_id, &handle ), PSA_ERROR_DOES_NOT_EXIST );
    TEST_EQUAL( handle, 0 );

    /* Shutdown and restart */
    PSA_DONE();
    PSA_ASSERT( psa_crypto_init() );

    /* Create another key in the same slot */
    psa_set_key_id( &attributes, key_id );
    psa_set_key_type( &attributes, second_type );
    PSA_ASSERT( psa_import_key( &attributes, second_data->x, second_data->len,
                                &handle ) );

    PSA_ASSERT( psa_destroy_key( handle ) );

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

/* BEGIN_CASE */
void persistent_key_import( int key_id_arg, int type_arg, data_t *data,
                            int restart, int expected_status )
{
    psa_key_id_t key_id = (psa_key_id_t) key_id_arg;
    psa_key_type_t type = (psa_key_type_t) type_arg;
    psa_key_handle_t handle = 0;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    PSA_ASSERT( psa_crypto_init() );

    psa_set_key_id( &attributes, key_id );
    psa_set_key_type( &attributes, type );
    TEST_EQUAL( psa_import_key( &attributes, data->x, data->len, &handle ),
                expected_status );

    if( expected_status != PSA_SUCCESS )
    {
        TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
        goto exit;
    }

    if( restart )
    {
        psa_close_key( handle );
        PSA_DONE();
        PSA_ASSERT( psa_crypto_init() );
        PSA_ASSERT( psa_open_key( key_id, &handle ) );
    }

    psa_reset_key_attributes( &attributes );
    PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
    TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
    TEST_EQUAL( psa_get_key_lifetime( &attributes ),
                PSA_KEY_LIFETIME_PERSISTENT );
    TEST_EQUAL( psa_get_key_type( &attributes ), type );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );

    PSA_ASSERT( psa_destroy_key( handle ) );

exit:
    psa_reset_key_attributes( &attributes );
    psa_destroy_persistent_key( key_id );
    PSA_DONE();
}
/* END_CASE */

/* BEGIN_CASE */
void import_export_persistent_key( data_t *data, int type_arg,
                                   int expected_bits,
                                   int restart, int key_not_exist )
{
    psa_key_id_t key_id = 42;
    psa_key_type_t type = (psa_key_type_t) type_arg;
    psa_key_handle_t handle = 0;
    unsigned char *exported = NULL;
    size_t export_size = data->len;
    size_t exported_length;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    ASSERT_ALLOC( exported, export_size );

    PSA_ASSERT( psa_crypto_init( ) );

    psa_set_key_id( &attributes, key_id );
    psa_set_key_type( &attributes, type );
    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );

    /* Import the key */
    PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );


    if( restart )
    {
        psa_close_key( handle );
        PSA_DONE();
        PSA_ASSERT( psa_crypto_init() );
        PSA_ASSERT( psa_open_key( key_id, &handle ) );
    }

    /* Test the key information */
    psa_reset_key_attributes( &attributes );
    PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
    TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
    TEST_EQUAL( psa_get_key_lifetime( &attributes ),
                PSA_KEY_LIFETIME_PERSISTENT );
    TEST_EQUAL( psa_get_key_type( &attributes ), type );
    TEST_EQUAL( psa_get_key_bits( &attributes ), (size_t) expected_bits );
    TEST_EQUAL( psa_get_key_usage_flags( &attributes ), PSA_KEY_USAGE_EXPORT );
    TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );

    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 1 );

    if( key_not_exist )
    {
        psa_destroy_persistent_key( key_id );
    }
    /* Export the key */
    PSA_ASSERT( psa_export_key( handle, exported, export_size,
                                &exported_length ) );

    ASSERT_COMPARE( data->x, data->len, exported, exported_length );

    /* Destroy the key */
    PSA_ASSERT( psa_destroy_key( handle ) );
    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );

exit:
    psa_reset_key_attributes( &attributes );
    mbedtls_free( exported );
    PSA_DONE( );
    psa_destroy_persistent_key( key_id );
}
/* END_CASE */
