Merge pull request #3744 from ronald-cron-arm/psa-generate-key-internal

Rework psa_generate_key
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index e3ba1d3..f304950 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -34,6 +34,7 @@
 #include "psa_crypto_driver_wrappers.h"
 #include "psa_crypto_ecp.h"
 #include "psa_crypto_rsa.h"
+#include "psa_crypto_ecp.h"
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
 #include "psa_crypto_se.h"
 #endif
@@ -5956,66 +5957,80 @@
 }
 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
 
-#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
-static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters,
-                                           size_t domain_parameters_size,
-                                           int *exponent )
+/** Validate the key type and size for key generation
+ *
+ * \param  type  The key type
+ * \param  bits  The number of bits of the key
+ *
+ * \retval #PSA_SUCCESS
+ *         The key type and size are valid.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size in bits of the key is not valid.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The type and/or the size in bits of the key or the combination of
+ *         the two is not supported.
+ */
+static psa_status_t psa_validate_key_type_and_size_for_key_generation(
+    psa_key_type_t type, size_t bits )
 {
-    size_t i;
-    uint32_t acc = 0;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
 
-    if( domain_parameters_size == 0 )
+    if( key_type_is_raw_bytes( type ) )
     {
-        *exponent = 65537;
+        status = validate_unstructured_key_bit_size( type, bits );
+        if( status != PSA_SUCCESS )
+            return( status );
+    }
+    else
+#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR)
+    if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
+    {
+        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
+            return( PSA_ERROR_NOT_SUPPORTED );
+
+        /* Accept only byte-aligned keys, for the same reasons as
+         * in psa_import_rsa_key(). */
+        if( bits % 8 != 0 )
+            return( PSA_ERROR_NOT_SUPPORTED );
+    }
+    else
+#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */
+
+#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR)
+    if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
+    {
+        /* To avoid empty block, return successfully here. */
         return( PSA_SUCCESS );
     }
+    else
+#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */
+    {
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
 
-    /* Mbed TLS encodes the public exponent as an int. For simplicity, only
-     * support values that fit in a 32-bit integer, which is larger than
-     * int on just about every platform anyway. */
-    if( domain_parameters_size > sizeof( acc ) )
-        return( PSA_ERROR_NOT_SUPPORTED );
-    for( i = 0; i < domain_parameters_size; i++ )
-        acc = ( acc << 8 ) | domain_parameters[i];
-    if( acc > INT_MAX )
-        return( PSA_ERROR_NOT_SUPPORTED );
-    *exponent = acc;
     return( PSA_SUCCESS );
 }
-#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
 
-static psa_status_t psa_generate_key_internal(
-    psa_key_slot_t *slot, size_t bits,
-    const uint8_t *domain_parameters, size_t domain_parameters_size )
+psa_status_t psa_generate_key_internal(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
 {
-    psa_key_type_t type = slot->attr.type;
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_type_t type = attributes->core.type;
 
-    if( domain_parameters == NULL && domain_parameters_size != 0 )
+    if( ( attributes->domain_parameters == NULL ) &&
+        ( attributes->domain_parameters_size != 0 ) )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
     if( key_type_is_raw_bytes( type ) )
     {
-        psa_status_t status;
-
-        status = validate_unstructured_key_bit_size( slot->attr.type, bits );
+        status = psa_generate_random( key_buffer, key_buffer_size );
         if( status != PSA_SUCCESS )
             return( status );
 
-        /* Allocate memory for the key */
-        status = psa_allocate_buffer_to_slot( slot, PSA_BITS_TO_BYTES( bits ) );
-        if( status != PSA_SUCCESS )
-            return( status );
-
-        status = psa_generate_random( slot->key.data,
-                                      slot->key.bytes );
-        if( status != PSA_SUCCESS )
-            return( status );
-
-        slot->attr.bits = (psa_key_bits_t) bits;
 #if defined(MBEDTLS_DES_C)
         if( type == PSA_KEY_TYPE_DES )
-            psa_des_set_key_parity( slot->key.data,
-                                    slot->key.bytes );
+            psa_des_set_key_parity( key_buffer, key_buffer_size );
 #endif /* MBEDTLS_DES_C */
     }
     else
@@ -6023,49 +6038,10 @@
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
     if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR )
     {
-        mbedtls_rsa_context rsa;
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        int exponent;
-        psa_status_t status;
-        if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        /* Accept only byte-aligned keys, for the same reasons as
-         * in mbedtls_psa_rsa_import_key(). */
-        if( bits % 8 != 0 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        status = psa_read_rsa_exponent( domain_parameters,
-                                        domain_parameters_size,
-                                        &exponent );
-        if( status != PSA_SUCCESS )
-            return( status );
-        mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
-        ret = mbedtls_rsa_gen_key( &rsa,
-                                   mbedtls_psa_get_random,
-                                   MBEDTLS_PSA_RANDOM_STATE,
-                                   (unsigned int) bits,
-                                   exponent );
-        if( ret != 0 )
-            return( mbedtls_to_psa_error( ret ) );
-
-        /* Make sure to always have an export representation available */
-        size_t bytes = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits );
-
-        status = psa_allocate_buffer_to_slot( slot, bytes );
-        if( status != PSA_SUCCESS )
-        {
-            mbedtls_rsa_free( &rsa );
-            return( status );
-        }
-
-        status = mbedtls_psa_rsa_export_key( type,
-                                             &rsa,
-                                             slot->key.data,
-                                             bytes,
-                                             &slot->key.bytes );
-        mbedtls_rsa_free( &rsa );
-        if( status != PSA_SUCCESS )
-            psa_remove_key_data_from_memory( slot );
-        return( status );
+        return( mbedtls_psa_rsa_generate_key( attributes,
+                                              key_buffer,
+                                              key_buffer_size,
+                                              key_buffer_length ) );
     }
     else
 #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
@@ -6073,50 +6049,15 @@
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
     if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) )
     {
-        psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type );
-        mbedtls_ecp_group_id grp_id =
-            mbedtls_ecc_group_of_psa( curve, bits, 0 );
-        const mbedtls_ecp_curve_info *curve_info =
-            mbedtls_ecp_curve_info_from_grp_id( grp_id );
-        mbedtls_ecp_keypair ecp;
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        if( domain_parameters_size != 0 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        mbedtls_ecp_keypair_init( &ecp );
-        ret = mbedtls_ecp_gen_key( grp_id, &ecp,
-                                   mbedtls_psa_get_random,
-                                   MBEDTLS_PSA_RANDOM_STATE );
-        if( ret != 0 )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-
-
-        /* Make sure to always have an export representation available */
-        size_t bytes = PSA_BITS_TO_BYTES( bits );
-        psa_status_t status = psa_allocate_buffer_to_slot( slot, bytes );
-        if( status != PSA_SUCCESS )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( status );
-        }
-
-        status = mbedtls_to_psa_error(
-            mbedtls_ecp_write_key( &ecp, slot->key.data, bytes ) );
-
-        mbedtls_ecp_keypair_free( &ecp );
-        if( status != PSA_SUCCESS ) {
-            memset( slot->key.data, 0, bytes );
-            psa_remove_key_data_from_memory( slot );
-        }
-        return( status );
+        return( mbedtls_psa_ecp_generate_key( attributes,
+                                              key_buffer,
+                                              key_buffer_size,
+                                              key_buffer_length ) );
     }
     else
 #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
     {
+        (void)key_buffer_length;
         return( PSA_ERROR_NOT_SUPPORTED );
     }
 
