SE keys: implement and smoke-test p_generate
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index f64487b..35c03dd 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -5944,21 +5944,37 @@
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
     psa_se_drv_table_entry_t *driver = NULL;
+
     status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE,
                                      attributes, handle, &slot, &driver );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     if( driver != NULL )
     {
-        /* Generating a key in a secure element is not implemented yet. */
-        status = PSA_ERROR_NOT_SUPPORTED;
+        const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
+        size_t pubkey_length = 0; /* We don't support this feature yet */
+        if( drv->key_management == NULL ||
+            drv->key_management->p_generate == NULL )
+        {
+            status = PSA_ERROR_NOT_SUPPORTED;
+            goto exit;
+        }
+        status = drv->key_management->p_generate(
+            psa_get_se_driver_context( driver ),
+            slot->data.se.slot_number, attributes,
+            NULL, 0, &pubkey_length );
     }
+    else
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
-    if( status == PSA_SUCCESS )
     {
         status = psa_generate_key_internal(
             slot, attributes->core.bits,
             attributes->domain_parameters, attributes->domain_parameters_size );
     }
+
+exit:
     if( status == PSA_SUCCESS )
         status = psa_finish_key_creation( slot, driver );
     if( status != PSA_SUCCESS )
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 267c7b8..0bec841 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.data
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.data
@@ -54,63 +54,72 @@
 Key creation in a specific slot (too large)
 key_creation_in_chosen_slot:ARRAY_LENGTH( ram_slots ):0:PSA_ERROR_INVALID_ARGUMENT
 
-Key creation smoke test: AES-CTR
-key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: AES-CTR
+import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: AES-CBC
-key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: AES-CBC
+import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: AES-CMAC
-key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: AES-CMAC
+import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: AES-CCM
-key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: AES-CCM
+import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: AES-GCM
-key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: AES-GCM
+import_key_smoke:PSA_KEY_TYPE_AES:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: CAMELLIA-CTR
-key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: CAMELLIA-CTR
+import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: CAMELLIA-CBC
-key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: CAMELLIA-CBC
+import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: CAMELLIA-CMAC
-key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: CAMELLIA-CMAC
+import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: CAMELLIA-CCM
-key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: CAMELLIA-CCM
+import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: CAMELLIA-CCM
-key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: CAMELLIA-CCM
+import_key_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: HMAC-SHA-256
-key_creation_smoke:PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: HMAC-SHA-256
+import_key_smoke:PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: HKDF-SHA-256
-key_creation_smoke:PSA_KEY_TYPE_DERIVE:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Key import smoke test: HKDF-SHA-256
+import_key_smoke:PSA_KEY_TYPE_DERIVE:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 
-Key creation smoke test: RSA PKCS#1v1.5 signature
-key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
+Key import smoke test: RSA PKCS#1v1.5 signature
+import_key_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
 
-Key creation smoke test: RSA PKCS#1v1.5 encryption
-key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
+Key import smoke test: RSA PKCS#1v1.5 encryption
+import_key_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
 
-Key creation smoke test: RSA OAEP encryption
-key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP( PSA_ALG_SHA_256 ):"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
+Key import smoke test: RSA OAEP encryption
+import_key_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP( PSA_ALG_SHA_256 ):"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
 
-Key creation smoke test: ECDSA secp256r1
-key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
+Key import smoke test: ECDSA secp256r1
+import_key_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
 
-Key creation smoke test: ECDH secp256r1
-key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDH:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
+Key import smoke test: ECDH secp256r1
+import_key_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDH:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
 
-Key creation smoke test: ECDH secp256r1 with HKDF
-key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
+Key import smoke test: ECDH secp256r1 with HKDF
+import_key_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
 
 Generate key: not supported
 generate_key_not_supported:PSA_KEY_TYPE_AES:128
 
+Key generation smoke test: AES-128-CTR
+generate_key_smoke:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR
+
+Key generation smoke test: AES-256-CTR
+generate_key_smoke:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR
+
+Key generation smoke test: HMAC-SHA-256
+generate_key_smoke:PSA_KEY_TYPE_HMAC:256:PSA_ALG_HMAC( PSA_ALG_SHA_256 )
+
 Key registration: smoke test
 register_key_smoke_test:MIN_DRIVER_LIFETIME:-1:PSA_SUCCESS
 
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 6c30851..d13e2f2 100644
--- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function
+++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function
@@ -96,6 +96,28 @@
     return( PSA_SUCCESS );
 }
 
+/* Null generate: do nothing, but pretend it worked. */
+static psa_status_t null_generate( psa_drv_se_context_t *context,
+                                   psa_key_slot_number_t slot_number,
+                                   const psa_key_attributes_t *attributes,
+                                   uint8_t *pubkey,
+                                   size_t pubkey_size,
+                                   size_t *pubkey_length )
+{
+    (void) context;
+    (void) slot_number;
+    (void) attributes;
+
+    DRIVER_ASSERT( *pubkey_length == 0 );
+    if( ! PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
+    {
+        DRIVER_ASSERT( pubkey == NULL );
+        DRIVER_ASSERT( pubkey_size == 0 );
+    }
+
+    return( PSA_SUCCESS );
+}
+
 
 
 /****************************************************************/
@@ -634,8 +656,8 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void key_creation_smoke( int type_arg, int alg_arg,
-                         data_t *key_material )
+void import_key_smoke( int type_arg, int alg_arg,
+                       data_t *key_material )
 {
     psa_key_type_t type = type_arg;
     psa_algorithm_t alg = alg_arg;
@@ -710,6 +732,7 @@
     driver.key_management = &key_management;
     driver.persistent_data_size = sizeof( psa_key_slot_number_t );
     key_management.p_allocate = counter_allocate;
+    /* No p_generate method */
 
     PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
     PSA_ASSERT( psa_crypto_init( ) );
@@ -729,6 +752,64 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void generate_key_smoke( int type_arg, int bits_arg, int alg_arg )
+{
+    psa_key_type_t type = type_arg;
+    psa_key_bits_t bits = bits_arg;
+    psa_algorithm_t alg = alg_arg;
+    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;
+
+    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( psa_key_slot_number_t );
+    key_management.p_allocate = counter_allocate;
+    key_management.p_generate = null_generate;
+
+    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_SIGN | PSA_KEY_USAGE_VERIFY |
+                             PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT |
+                             PSA_KEY_USAGE_EXPORT );
+    psa_set_key_algorithm( &attributes, alg );
+    psa_set_key_type( &attributes, type );
+    psa_set_key_bits( &attributes, bits );
+    PSA_ASSERT( psa_generate_key( &attributes, &handle ) );
+
+    /* Do stuff with the key. */
+    if( ! smoke_test_key( handle ) )
+        goto exit;
+
+    /* Restart and try again. */
+    mbedtls_psa_crypto_free( );
+    PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
+    PSA_ASSERT( psa_crypto_init( ) );
+    PSA_ASSERT( psa_open_key( id, &handle ) );
+    if( ! smoke_test_key( handle ) )
+        goto exit;
+
+    /* We're done. */
+    PSA_ASSERT( psa_destroy_key( handle ) );
+
+exit:
+    PSA_DONE( );
+    ram_slots_reset( );
+    psa_purge_storage( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void register_key_smoke_test( int lifetime_arg,
                               int validate,
                               int expected_status_arg )