Dispatch cipher functions through the driver interface

Signed-off-by: gabor-mezei-arm <gabor.mezei@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 8932586..9a4bfb0 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3492,47 +3492,51 @@
                                  size_t *output_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-    size_t iv_length = 0;;
-    size_t olength;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
+    psa_key_type_t key_type;
+    size_t iv_length;
 
-    status = psa_cipher_encrypt_setup( &operation, key, alg );
+    /* The requested algorithm must be one that can be processed by cipher. */
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Fetch key material from key storage. */
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_ENCRYPT,
+                                                    alg );
     if( status != PSA_SUCCESS )
-        goto exit;
+        return( status );
 
-    *output_length = 0;
-    if( operation.iv_required )
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
+
+    key_type = slot->attr.type;
+    iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
+
+    if( iv_length > 0 )
     {
-        status = psa_cipher_generate_iv( &operation, output,
-                                         operation.default_iv_length,
-                                         &iv_length );
-        *output_length += iv_length;
+        if( output_size < iv_length )
+        {
+            status = PSA_ERROR_BUFFER_TOO_SMALL;
+            goto exit;
+        }
+
+        status = psa_generate_random( output, iv_length );
         if( status != PSA_SUCCESS )
             goto exit;
     }
 
-    olength = 0;
-    status = psa_cipher_update( &operation, input, input_length,
-                                output + iv_length, output_size - iv_length,
-                                &olength );
-    *output_length += olength;
-    if( status != PSA_SUCCESS )
-        goto exit;
-
-    olength = 0;
-    status = psa_cipher_finish( &operation, output + *output_length,
-                                output_size - *output_length, &olength );
-    *output_length += olength;
-    if( status != PSA_SUCCESS )
-        goto exit;
+    status = psa_driver_wrapper_cipher_encrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
 
 exit:
-    if ( status == PSA_SUCCESS )
-        status = psa_cipher_abort( &operation );
-    else
-        psa_cipher_abort( &operation );
+    unlock_status = psa_unlock_key_slot( slot );
 
-    return ( status );
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
 }
 
 psa_status_t psa_cipher_decrypt( mbedtls_svc_key_id_t key,
@@ -3544,43 +3548,32 @@
                                  size_t *output_length )
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
-    psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
-    size_t olength;
+    psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_slot_t *slot;
 
-    status = psa_cipher_decrypt_setup( &operation, key, alg );
+    /* The requested algorithm must be one that can be processed by cipher. */
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Fetch key material from key storage. */
+    status = psa_get_and_lock_key_slot_with_policy( key, &slot,
+                                                    PSA_KEY_USAGE_DECRYPT,
+                                                    alg );
     if( status != PSA_SUCCESS )
-        goto exit;
+        return( status );
 
-    if( operation.iv_required )
-    {
-        status = psa_cipher_set_iv( &operation, input,
-                                    operation.default_iv_length );
-        if( status != PSA_SUCCESS )
-            goto exit;
-    }
+    psa_key_attributes_t attributes = {
+      .core = slot->attr
+    };
 
-    olength = 0;
-    status = psa_cipher_update( &operation, input + operation.default_iv_length,
-                                input_length - operation.default_iv_length,
-                                output, output_size, &olength );
-    *output_length = olength;
-    if( status != PSA_SUCCESS )
-        goto exit;
+    status = psa_driver_wrapper_cipher_decrypt(
+        &attributes, slot->key.data, slot->key.bytes,
+        alg, input, input_length,
+        output, output_size, output_length );
 
-    olength = 0;
-    status = psa_cipher_finish( &operation, output + *output_length,
-                                output_size - *output_length, &olength );
-    *output_length += olength;
-    if( status != PSA_SUCCESS )
-        goto exit;
+    unlock_status = psa_unlock_key_slot( slot );
 