@@ -6129,6 +6070,7 @@
     psa_status_t status;
     psa_key_slot_t *slot = NULL;
     psa_se_drv_table_entry_t *driver = NULL;
+    size_t key_buffer_size;
 
     *key = MBEDTLS_SVC_KEY_ID_INIT;
 
@@ -6142,15 +6084,42 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
-    status = psa_driver_wrapper_generate_key( attributes,
-                                              slot );
-    if( status != PSA_ERROR_NOT_SUPPORTED ||
-        psa_key_lifetime_is_external( attributes->core.lifetime ) )
-        goto exit;
+    /* In the case of a transparent key or an opaque key stored in local
+     * storage (thus not in the case of generating a key in a secure element
+     * or cryptoprocessor with storage), we have to allocate a buffer to
+     * hold the generated key material. */
+    if( slot->key.data == NULL )
+    {
+        if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) ==
+             PSA_KEY_LOCATION_LOCAL_STORAGE )
+        {
+            status = psa_validate_key_type_and_size_for_key_generation(
+                attributes->core.type, attributes->core.bits );
+            if( status != PSA_SUCCESS )
+                goto exit;
 
-    status = psa_generate_key_internal(
-        slot, attributes->core.bits,
-        attributes->domain_parameters, attributes->domain_parameters_size );
+            key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
+                                  attributes->core.type,
+                                  attributes->core.bits );
+        }
+        else
+        {
+            status = psa_driver_wrapper_get_key_buffer_size(
+                         attributes, &key_buffer_size );
+            if( status != PSA_SUCCESS )
+                goto exit;
+        }
+
+        status = psa_allocate_buffer_to_slot( slot, key_buffer_size );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    status = psa_driver_wrapper_generate_key( attributes,
+        slot->key.data, slot->key.bytes, &slot->key.bytes );
+
+    if( status != PSA_SUCCESS )
+        psa_remove_key_data_from_memory( slot );
 
 exit:
     if( status == PSA_SUCCESS )
