/* 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_slot_management.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_bits,
                                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_bits( &attributes, key_bits );
    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_bits,
                               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_bits( &attributes ),
                (psa_key_bits_t) expected_key_bits );
    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 )
{
    mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make( 1, 42 );
    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, &key_id ),
                expected_status );

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

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

/* BEGIN_CASE */
void persistent_key_destroy( int owner_id_arg, int key_id_arg, int restart,
                             int first_type_arg, data_t *first_data,
                             int second_type_arg, data_t *second_data )
{
    mbedtls_svc_key_id_t key_id =
        mbedtls_svc_key_id_make( owner_id_arg, key_id_arg );
    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
    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,
                                &returned_key_id ) );

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

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

    /* Check key slot storage is removed */
    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 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,
                                &returned_key_id ) );

    PSA_ASSERT( psa_destroy_key( key_id ) );

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

/* BEGIN_CASE */
void persistent_key_import( int owner_id_arg, int key_id_arg, int type_arg,
                            data_t *data, int restart, int expected_status )
{
    mbedtls_svc_key_id_t key_id =
        mbedtls_svc_key_id_make( owner_id_arg, key_id_arg );
    mbedtls_svc_key_id_t returned_key_id;
    psa_key_type_t type = (psa_key_type_t) 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, type );
    TEST_EQUAL( psa_import_key( &attributes, data->x, data->len, &returned_key_id ),
                expected_status );

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

    TEST_ASSERT( mbedtls_svc_key_id_equal( returned_key_id, key_id ) );

    if( restart )
    {
        PSA_ASSERT( psa_purge_key( key_id ) );
        PSA_DONE();
        PSA_ASSERT( psa_crypto_init() );
    }

    psa_reset_key_attributes( &attributes );
    PSA_ASSERT( psa_get_key_attributes( key_id, &attributes ) );
    TEST_ASSERT( mbedtls_svc_key_id_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( key_id ) );

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    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 )
{
    mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make( 1, 42 );
    psa_key_type_t type = (psa_key_type_t) type_arg;
    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
    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,
                                &returned_key_id ) );


    if( restart )
    {
        PSA_ASSERT( psa_purge_key( key_id ) );
        PSA_DONE();
        PSA_ASSERT( psa_crypto_init() );
    }

    /* Test the key information */
    psa_reset_key_attributes( &attributes );
    PSA_ASSERT( psa_get_key_attributes( key_id, &attributes ) );
    TEST_ASSERT( mbedtls_svc_key_id_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( key_id, exported, export_size,
                                &exported_length ) );

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

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

exit:
    /*
     * Key attributes may have been returned by psa_get_key_attributes()
     * thus reset them as required.
     */
    psa_reset_key_attributes( &attributes );

    mbedtls_free( exported );
    PSA_DONE( );
    psa_destroy_persistent_key( key_id );
}
/* END_CASE */