-exit:
-    if ( status == PSA_SUCCESS )
-        status = psa_cipher_abort( &operation );
-    else
-        psa_cipher_abort( &operation );
-
-    return ( status );
+    return( ( status == PSA_SUCCESS ) ? unlock_status : status );
 }
 
 
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index a65e884..b018e2a 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -445,6 +445,107 @@
 
     return( PSA_SUCCESS );
 }
+
+static psa_status_t cipher_encrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength;
+
+   status = cipher_encrypt_setup( &operation, attributes,
+                                  key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    *output_length = 0;
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, output, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+
+        *output_length = operation.iv_length;
+    }
+
+    olength = 0;
+    status = cipher_update( &operation, input, input_length,
+                            output + *output_length,output_size - *output_length,
+                            &olength );
+    *output_length += olength;
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    olength = 0;
+    status = cipher_finish( &operation, output + *output_length,
+                            output_size - *output_length, &olength );
+    *output_length += olength;
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+exit:
+    if( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
+
+static psa_status_t cipher_decrypt( const psa_key_attributes_t *attributes,
+                                    const uint8_t *key_buffer,
+                                    size_t key_buffer_size,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length )
+{
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
+    size_t olength;
+
+    status = cipher_decrypt_setup( &operation, attributes,
+                                   key_buffer, key_buffer_size, alg );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    if( operation.iv_length > 0 )
+    {
+        status = cipher_set_iv( &operation, input, operation.iv_length );
+        if( status != PSA_SUCCESS )
+            goto exit;
+    }
+
+    olength = 0;
+    status = cipher_update( &operation, input + operation.iv_length,
+                            input_length - operation.iv_length,
+                            output, output_size, &olength );
+    *output_length = olength;
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    olength = 0;
+    status = cipher_finish( &operation, output + *output_length,
+                            output_size - *output_length, &olength );
+    *output_length += olength;
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+exit:
+    if ( status == PSA_SUCCESS )
+        status = cipher_abort( &operation );
+    else
+        cipher_abort( &operation );
+    return( status );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER || PSA_CRYPTO_DRIVER_TEST */
 
 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
@@ -498,6 +599,36 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
 
 /*
@@ -553,6 +684,38 @@
 {
     return( cipher_abort( operation ) );
 }
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_encrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
+{
+    return( cipher_decrypt( attributes, key_buffer, key_buffer_size,
+                            alg, input, input_length,
+                            output, output_size, output_length ) );
+}
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h
index 3e1a7a0..2dd3330 100644
--- a/library/psa_crypto_cipher.h
+++ b/library/psa_crypto_cipher.h
@@ -199,6 +199,104 @@
  */
 psa_status_t mbedtls_psa_cipher_abort( mbedtls_psa_cipher_operation_t *operation );
 
+/** Encrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_encrypt entry point. This function behaves as a
+ *       cipher_encrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in] attributes        The attributes of the key to use for the
+ *                              operation.
+ * \param[in] key_buffer        The buffer containing the key context.
+ * \param[in] key_buffer_size   Size of the \p key_buffer buffer in bytes.
+ * \param[in] alg               The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the iv and the plaintext.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[in,out] output        Buffer where the output is to be written.
+ *                              The IV must be written to this buffer before
+ *                              this function is called.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes
+ *                              that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
+/** Decrypt a message using a symmetric cipher.
+ *
+ * \note The signature of this function is that of a PSA driver
+ *       cipher_decrypt entry point. This function behaves as a
+ *       cipher_decrypt entry point as defined in the PSA driver
+ *       interface specification for transparent drivers.
+ *
+ * \param[in]  attributes       The attributes of the key to use for the
+ *                              operation.
+ * \param[in]  key_buffer       The buffer containing the key context.
+ * \param[in]  key_buffer_size  Size of the \p key_buffer buffer in bytes.
+ * \param[in]  alg              The cipher algorithm to compute
+ *                              (\c PSA_ALG_XXX value such that
+ *                              #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param[in]  input            Buffer containing the iv and the  ciphertext.
+ * \param[in]  input_length     Size of the \p input buffer in bytes.
+ * \param[out] output           Buffer where the output is to be written.
+ * \param[in]  output_size      Size of the \p output buffer in bytes.
+ * \param[out] output_length    On success, the number of bytes
+ *                              that make up the returned output.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ *         The size of the \p output buffer is too small.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ *         The size of \p iv is not acceptable for the chosen algorithm,
+ *         or the chosen algorithm does not use an IV.
+ *         The total input size passed to this operation is not valid for
+ *         this particular algorithm. For example, the algorithm is a based
+ *         on block cipher and requires a whole number of blocks, but the
+ *         total input size is not a multiple of the block size.
+ * \retval #PSA_ERROR_INVALID_PADDING
+ *         This is a decryption operation for an algorithm that includes
+ *         padding, and the ciphertext does not contain valid padding.
+ */
+psa_status_t mbedtls_psa_cipher_decrypt( const psa_key_attributes_t *attributes,
+                                         const uint8_t *key_buffer,
+                                         size_t key_buffer_size,
+                                         psa_algorithm_t alg,
+                                         const uint8_t *input,
+                                         size_t input_length,
+                                         uint8_t *output,
+                                         size_t output_size,
+                                         size_t *output_length );
+
 /*
  * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
  */
@@ -231,6 +329,28 @@
 
 psa_status_t mbedtls_transparent_test_driver_cipher_abort(
     mbedtls_psa_cipher_operation_t *operation );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
+
+psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
+    psa_algorithm_t alg,
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
 
 #endif /* PSA_CRYPTO_CIPHER_H */
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 19260c4..6bf08d9 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -737,7 +737,9 @@
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -745,22 +747,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && 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);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     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)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_encrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_encrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -771,14 +771,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_encrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
             return( PSA_ERROR_NOT_SUPPORTED );
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_encrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_encrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -786,25 +801,27 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -812,22 +829,20 @@
     size_t output_size,
     size_t *output_length )
 {
-#if defined(PSA_CRYPTO_DRIVER_PRESENT) && 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);
-    psa_key_attributes_t attributes = {
-      .core = slot->attr
-    };
+    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+    psa_key_location_t location =
+        PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime );
 
     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)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