@@ -6161,8 +6130,6 @@
     return( status );
 }
 
-
-
 /****************************************************************/
 /* Module setup */
 /****************************************************************/
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index cf9d6d0..9f10868 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -299,4 +299,29 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+/**
+ * \brief Generate a key.
+ *
+ * \note The signature of the function is that of a PSA driver generate_key
+ *       entry point.
+ *
+ * \param[in]  attributes         The attributes for the key to generate.
+ * \param[out] key_buffer         Buffer where the key data is to be written.
+ * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
+ * \param[out] key_buffer_length  On success, the number of bytes written in
+ *                                \p key_buffer.
+ *
+ * \retval #PSA_SUCCESS
+ *         The key was generated successfully.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Key size in bits or type not supported.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of \p key_buffer is too small.
+ */
+psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes,
+                                        uint8_t *key_buffer,
+                                        size_t key_buffer_size,
+                                        size_t *key_buffer_length );
+
 #endif /* PSA_CRYPTO_CORE_H */
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 1eb9ebe..3cb7557 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -238,62 +238,56 @@
 #endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
-#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-/** Calculate the size to allocate for buffering a key with given attributes.
+/** Get the key buffer size for the key material of a generated key in the
+ *  case of an opaque driver without storage.
  *
- * This function provides a way to get the expected size for storing a key with
- * the given attributes. This will be the size of the export representation for
- * cleartext keys, and a driver-defined size for keys stored by opaque drivers.
- *
- * \param[in] attributes        The key attribute structure of the key to store.
- * \param[out] expected_size    On success, a byte size large enough to contain
- *                              the declared key.
+ * \param[in] attributes  The key attributes.
+ * \param[out] key_buffer_size  Minimum buffer size to contain the key material
  *
  * \retval #PSA_SUCCESS
+ *         The minimum size for a buffer to contain the key material has been
+ *         returned successfully.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size in bits of the key is not valid.
  * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         The type and/or the size in bits of the key or the combination of
+ *         the two is not supported.
  */
-static psa_status_t get_expected_key_size( const psa_key_attributes_t *attributes,
-                                           size_t *expected_size )
+psa_status_t psa_driver_wrapper_get_key_buffer_size(
+    const psa_key_attributes_t *attributes,
+    size_t *key_buffer_size )
 {
-    size_t buffer_size = 0;
     psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
     psa_key_type_t key_type = attributes->core.type;
     size_t key_bits = attributes->core.bits;
 
+    *key_buffer_size = 0;
     switch( location )
     {
-        case PSA_KEY_LOCATION_LOCAL_STORAGE:
-            buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits );
-
-            if( buffer_size == 0 )
-                return( PSA_ERROR_NOT_SUPPORTED );
-
-            *expected_size = buffer_size;
-            return( PSA_SUCCESS );
-
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
 #ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION
-            *expected_size = test_size_function( key_type, key_bits );
+            *key_buffer_size = test_size_function( key_type, key_bits );
             return( PSA_SUCCESS );
 #else /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */
             if( PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) )
             {
-                int public_key_overhead = ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ?
-                                           PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) : 0 );
-                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                int public_key_overhead =
+                    ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ?
+                      PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) : 0 );
+                *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
                                  + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE
                                  + public_key_overhead;
             }
