SE keys: smoke test import, export, destroy
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.data b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
index c04b70d..28c7d75 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -26,3 +26,9 @@
 
 Register SE driver: maximum number of drivers
 register_max:
+
+Key creation smoke test (p_allocate allows all slots)
+key_creation_import_export:0
+
+Key creation smoke test (p_allocate allows 1 slot)
+key_creation_import_export:ARRAY_LENGTH( ram_slots ) - 1
diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
index b9d0a1f..2e2a648 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -4,9 +4,117 @@
 
 #include "psa_crypto_se.h"
 
-/* The minimum valid lifetime value for a secure element driver. */
+/** The minimum valid lifetime value for a secure element driver. */
 #define MIN_DRIVER_LIFETIME 2
 
+/** The driver detected a condition that shouldn't happen.
+ * This is probably a bug in the library. */
+#define PSA_ERROR_DETECTED_BY_DRIVER ((psa_status_t)( -500 ))
+
+/** Like #TEST_ASSERT for use in a driver method.
+ *
+ * Use this macro to assert on guarantees provided by the core.
+ */
+#define DRIVER_ASSERT( TEST )                               \
+    do {                                                    \
+       if( ! (TEST) )                                       \
+       {                                                    \
+          test_fail( #TEST, __LINE__, __FILE__ );           \
+          return( PSA_ERROR_DETECTED_BY_DRIVER );           \
+       }                                                    \
+    } while( 0 )
+
+#define RAM_MAX_KEY_SIZE 64
+typedef struct
+{
+    psa_key_lifetime_t lifetime;
+    psa_key_type_t type;
+    size_t bits;
+    uint8_t content[RAM_MAX_KEY_SIZE];
+} ram_slot_t;
+static ram_slot_t ram_slots[16];
+
+/* A type with at least ARRAY_LENGTH(ram_slots) bits, containing a
+ * bit vector indicating which slots are in use. */
+typedef uint16_t ram_slot_usage_t;
+
+static uint8_t ram_min_slot = 0;
+
+static void ram_slots_reset( void )
+{
+    memset( ram_slots, 0, sizeof( ram_slots ) );
+    ram_min_slot = 0;
+}
+
+static psa_status_t ram_import( psa_drv_se_context_t *context,
+                                psa_key_slot_number_t slot_number,
+                                psa_key_lifetime_t lifetime,
+                                psa_key_type_t type,
+                                psa_algorithm_t algorithm,
+                                psa_key_usage_t usage,
+                                const uint8_t *p_data,
+                                size_t data_length )
+{
+    (void) context;
+    DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
+    if( data_length > sizeof( ram_slots[slot_number].content ) )
+        return( PSA_ERROR_INSUFFICIENT_STORAGE );
+    ram_slots[slot_number].lifetime = lifetime;
+    ram_slots[slot_number].type = type;
+    ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
+    (void) algorithm;
+    (void) usage;
+    memcpy( ram_slots[slot_number].content, p_data, data_length );
+    return( PSA_SUCCESS );
+}
+
+psa_status_t ram_export( psa_drv_se_context_t *context,
+                         psa_key_slot_number_t slot_number,
+                         uint8_t *p_data,
+                         size_t data_size,
+                         size_t *p_data_length )
+{
+    size_t actual_size;
+    (void) context;
+    DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
+    actual_size = PSA_BITS_TO_BYTES( ram_slots[slot_number].bits );
+    if( actual_size > data_size )
+        return( PSA_ERROR_BUFFER_TOO_SMALL );
+    *p_data_length = actual_size;
+    memcpy( p_data, ram_slots[slot_number].content, actual_size );
+    return( PSA_SUCCESS );
+}
+
+psa_status_t ram_destroy( psa_drv_se_context_t *context,
+                          void *persistent_data,
+                          psa_key_slot_number_t slot_number )
+{
+    ram_slot_usage_t *slot_usage = persistent_data;
+    DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
+    DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
+    memset( &ram_slots[slot_number], 0, sizeof( ram_slots[slot_number] ) );
+    *slot_usage &= ~(ram_slot_usage_t)( 1 << slot_number );
+    return( PSA_SUCCESS );
+}
+
+psa_status_t ram_allocate( psa_drv_se_context_t *context,
+                           void *persistent_data,
+                           const psa_key_attributes_t *attributes,
+                           psa_key_slot_number_t *slot_number )
+{
+    ram_slot_usage_t *slot_usage = persistent_data;
+    (void) attributes;
+    DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
+    for( *slot_number = ram_min_slot;
+         *slot_number < ARRAY_LENGTH( ram_slots );
+         ++( *slot_number ) )
+    {
+        if( ! ( *slot_usage & 1 << *slot_number ) )
+            return( PSA_SUCCESS );
+    }
+    return( PSA_ERROR_INSUFFICIENT_STORAGE );
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -78,3 +186,59 @@
     PSA_DONE( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void key_creation_import_export( int min_slot )
+{
+    psa_drv_se_t driver;
+    psa_drv_se_key_management_t key_management;
+    psa_key_lifetime_t lifetime = 2;
+    psa_key_id_t id = 1;
+    psa_key_handle_t handle = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
+    uint8_t exported[sizeof( key_material )];
+    size_t exported_length;
+
+    memset( &driver, 0, sizeof( driver ) );
+    memset( &key_management, 0, sizeof( key_management ) );
+    driver.hal_version = PSA_DRV_SE_HAL_VERSION;
+    driver.key_management = &key_management;
+    driver.persistent_data_size = sizeof( ram_slot_usage_t );
+    key_management.p_allocate = ram_allocate;
+    key_management.p_import = ram_import;
+    key_management.p_destroy = ram_destroy;
+    key_management.p_export = ram_export;
+    ram_min_slot = min_slot;
+
+    PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
+    PSA_ASSERT( psa_crypto_init( ) );
+
+    /* Create a key. */
+    psa_set_key_id( &attributes, id );
+    psa_set_key_lifetime( &attributes, lifetime );
+    psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
+    psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
+    PSA_ASSERT( psa_import_key( &attributes,
+                                key_material, sizeof( key_material ),
+                                &handle ) );
+
+    /* Test that the key was created in the expected slot. */
+    TEST_ASSERT( ram_slots[min_slot].type == PSA_KEY_TYPE_RAW_DATA );
+
+    PSA_ASSERT( psa_export_key( handle,
+                                exported, sizeof( exported ),
+                                &exported_length ) );
+    ASSERT_COMPARE( key_material, sizeof( key_material ),
+                    exported, exported_length );
+
+    PSA_ASSERT( psa_destroy_key( handle ) );
+
+    /* Test that the key has been erased from the designated slot. */
+    TEST_ASSERT( ram_slots[min_slot].type == 0 );
+
+exit:
+    PSA_DONE( );
+    ram_slots_reset( );
+}
+/* END_CASE */