-            status = mbedtls_test_transparent_cipher_decrypt( &attributes,
-                                                              slot->key.data,
-                                                              slot->key.bytes,
+            status = mbedtls_test_transparent_cipher_decrypt( attributes,
+                                                              key_buffer,
+                                                              key_buffer_size,
                                                               alg,
                                                               input,
                                                               input_length,
@@ -838,14 +853,29 @@
             if( status != PSA_ERROR_NOT_SUPPORTED )
                 return( status );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
-            /* Fell through, meaning no accelerator supports this operation */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
+#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
+            return( mbedtls_psa_cipher_decrypt( attributes,
+                                                key_buffer,
+                                                key_buffer_size,
+                                                alg,
+                                                input,
+                                                input_length,
+                                                output,
+                                                output_size,
+                                                output_length ) );
+#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
+
             return( PSA_ERROR_NOT_SUPPORTED );
+
         /* Add cases for opaque driver here */
+#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
 #if defined(PSA_CRYPTO_DRIVER_TEST)
         case PSA_CRYPTO_TEST_DRIVER_LOCATION:
-            return( mbedtls_test_opaque_cipher_decrypt( &attributes,
-                                                        slot->key.data,
-                                                        slot->key.bytes,
+            return( mbedtls_test_opaque_cipher_decrypt( attributes,
+                                                        key_buffer,
+                                                        key_buffer_size,
                                                         alg,
                                                         input,
                                                         input_length,
@@ -853,21 +883,21 @@
                                                         output_size,
                                                         output_length ) );
 #endif /* PSA_CRYPTO_DRIVER_TEST */
+#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
+
         default:
             /* Key is declared with a lifetime not known to us */
-            return( status );
+            (void)status;
+            (void)key_buffer;
+            (void)key_buffer_size;
+            (void)alg;
+            (void)input;
+            (void)input_length;
+            (void)output;
+            (void)output_size;
+            (void)output_length;
+            return( PSA_ERROR_INVALID_ARGUMENT );
     }
-#else /* PSA_CRYPTO_DRIVER_PRESENT */
-    (void) slot;
-    (void) alg;
-    (void) input;
-    (void) input_length;
-    (void) output;
-    (void) output_size;
-    (void) output_length;
-
-    return( PSA_ERROR_NOT_SUPPORTED );
-#endif /* PSA_CRYPTO_DRIVER_PRESENT */
 }
 
 psa_status_t psa_driver_wrapper_cipher_encrypt_setup(
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 732ed2a..38a6ee8 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -98,7 +98,9 @@
  * Cipher functions
  */
 psa_status_t psa_driver_wrapper_cipher_encrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
@@ -107,7 +109,9 @@
     size_t *output_length );
 
 psa_status_t psa_driver_wrapper_cipher_decrypt(
-    psa_key_slot_t *slot,
+    const psa_key_attributes_t *attributes,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
     const uint8_t *input,
     size_t input_length,
diff --git a/tests/src/drivers/test_driver_cipher.c b/tests/src/drivers/test_driver_cipher.c
index 9c95cc8..89a7b59 100644
--- a/tests/src/drivers/test_driver_cipher.c
+++ b/tests/src/drivers/test_driver_cipher.c
@@ -35,26 +35,19 @@
 mbedtls_test_driver_cipher_hooks_t mbedtls_test_driver_cipher_hooks =
     MBEDTLS_TEST_DRIVER_CIPHER_INIT;
 
-static psa_status_t mbedtls_test_transparent_cipher_oneshot(
-    mbedtls_operation_t direction,
+psa_status_t mbedtls_test_transparent_cipher_encrypt(
     const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
 {
     mbedtls_test_driver_cipher_hooks.hits++;
 
-    /* Test driver supports AES-CTR only, to verify operation calls. */
-    if( alg != PSA_ALG_CTR ||
-        psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES )
-        return( PSA_ERROR_NOT_SUPPORTED );
-
-    /* If test driver response code is not SUCCESS, we can return early */
-    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
-        return( mbedtls_test_driver_cipher_hooks.forced_status );
-
-    /* If test driver output is overridden, we don't need to do actual crypto */
     if( mbedtls_test_driver_cipher_hooks.forced_output != NULL )
     {
         if( output_size < mbedtls_test_driver_cipher_hooks.forced_output_length )
@@ -68,133 +61,50 @@
         return( mbedtls_test_driver_cipher_hooks.forced_status );
     }
 
-    /* Run AES-CTR using the cipher module */
-    {
-        mbedtls_test_rnd_pseudo_info rnd_info;
-        memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
+    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
 
-        const mbedtls_cipher_info_t *cipher_info =
-            mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES,
-                                             key_length * 8,
-                                             MBEDTLS_MODE_CTR );
-        mbedtls_cipher_context_t cipher;
-        int ret = 0;
-        uint8_t temp_output_buffer[16] = {0};
-        size_t temp_output_length = 0;
+    psa_generate_random( output, PSA_CIPHER_IV_LENGTH( attributes->core.type, alg ) );
 
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            /* Oneshot encrypt needs to prepend the IV to the output */
-            if( output_size < ( input_length + 16 ) )
-                return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-        else
-        {
-            /* Oneshot decrypt has the IV prepended to the input */
-            if( output_size < ( input_length - 16 ) )
-                return( PSA_ERROR_BUFFER_TOO_SMALL );
-        }
-
-        if( cipher_info == NULL )
-            return( PSA_ERROR_NOT_SUPPORTED );
-
-        mbedtls_cipher_init( &cipher );
-        ret = mbedtls_cipher_setup( &cipher, cipher_info );
-        if( ret != 0 )
-            goto exit;
-
-        ret = mbedtls_cipher_setkey( &cipher,
-                                     key,
-                                     key_length * 8, direction );
-        if( ret != 0 )
-            goto exit;
-
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            mbedtls_test_rnd_pseudo_info rnd_info;
-            memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
-
-            ret = mbedtls_test_rnd_pseudo_rand( &rnd_info,
-                                                temp_output_buffer,
-                                                16 );
-            if( ret != 0 )
-                goto exit;
-
-            ret = mbedtls_cipher_set_iv( &cipher, temp_output_buffer, 16 );
-        }
-        else
-            ret = mbedtls_cipher_set_iv( &cipher, input, 16 );
-
-        if( ret != 0 )
-            goto exit;
-
-        if( direction == MBEDTLS_ENCRYPT )
-        {
-            ret = mbedtls_cipher_update( &cipher,
-                                         input, input_length,
-                                         &output[16], output_length );
-            if( ret == 0 )
-            {
-                memcpy( output, temp_output_buffer, 16 );
-                *output_length += 16;
-            }
-        }
-        else
-            ret = mbedtls_cipher_update( &cipher,
-                                         &input[16], input_length - 16,
-                                         output, output_length );
-
-        if( ret != 0 )
-            goto exit;
-
-        ret = mbedtls_cipher_finish( &cipher,
-                                     temp_output_buffer,
-                                     &temp_output_length );
-
-exit:
-        if( ret != 0 )
-        {
-            *output_length = 0;
-            memset(output, 0, output_size);
-        }
-
-        mbedtls_cipher_free( &cipher );
-        return( mbedtls_to_psa_error( ret ) );
-    }
-}
-
-psa_status_t mbedtls_test_transparent_cipher_encrypt(
-    const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
-    psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
-{
-    return (
-        mbedtls_test_transparent_cipher_oneshot(
-            MBEDTLS_ENCRYPT,
-            attributes,
-            key, key_length,
-            alg,
-            input, input_length,
-            output, output_size, output_length) );
+    return( mbedtls_transparent_test_driver_cipher_encrypt(
+                attributes, key_buffer, key_buffer_size,
+                alg, input, input_length,
+                output, output_size, output_length ) );
 }
 
 psa_status_t mbedtls_test_transparent_cipher_decrypt(
     const psa_key_attributes_t *attributes,
-    const uint8_t *key, size_t key_length,
+    const uint8_t *key_buffer,
+    size_t key_buffer_size,
     psa_algorithm_t alg,
-    const uint8_t *input, size_t input_length,
-    uint8_t *output, size_t output_size, size_t *output_length)
+    const uint8_t *input,
+    size_t input_length,
+    uint8_t *output,
+    size_t output_size,
+    size_t *output_length )
 {
-    return (
-        mbedtls_test_transparent_cipher_oneshot(
-            MBEDTLS_DECRYPT,
-            attributes,
-            key, key_length,
-            alg,
-            input, input_length,
-            output, output_size, output_length) );
+   mbedtls_test_driver_cipher_hooks.hits++;
+
+    if( mbedtls_test_driver_cipher_hooks.forced_output != NULL )
+    {
+        if( output_size < mbedtls_test_driver_cipher_hooks.forced_output_length )
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
+        memcpy( output,
+                mbedtls_test_driver_cipher_hooks.forced_output,
+                mbedtls_test_driver_cipher_hooks.forced_output_length );
+        *output_length = mbedtls_test_driver_cipher_hooks.forced_output_length;
+
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
+    }
+
+    if( mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
+        return( mbedtls_test_driver_cipher_hooks.forced_status );
+
+    return( mbedtls_transparent_test_driver_cipher_decrypt(
+                attributes, key_buffer, key_buffer_size,
+                alg, input, input_length,
+                output, output_size, output_length ) );
 }
 
 psa_status_t mbedtls_test_transparent_cipher_encrypt_setup(