-            else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( attributes->core.type ) )
+            else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( key_type ) )
             {
-                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
                                  + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE;
             }
             else if ( !PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) &&
-                      !PSA_KEY_TYPE_IS_PUBLIC_KEY ( attributes->core.type ) )
+                      !PSA_KEY_TYPE_IS_PUBLIC_KEY ( key_type ) )
             {
-                *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
+                *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE
                                  + TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR
                                  * ( ( key_bits + 7 ) / 8 );
             }
@@ -306,21 +300,26 @@
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
         default:
+            (void)key_type;
+            (void)key_bits;
             return( PSA_ERROR_NOT_SUPPORTED );
     }
 }
-#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
 
-psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
-                                              psa_key_slot_t *slot )
+psa_status_t psa_driver_wrapper_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT)
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime);
+
     /* Try dynamically-registered SE interface first */
 #if defined(MBEDTLS_PSA_CRYPTO_SE_C)
     const psa_drv_se_t *drv;
     psa_drv_se_context_t *drv_context;
 
-    if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
+    if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) )
     {
         size_t pubkey_length = 0; /* We don't support this feature yet */
         if( drv->key_management == NULL ||
@@ -330,83 +329,53 @@
             return( PSA_ERROR_NOT_SUPPORTED );
         }
         return( drv->key_management->p_generate(
-            drv_context, psa_key_slot_get_slot_number( slot ),
+            drv_context,
+            *( (psa_key_slot_number_t *)key_buffer ),
             attributes, NULL, 0, &pubkey_length ) );
     }
 #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
 
-    /* Then try accelerator API */
-#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-    psa_status_t status = PSA_ERROR_INVALID_ARGUMENT;
-    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime);
-    size_t export_size = 0;
-
-    status = get_expected_key_size( attributes, &export_size );
-    if( status != PSA_SUCCESS )
-        return( status );
-
-    slot->key.data = mbedtls_calloc(1, export_size);
-    if( slot->key.data == NULL )
-        return( PSA_ERROR_INSUFFICIENT_MEMORY );
-    slot->key.bytes = export_size;
-
     switch( location )
     {
         case PSA_KEY_LOCATION_LOCAL_STORAGE:
-            /* Key is stored in the slot in export representation, so
-             * cycle through all known transparent accelerators */
-
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
             /* Transparent drivers are limited to generating asymmetric keys */
-            if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) )
+            if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) )
             {
-                status = PSA_ERROR_NOT_SUPPORTED;
-                break;
-            }
+            /* Cycle through all known transparent accelerators */
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = test_transparent_generate_key( attributes,
-                                                    slot->key.data,
-                                                    slot->key.bytes,
-                                                    &slot->key.bytes );
-            /* Declared with fallback == true */
-            if( status != PSA_ERROR_NOT_SUPPORTED )
-                break;
+                status = test_transparent_generate_key(
+                    attributes, key_buffer, key_buffer_size,
+                    key_buffer_length );
+                /* Declared with fallback == true */
+                if( status != PSA_ERROR_NOT_SUPPORTED )
+                    break;
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
-            status = PSA_ERROR_NOT_SUPPORTED;
+            }
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+            /* Software fallback */
+            status = psa_generate_key_internal(
+                attributes, key_buffer, key_buffer_size, key_buffer_length );
             break;
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LIFETIME:
-            status = test_opaque_generate_key( attributes,
-                                               slot->key.data,
-                                               slot->key.bytes,
-                                               &slot->key.bytes );
+            status = test_opaque_generate_key(
+                attributes, key_buffer, key_buffer_size, key_buffer_length );
             break;
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
             status = PSA_ERROR_INVALID_ARGUMENT;
             break;
     }
 
-    if( status != PSA_SUCCESS )
-    {
-        /* free allocated buffer */
-        mbedtls_free( slot->key.data );
-        slot->key.data = NULL;
-        slot->key.bytes = 0;
-    }
-
     return( status );
-#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) attributes;
-    (void) slot;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_import_key(
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 27d8b64..ad16cdd 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -63,9 +63,13 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+psa_status_t psa_driver_wrapper_get_key_buffer_size(
+    const psa_key_attributes_t *attributes,
+    size_t *key_buffer_size );
+
 psa_status_t psa_driver_wrapper_generate_key(
     const psa_key_attributes_t *attributes,
-    psa_key_slot_t *slot );
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
 
 /*
  * Cipher functions
diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c
index 1a8f15e..23ec6ac 100644
--- a/library/psa_crypto_ecp.c
+++ b/library/psa_crypto_ecp.c
@@ -292,6 +292,51 @@
 #endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
         * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
 
+#if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
+static psa_status_t ecp_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+    psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
+                                 attributes->core.type );
+    mbedtls_ecp_group_id grp_id =
+         mbedtls_ecc_group_of_psa( curve, attributes->core.bits, 0 );
+
+    const mbedtls_ecp_curve_info *curve_info =
+        mbedtls_ecp_curve_info_from_grp_id( grp_id );
+    mbedtls_ecp_keypair ecp;
+
+    if( attributes->domain_parameters_size != 0 )
+        return( PSA_ERROR_NOT_SUPPORTED );
+
+    if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
+        return( PSA_ERROR_NOT_SUPPORTED );
+
+    mbedtls_ecp_keypair_init( &ecp );
+    ret = mbedtls_ecp_gen_key( grp_id, &ecp,
+                               mbedtls_psa_get_random,
+                               MBEDTLS_PSA_RANDOM_STATE );
+    if( ret != 0 )
+    {
+        mbedtls_ecp_keypair_free( &ecp );
+        return( mbedtls_to_psa_error( ret ) );
+    }
+
+    status = mbedtls_to_psa_error(
+        mbedtls_ecp_write_key( &ecp, key_buffer, key_buffer_size ) );
+
+    mbedtls_ecp_keypair_free( &ecp );
+
+    if( status == PSA_SUCCESS )
+        *key_buffer_length = key_buffer_size;
+
+    return( status );
+}
+#endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
+
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
 
@@ -318,6 +363,16 @@
 #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
 
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
+psa_status_t mbedtls_psa_ecp_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    return( ecp_generate_key( attributes, key_buffer, key_buffer_size,
+                              key_buffer_length ) );
+}
+#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -350,6 +405,18 @@
 #endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) ||
           defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */
 
+#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \
+    defined(MBEDTLS_GENPRIME)
+psa_status_t mbedtls_transparent_test_driver_ecp_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    return( ecp_generate_key( attributes, key_buffer, key_buffer_size,
+                              key_buffer_length ) );
+}
+#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) &&
+          defined(MBEDTLS_GENPRIME) */
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_ecp.h b/library/psa_crypto_ecp.h
index 59b61b9..5c9b63c 100644
--- a/library/psa_crypto_ecp.h
+++ b/library/psa_crypto_ecp.h
@@ -123,11 +123,35 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+/**
+ * \brief Generate an ECP key.
+ *
+ * \note The signature of the function is that of a PSA driver generate_key
+ *       entry point.
+ *
+ * \param[in]  attributes         The attributes for the ECP key to generate.
+ * \param[out] key_buffer         Buffer where the key data is to be written.
+ * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
+ * \param[out] key_buffer_length  On success, the number of bytes written in
+ *                                \p key_buffer.
+ *
+ * \retval #PSA_SUCCESS
+ *         The key was successfully generated.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Key length or type not supported.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of \p key_buffer is too small.
+ */
+psa_status_t mbedtls_psa_ecp_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
 
 #if defined(PSA_CRYPTO_DRIVER_TEST)
+
 psa_status_t mbedtls_transparent_test_driver_ecp_import_key(
     const psa_key_attributes_t *attributes,
     const uint8_t *data, size_t data_length,
@@ -139,6 +163,10 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+psa_status_t mbedtls_transparent_test_driver_ecp_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_ECP_H */
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index aae1d05..fa64001 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -24,6 +24,7 @@
 
 #include <psa/crypto.h>
 #include "psa_crypto_core.h"
+#include "psa_crypto_random_impl.h"
 #include "psa_crypto_rsa.h"
 
 #include <stdlib.h>
@@ -258,6 +259,66 @@
 #endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
         * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
 
+#if defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
+static psa_status_t psa_rsa_read_exponent( const uint8_t *domain_parameters,
+                                           size_t domain_parameters_size,
+                                           int *exponent )
+{
+    size_t i;
+    uint32_t acc = 0;
+
+    if( domain_parameters_size == 0 )
+    {
+        *exponent = 65537;
+        return( PSA_SUCCESS );
+    }
+
+    /* Mbed TLS encodes the public exponent as an int. For simplicity, only
+     * support values that fit in a 32-bit integer, which is larger than
+     * int on just about every platform anyway. */
+    if( domain_parameters_size > sizeof( acc ) )
+        return( PSA_ERROR_NOT_SUPPORTED );
+    for( i = 0; i < domain_parameters_size; i++ )
+        acc = ( acc << 8 ) | domain_parameters[i];
+    if( acc > INT_MAX )
+        return( PSA_ERROR_NOT_SUPPORTED );
+    *exponent = acc;
+    return( PSA_SUCCESS );
+}
+
+static psa_status_t rsa_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    psa_status_t status;
+    mbedtls_rsa_context rsa;
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    int exponent;
+
+    status = psa_rsa_read_exponent( attributes->domain_parameters,
+                                    attributes->domain_parameters_size,
+                                    &exponent );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
+    ret = mbedtls_rsa_gen_key( &rsa,
+                               mbedtls_psa_get_random,
+                               MBEDTLS_PSA_RANDOM_STATE,
+                               (unsigned int)attributes->core.bits,
+                               exponent );
+    if( ret != 0 )
+        return( mbedtls_to_psa_error( ret ) );
+
+    status = mbedtls_psa_rsa_export_key( attributes->core.type,
+                                         &rsa, key_buffer, key_buffer_size,
+                                         key_buffer_length );
+    mbedtls_rsa_free( &rsa );
+
+    return( status );
+}
+#endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
+
 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \
     defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY)
 
@@ -284,6 +345,16 @@
 #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) ||
         * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */
 
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR)
+psa_status_t mbedtls_psa_rsa_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    return( rsa_generate_key( attributes, key_buffer, key_buffer_size,
+                              key_buffer_length ) );
+}
+#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -316,6 +387,16 @@
 #endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) ||
           defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) */
 
+#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR)
+psa_status_t mbedtls_transparent_test_driver_rsa_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
+{
+    return( rsa_generate_key( attributes, key_buffer, key_buffer_size,
+                              key_buffer_length ) );
+}
+#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) */
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h
index 64013df..08182a7 100644
--- a/library/psa_crypto_rsa.h
+++ b/library/psa_crypto_rsa.h
@@ -114,6 +114,29 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+/**
+ * \brief Generate an RSA key.
+ *
+ * \note The signature of the function is that of a PSA driver generate_key
+ *       entry point.
+ *
+ * \param[in]  attributes         The attributes for the RSA key to generate.
+ * \param[out] key_buffer         Buffer where the key data is to be written.
+ * \param[in]  key_buffer_size    Size of \p key_buffer in bytes.
+ * \param[out] key_buffer_length  On success, the number of bytes written in
+ *                                \p key_buffer.
+ *
+ * \retval #PSA_SUCCESS
+ *         The key was successfully generated.
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ *         Key length or type not supported.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of \p key_buffer is too small.
+ */
+psa_status_t mbedtls_psa_rsa_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -131,6 +154,10 @@
     const uint8_t *key_buffer, size_t key_buffer_size,
     uint8_t *data, size_t data_size, size_t *data_length );
 
+psa_status_t mbedtls_transparent_test_driver_rsa_generate_key(
+    const psa_key_attributes_t *attributes,
+    uint8_t *key, size_t key_size, size_t *key_length );
+
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_RSA_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index e9d15e4..1036a7c 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1371,7 +1371,7 @@
     scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS
     scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
     # Need to define the correct symbol and include the test driver header path in order to build with the test driver
-    make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
+    make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS"
 
     msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG"
     make test
diff --git a/tests/src/drivers/key_management.c b/tests/src/drivers/key_management.c
index be6a814..10a40c3 100644
--- a/tests/src/drivers/key_management.c
+++ b/tests/src/drivers/key_management.c
@@ -45,11 +45,6 @@
     const psa_key_attributes_t *attributes,
     uint8_t *key, size_t key_size, size_t *key_length )
 {
-#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \
-    !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
-    (void)attributes;
-#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR &&
-        * !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */
     ++test_driver_key_management_hooks.hits;
 
     if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS )
@@ -66,66 +61,26 @@
     }
 
     /* Copied from psa_crypto.c */
-#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \
-    defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY)
+#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR)
     if ( PSA_KEY_TYPE_IS_ECC( psa_get_key_type( attributes ) )
          && PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) )
     {
-        psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
-            psa_get_key_type( attributes ) );
-        mbedtls_ecp_group_id grp_id =
-            mbedtls_ecc_group_of_psa(
-                curve,
-                psa_get_key_bits( attributes ), 0 );
-        const mbedtls_ecp_curve_info *curve_info =
-            mbedtls_ecp_curve_info_from_grp_id( grp_id );
-        mbedtls_ecp_keypair ecp;
-        mbedtls_test_rnd_pseudo_info rnd_info;
-        memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
-
-        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-        if( attributes->domain_parameters_size != 0 )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-        if( curve_info->bit_size != psa_get_key_bits( attributes ) )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-        mbedtls_ecp_keypair_init( &ecp );
-        ret = mbedtls_ecp_gen_key( grp_id, &ecp,
-                                   &mbedtls_test_rnd_pseudo_rand,
-                                   &rnd_info );
-        if( ret != 0 )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-
-        /* Make sure to use export representation */
-        size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) );
-        if( key_size < bytes )
-        {
-            mbedtls_ecp_keypair_free( &ecp );
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-        psa_status_t status = mbedtls_to_psa_error(
-            mbedtls_mpi_write_binary( &ecp.d, key, bytes ) );
-
-        if( status == PSA_SUCCESS )
-        {
-            *key_length = bytes;
-        }
-        else
-        {
-            memset( key, 0, bytes );
-        }
-
-        mbedtls_ecp_keypair_free( &ecp );
-        return( status );
+        return( mbedtls_transparent_test_driver_ecp_generate_key(
+                    attributes, key, key_size, key_length ) );
     }
     else
-#endif /* MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR ||
-        * MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */
-    return( PSA_ERROR_NOT_SUPPORTED );
+#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) */
+
+#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR)
+    if ( psa_get_key_type( attributes ) == PSA_KEY_TYPE_RSA_KEY_PAIR )
+        return( mbedtls_transparent_test_driver_rsa_generate_key(
+                    attributes, key, key_size, key_length ) );
+    else
+#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) */
+    {
+        (void)attributes;
+        return( PSA_ERROR_NOT_SUPPORTED );
+    }
 }
 
 psa_status_t test_opaque_generate_key(
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index c37bdce..c981e98 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -2915,7 +2915,7 @@
 generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0
 
 PSA generate key: ECC, Curve25519, good
-depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_ECP_DP_CURVE25519_ENABLED:!MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_ECP_DP_CURVE25519_ENABLED
 generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0
 
 PSA generate key: RSA, default e
diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
index 1fd449f..14f84c0 100644
--- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data
+++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data
@@ -38,6 +38,10 @@
 depends_on:MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR
 generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_SUCCESS
 
+generate_key through transparent driver: fallback not available
+depends_on:!MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR
+generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_ERROR_NOT_SUPPORTED
+
 generate_key through transparent driver: error
 generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR