Crypto: Implement additional PSA Crypto APIs

This patch implements additional missing APIs available
in the PSA Crypto API headers.

Change-Id: I453f6829ed2c87a47546514becda599ecd1273a4
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/ConfigPsaApiTest.cmake b/ConfigPsaApiTest.cmake
index e66a821..a449aaf 100644
--- a/ConfigPsaApiTest.cmake
+++ b/ConfigPsaApiTest.cmake
@@ -49,7 +49,7 @@
 
 #Service specific configuration for the PSA API Compliance test requirements
 if(PSA_API_TEST_CRYPTO)
-	set(CRYPTO_ENGINE_BUF_SIZE 3072)
+	set(CRYPTO_ENGINE_BUF_SIZE 20480)
 endif()
 
 include ("${CMAKE_CURRENT_LIST_DIR}/CommonConfig.cmake")
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index ec11613..436cc81 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -45,6 +45,7 @@
     uint32_t op_handle;          /*!< Frontend context handle associated to a
                                   *   multipart operation
                                   */
+    size_t capacity;             /*!< Generator capacity */
 
     struct tfm_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
                                                 *   AEAD until the API is
@@ -53,36 +54,55 @@
 };
 
 /**
- * \brief Define a numerical value for each SFID which can be used when
- *        dispatching the requests to the service
+ * \brief Define a progressive numerical value for each SFID which can be used
+ *        when dispatching the requests to the service
  */
-#define TFM_CRYPTO_ALLOCATE_KEY_SFID             (0u)
-#define TFM_CRYPTO_IMPORT_KEY_SFID               (1u)
-#define TFM_CRYPTO_DESTROY_KEY_SFID              (2u)
-#define TFM_CRYPTO_GET_KEY_INFORMATION_SFID      (3u)
-#define TFM_CRYPTO_EXPORT_KEY_SFID               (4u)
-#define TFM_CRYPTO_SET_KEY_POLICY_SFID           (5u)
-#define TFM_CRYPTO_GET_KEY_POLICY_SFID           (6u)
-#define TFM_CRYPTO_GET_KEY_LIFETIME_SFID         (7u)
-#define TFM_CRYPTO_CIPHER_SET_IV_SFID            (8u)
-#define TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID     (9u)
-#define TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID     (10u)
-#define TFM_CRYPTO_CIPHER_UPDATE_SFID            (11u)
-#define TFM_CRYPTO_CIPHER_ABORT_SFID             (12u)
-#define TFM_CRYPTO_CIPHER_FINISH_SFID            (13u)
-#define TFM_CRYPTO_HASH_SETUP_SFID               (14u)
-#define TFM_CRYPTO_HASH_UPDATE_SFID              (15u)
-#define TFM_CRYPTO_HASH_FINISH_SFID              (16u)
-#define TFM_CRYPTO_HASH_VERIFY_SFID              (17u)
-#define TFM_CRYPTO_HASH_ABORT_SFID               (18u)
-#define TFM_CRYPTO_MAC_SIGN_SETUP_SFID           (19u)
-#define TFM_CRYPTO_MAC_VERIFY_SETUP_SFID         (20u)
-#define TFM_CRYPTO_MAC_UPDATE_SFID               (21u)
-#define TFM_CRYPTO_MAC_SIGN_FINISH_SFID          (22u)
-#define TFM_CRYPTO_MAC_VERIFY_FINISH_SFID        (23u)
-#define TFM_CRYPTO_MAC_ABORT_SFID                (24u)
-#define TFM_CRYPTO_AEAD_ENCRYPT_SFID             (25u)
-#define TFM_CRYPTO_AEAD_DECRYPT_SFID             (26u)
+enum {
+    TFM_CRYPTO_ALLOCATE_KEY_SFID = (0u),
+    TFM_CRYPTO_IMPORT_KEY_SFID,
+    TFM_CRYPTO_DESTROY_KEY_SFID,
+    TFM_CRYPTO_GET_KEY_INFORMATION_SFID,
+    TFM_CRYPTO_EXPORT_KEY_SFID,
+    TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+    TFM_CRYPTO_COPY_KEY_SFID,
+    TFM_CRYPTO_SET_KEY_POLICY_SFID,
+    TFM_CRYPTO_GET_KEY_POLICY_SFID,
+    TFM_CRYPTO_GET_KEY_LIFETIME_SFID,
+    TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+    TFM_CRYPTO_CIPHER_SET_IV_SFID,
+    TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SFID,
+    TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SFID,
+    TFM_CRYPTO_CIPHER_UPDATE_SFID,
+    TFM_CRYPTO_CIPHER_ABORT_SFID,
+    TFM_CRYPTO_CIPHER_FINISH_SFID,
+    TFM_CRYPTO_HASH_SETUP_SFID,
+    TFM_CRYPTO_HASH_UPDATE_SFID,
+    TFM_CRYPTO_HASH_FINISH_SFID,
+    TFM_CRYPTO_HASH_VERIFY_SFID,
+    TFM_CRYPTO_HASH_ABORT_SFID,
+    TFM_CRYPTO_HASH_CLONE_SFID,
+    TFM_CRYPTO_MAC_SIGN_SETUP_SFID,
+    TFM_CRYPTO_MAC_VERIFY_SETUP_SFID,
+    TFM_CRYPTO_MAC_UPDATE_SFID,
+    TFM_CRYPTO_MAC_SIGN_FINISH_SFID,
+    TFM_CRYPTO_MAC_VERIFY_FINISH_SFID,
+    TFM_CRYPTO_MAC_ABORT_SFID,
+    TFM_CRYPTO_AEAD_ENCRYPT_SFID,
+    TFM_CRYPTO_AEAD_DECRYPT_SFID,
+    TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+    TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+    TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+    TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+    TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+    TFM_CRYPTO_GENERATOR_READ_SFID,
+    TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+    TFM_CRYPTO_GENERATOR_ABORT_SFID,
+    TFM_CRYPTO_KEY_DERIVATION_SFID,
+    TFM_CRYPTO_KEY_AGREEMENT_SFID,
+    TFM_CRYPTO_GENERATE_RANDOM_SFID,
+    TFM_CRYPTO_GENERATE_KEY_SFID,
+    TFM_CRYPTO_SFID_MAX,
+};
 
 /**
  * \brief Define the SID values and minor versions to match the ones defined in
@@ -92,10 +112,9 @@
 #define TFM_CRYPTO_MIN_VER (0x0001)
 
 /**
- * \brief Define the maximum value based on the previous list, and
- *        an invalid value
+ * \brief Define an invalid value for an SFID
+ *
  */
-#define TFM_CRYPTO_SFID_MAX (TFM_CRYPTO_AEAD_DECRYPT_SFID + 1u)
 #define TFM_CRYPTO_SFID_INVALID (~0x0u)
 
 /**
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index b020acc..1bbaf76 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -36,9 +36,12 @@
 psa_status_t tfm_tfm_crypto_destroy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_get_key_information_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_export_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_export_public_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_copy_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_set_key_policy_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_get_key_policy_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_get_key_lifetime_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_cipher_generate_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_cipher_set_iv_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_cipher_encrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_cipher_decrypt_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
@@ -50,14 +53,27 @@
 psa_status_t tfm_tfm_crypto_hash_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_hash_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_hash_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_hash_clone_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_sign_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_verify_setup_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_update_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_sign_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_verify_finish_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_mac_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
-psa_status_t tfm_tfm_crypto_aead_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 psa_status_t tfm_tfm_crypto_aead_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_aead_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_sign_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_verify_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_encrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_asymmetric_decrypt_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_get_generator_capacity_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_read_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_import_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generator_abort_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_key_derivation_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_key_agreement_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generate_random_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_tfm_crypto_generate_key_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 
 /******** TFM_SP_PLATFORM ********/
 psa_status_t tfm_platform_sp_system_reset_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index fe8a537..92d47d1 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -91,7 +91,7 @@
     (void)id;
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -103,7 +103,7 @@
     (void)id;
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -111,7 +111,7 @@
 {
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -236,25 +236,62 @@
                                    size_t data_size,
                                    size_t *data_length)
 {
-    (void)handle;
-    (void)data;
-    (void)data_size;
-    (void)data_length;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+        .key_handle = handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = data, .len = data_size}
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_export_public_key,
+                          TFM_CRYPTO_EXPORT_PUBLIC_KEY);
+
+    *data_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 psa_status_t psa_copy_key(psa_key_handle_t source_handle,
                           psa_key_handle_t target_handle,
                           const psa_key_policy_t *constraint)
 {
-    (void)source_handle;
-    (void)target_handle;
-    (void)constraint;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_COPY_KEY_SFID,
+        .key_handle = source_handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &target_handle, .len = sizeof(psa_key_handle_t)},
+        {.base = constraint, .len = sizeof(psa_key_policy_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_copy_key,
+                                    TFM_CRYPTO_COPY_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 void psa_key_policy_set_usage(psa_key_policy_t *policy,
@@ -365,13 +402,34 @@
                                     size_t iv_size,
                                     size_t *iv_length)
 {
-    (void) operation;
-    (void) iv;
-    (void) iv_size;
-    (void) iv_length;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+        .op_handle = operation->handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = iv, .len = iv_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_generate_iv,
+                          TFM_CRYPTO_CIPHER_GENERATE_IV);
+
+    *iv_length = out_vec[1].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
@@ -730,11 +788,30 @@
 psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
                             psa_hash_operation_t *target_operation)
 {
-    (void)source_operation;
-    (void)target_operation;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_CLONE_SFID,
+        .op_handle = source_operation->handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = target_operation, .len = sizeof(psa_hash_operation_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_clone,
+                          TFM_CRYPTO_HASH_CLONE);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
@@ -947,6 +1024,11 @@
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
 
+    /* Sanitize the optional input */
+    if ((additional_data == NULL) && (additional_data_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     size_t idx = 0;
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1012,6 +1094,11 @@
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
 
+    /* Sanitize the optional input */
+    if ((additional_data == NULL) && (additional_data_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     size_t idx = 0;
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1056,3 +1143,491 @@
 
     return status;
 }
+
+psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *hash,
+                                 size_t hash_length,
+                                 uint8_t *signature,
+                                 size_t signature_size,
+                                 size_t *signature_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+        .key_handle = handle,
+        .alg = alg,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = hash, .len = hash_length},
+    };
+    psa_outvec out_vec[] = {
+        {.base = signature, .len = signature_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_asymmetric_sign,
+                          TFM_CRYPTO_ASYMMETRIC_SIGN);
+
+    *signature_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+                                   psa_algorithm_t alg,
+                                   const uint8_t *hash,
+                                   size_t hash_length,
+                                   const uint8_t *signature,
+                                   size_t signature_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = hash, .len = hash_length},
+        {.base = signature, .len = signature_length}
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_asymmetric_verify,
+                                    TFM_CRYPTO_ASYMMETRIC_VERIFY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    const uint8_t *salt,
+                                    size_t salt_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+        {.base = salt, .len = salt_length}
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (salt == NULL) {
+        in_len--;
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_asymmetric_encrypt,
+                          TFM_CRYPTO_ASYMMETRIC_ENCRYPT);
+#endif
+
+    *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    const uint8_t *salt,
+                                    size_t salt_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+        {.base = salt, .len = salt_length}
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (salt == NULL) {
+        in_len--;
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_asymmetric_decrypt,
+                          TFM_CRYPTO_ASYMMETRIC_DECRYPT);
+#endif
+
+    *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = capacity, .len = sizeof(size_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_get_generator_capacity,
+                          TFM_CRYPTO_GET_GENERATOR_CAPACITY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+                                uint8_t *output,
+                                size_t output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_READ_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_length},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generator_read,
+                          TFM_CRYPTO_GENERATOR_READ);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_generator_import_key(psa_key_handle_t handle,
+                                      psa_key_type_t type,
+                                      size_t bits,
+                                      psa_crypto_generator_t *generator)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+        .key_handle = handle,
+        .type = type,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &bits, .len = sizeof(size_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generator_import_key,
+                                    TFM_CRYPTO_GENERATOR_IMPORT_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_ABORT_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generator_abort,
+                          TFM_CRYPTO_GENERATOR_ABORT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+                                psa_key_handle_t handle,
+                                psa_algorithm_t alg,
+                                const uint8_t *salt,
+                                size_t salt_length,
+                                const uint8_t *label,
+                                size_t label_length,
+                                size_t capacity)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SFID,
+        .key_handle = handle,
+        .alg = alg,
+        .op_handle = generator->handle,
+        .capacity = capacity,
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((label == NULL) && (label_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = salt, .len = salt_length},
+        {.base = label, .len = label_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (label == NULL) {
+        in_len--;
+        if (salt == NULL) {
+            in_len--;
+        }
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_key_derivation,
+                          TFM_CRYPTO_KEY_DERIVATION);
+#endif
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
+                               psa_key_handle_t private_key,
+                               const uint8_t *peer_key,
+                               size_t peer_key_length,
+                               psa_algorithm_t alg)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_AGREEMENT_SFID,
+        .key_handle = private_key,
+        .alg = alg,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = peer_key, .len = peer_key_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_key_agreement,
+                          TFM_CRYPTO_KEY_AGREEMENT);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_generate_random(uint8_t *output,
+                                 size_t output_size)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATE_RANDOM_SFID,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    if (output_size == 0) {
+        return PSA_SUCCESS;
+    }
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generate_random,
+                          TFM_CRYPTO_GENERATE_RANDOM);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+psa_status_t psa_generate_key(psa_key_handle_t handle,
+                              psa_key_type_t type,
+                              size_t bits,
+                              const void *extra,
+                              size_t extra_size)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATE_KEY_SFID,
+        .key_handle = handle,
+        .type = type,
+    };
+
+    /* Sanitize the optional input */
+    if ((extra == NULL) && (extra_size != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &bits, .len = sizeof(size_t)},
+        {.base = extra, .len = extra_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (extra == NULL) {
+        in_len--;
+    }
+
+    status = psa_call(ipc_handle, in_vec, in_len, NULL, 0);
+#else
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generate_key,
+                                    TFM_CRYPTO_GENERATE_KEY);
+#endif
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
diff --git a/lib/t_cose/src/t_cose_psa_crypto_sign.c b/lib/t_cose/src/t_cose_psa_crypto_sign.c
index 19b29bd..85fb8f5 100644
--- a/lib/t_cose/src/t_cose_psa_crypto_sign.c
+++ b/lib/t_cose/src/t_cose_psa_crypto_sign.c
@@ -15,6 +15,15 @@
 /* Avoid compiler warning due to unused argument */
 #define ARG_UNUSED(arg) (void)(arg)
 
+/* FixMe: To be removed when the real Crypto API is used */
+psa_status_t psa_asymmetric_sign_stub(psa_key_handle_t handle,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *hash,
+                                 size_t hash_length,
+                                 uint8_t *signature,
+                                 size_t signature_size,
+                                 size_t *signature_length);
+
 enum t_cose_err_t
 t_cose_crypto_pub_key_sign(int32_t cose_alg_id,
                            int32_t key_select,
@@ -44,13 +53,14 @@
         return T_COSE_ERR_FAIL;
     }
 
-    psa_ret = psa_asymmetric_sign(key_handle_private,
-                                  0, /* FixMe: algorithm ID */
-                                  hash_to_sign.ptr,
-                                  hash_to_sign.len,
-                                  signature_buffer.ptr, /* Sig buf */
-                                  signature_buffer.len, /* Sig buf size */
-                                  &(signature->len));   /* Sig length */
+    /* FixMe: To be removed when the real Crypto API is used */
+    psa_ret = psa_asymmetric_sign_stub(key_handle_private,
+                                       0, /* FixMe: algorithm ID */
+                                       hash_to_sign.ptr,
+                                       hash_to_sign.len,
+                                       signature_buffer.ptr, /* Sig buf */
+                                       signature_buffer.len, /* Sig buf size */
+                                       &(signature->len));   /* Sig length */
 
     if (psa_ret != PSA_SUCCESS) {
         return T_COSE_ERR_FAIL;
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 4621280..d1cb113 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -30,9 +30,12 @@
 psa_status_t tfm_crypto_destroy_key(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_get_key_information(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_export_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_export_public_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_copy_key(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_set_key_policy(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_get_key_policy(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_get_key_lifetime(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_cipher_generate_iv(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_cipher_set_iv(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_cipher_decrypt_setup(psa_invec *, size_t, psa_outvec *, size_t);
@@ -44,14 +47,27 @@
 psa_status_t tfm_crypto_hash_finish(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_hash_verify(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_hash_abort(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_hash_clone(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_sign_setup(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_verify_setup(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_update(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_sign_finish(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_verify_finish(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_mac_abort(psa_invec *, size_t, psa_outvec *, size_t);
-psa_status_t tfm_crypto_aead_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t tfm_crypto_aead_encrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_aead_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_sign(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_verify(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_get_generator_capacity(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_read(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_import_key(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generator_abort(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_key_derivation(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_key_agreement(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generate_random(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t tfm_crypto_generate_key(psa_invec *, size_t, psa_outvec *, size_t);
 
 /******** TFM_SP_PLATFORM ********/
 psa_status_t platform_sp_system_reset(psa_invec *, size_t, psa_outvec *, size_t);
@@ -122,9 +138,12 @@
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_destroy_key)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_information)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_export_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_export_public_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_copy_key)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_set_key_policy)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_policy)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_key_lifetime)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_generate_iv)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_set_iv)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_encrypt_setup)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_cipher_decrypt_setup)
@@ -136,14 +155,27 @@
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_finish)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_verify)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_abort)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_hash_clone)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_sign_setup)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_verify_setup)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_update)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_sign_finish)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_verify_finish)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_mac_abort)
-TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_decrypt)
 TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_encrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_aead_decrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_sign)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_verify)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_encrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_asymmetric_decrypt)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_get_generator_capacity)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_read)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_import_key)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generator_abort)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_key_derivation)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_key_agreement)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generate_random)
+TFM_VENEER_FUNCTION(TFM_SP_CRYPTO, tfm_crypto_generate_key)
 
 /******** TFM_SP_PLATFORM ********/
 TFM_VENEER_FUNCTION(TFM_SP_PLATFORM, platform_sp_system_reset)
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index f5910a8..fafbd30 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -48,6 +48,8 @@
                     "${CRYPTO_DIR}/crypto_mac.c"
                     "${CRYPTO_DIR}/crypto_key.c"
                     "${CRYPTO_DIR}/crypto_aead.c"
+                    "${CRYPTO_DIR}/crypto_asymmetric.c"
+                    "${CRYPTO_DIR}/crypto_generator.c"
                     "${CRYPTO_DIR}/tfm_crypto_secure_api.c"
       )
 
diff --git a/secure_fw/services/crypto/crypto_alloc.c b/secure_fw/services/crypto/crypto_alloc.c
index ef0da17..db9c6af 100644
--- a/secure_fw/services/crypto/crypto_alloc.c
+++ b/secure_fw/services/crypto/crypto_alloc.c
@@ -29,9 +29,10 @@
     uint32_t in_use;                /*!< Indicates if the operation is in use */
     enum tfm_crypto_operation_type type; /*!< Type of the operation */
     union {
-        psa_cipher_operation_t cipher;   /*!< Cipher operation context */
-        psa_mac_operation_t mac;         /*!< MAC operation context */
-        psa_hash_operation_t hash;       /*!< Hash operation context */
+        psa_cipher_operation_t cipher;    /*!< Cipher operation context */
+        psa_mac_operation_t mac;          /*!< MAC operation context */
+        psa_hash_operation_t hash;        /*!< Hash operation context */
+        psa_crypto_generator_t generator; /*!< Generator operation context */
     } operation;
 };
 
@@ -61,6 +62,9 @@
     case TFM_CRYPTO_HASH_OPERATION:
         mem_size = sizeof(psa_hash_operation_t);
         break;
+    case TFM_CRYPTO_GENERATOR_OPERATION:
+        mem_size = sizeof(psa_crypto_generator_t);
+        break;
     case TFM_CRYPTO_OPERATION_NONE:
     default:
         mem_size = 0;
@@ -117,6 +121,7 @@
     if ( (h_val != TFM_CRYPTO_INVALID_HANDLE) &&
          (h_val < TFM_CRYPTO_CONC_OPER_NUM) &&
          (operation[h_val].in_use == TFM_CRYPTO_IN_USE) ) {
+
         memset_operation_context(h_val);
         operation[h_val].in_use = TFM_CRYPTO_NOT_IN_USE;
         operation[h_val].type = TFM_CRYPTO_OPERATION_NONE;
@@ -135,6 +140,7 @@
          (handle < TFM_CRYPTO_CONC_OPER_NUM) &&
          (operation[handle].in_use == TFM_CRYPTO_IN_USE) &&
          (operation[handle].type == type) ) {
+
         *ctx = (void *) &(operation[handle].operation);
         return PSA_SUCCESS;
     }
diff --git a/secure_fw/services/crypto/crypto_asymmetric.c b/secure_fw/services/crypto/crypto_asymmetric.c
new file mode 100644
index 0000000..3db7938
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_asymmetric.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ *        integrity checks but this will have to be revised
+ *        when the full set of error codes mandated by PSA FF
+ *        is available.
+ */
+#include "tfm_mbedcrypto_include.h"
+
+#include "tfm_crypto_api.h"
+#include "tfm_crypto_defs.h"
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+psa_status_t tfm_crypto_asymmetric_sign(psa_invec in_vec[],
+                                        size_t in_len,
+                                        psa_outvec out_vec[],
+                                        size_t out_len)
+{
+    if ((in_len != 2) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t handle = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *hash = in_vec[1].base;
+    size_t hash_length = in_vec[1].len;
+    uint8_t *signature = out_vec[0].base;
+    size_t signature_size = out_vec[0].len;
+
+    return psa_asymmetric_sign(handle, alg, hash, hash_length,
+                               signature, signature_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_asymmetric_verify(psa_invec in_vec[],
+                                          size_t in_len,
+                                          psa_outvec out_vec[],
+                                          size_t out_len)
+{
+    if ((in_len != 3) || (out_len != 0)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t handle = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *hash = in_vec[1].base;
+    size_t hash_length = in_vec[1].len;
+    const uint8_t *signature = in_vec[2].base;
+    size_t signature_length = in_vec[2].len;
+
+    return psa_asymmetric_verify(handle, alg, hash, hash_length,
+                                 signature, signature_length);
+}
+
+psa_status_t tfm_crypto_asymmetric_encrypt(psa_invec in_vec[],
+                                           size_t in_len,
+                                           psa_outvec out_vec[],
+                                           size_t out_len)
+{
+    if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t handle = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *input = in_vec[1].base;
+    size_t input_length = in_vec[1].len;
+    const uint8_t *salt = NULL;
+    size_t salt_length = 0;
+    uint8_t *output = out_vec[0].base;
+    size_t output_size = out_vec[0].len;
+
+    if (in_len == 3) {
+        salt = in_vec[2].base;
+        salt_length = in_vec[2].len;
+    }
+
+    return psa_asymmetric_encrypt(handle, alg, input, input_length,
+                                  salt, salt_length,
+                                  output, output_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_asymmetric_decrypt(psa_invec in_vec[],
+                                           size_t in_len,
+                                           psa_outvec out_vec[],
+                                           size_t out_len)
+{
+    if (!((in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t handle = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *input = in_vec[1].base;
+    size_t input_length = in_vec[1].len;
+    const uint8_t *salt = NULL;
+    size_t salt_length = 0;
+    uint8_t *output = out_vec[0].base;
+    size_t output_size = out_vec[0].len;
+
+    if (in_len == 3) {
+        salt = in_vec[2].base;
+        salt_length = in_vec[2].len;
+    }
+
+    return psa_asymmetric_decrypt(handle, alg, input, input_length,
+                                  salt, salt_length,
+                                  output, output_size, &(out_vec[0].len));
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
index e49b145..aa61025c 100644
--- a/secure_fw/services/crypto/crypto_cipher.c
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -24,6 +24,52 @@
  */
 
 /*!@{*/
+psa_status_t tfm_crypto_cipher_generate_iv(psa_invec in_vec[],
+                                           size_t in_len,
+                                           psa_outvec out_vec[],
+                                           size_t out_len)
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_cipher_operation_t *operation = NULL;
+
+    if ((in_len != 1) || (out_len != 2)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(uint32_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    uint32_t handle = iov->op_handle;
+    uint32_t *handle_out = out_vec[0].base;
+    unsigned char *iv = out_vec[1].base;
+    size_t iv_size = out_vec[1].len;
+
+    /* Init the handle in the operation with the one passed from the iov */
+    *handle_out = iov->op_handle;
+
+    /* Look up the corresponding operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
+                                         handle,
+                                         (void **)&operation);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    *handle_out = handle;
+
+    status = psa_cipher_generate_iv(operation, iv, iv_size, &out_vec[1].len);
+    if (status != PSA_SUCCESS) {
+        /* Release the operation context, ignore if the operation fails. */
+        (void)tfm_crypto_operation_release(handle_out);
+        return status;
+    }
+
+    return status;
+}
+
 psa_status_t tfm_crypto_cipher_set_iv(psa_invec in_vec[],
                                       size_t in_len,
                                       psa_outvec out_vec[],
@@ -67,11 +113,6 @@
     return status;
 }
 
-/**
- * TODO: psa_cipher_generate_iv(...)
- *
- */
-
 psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec in_vec[],
                                              size_t in_len,
                                              psa_outvec out_vec[],
@@ -281,7 +322,8 @@
                                          handle,
                                          (void **)&operation);
     if (status != PSA_SUCCESS) {
-        return status;
+        /* Operation does not exist, so abort has no effect */
+        return PSA_SUCCESS;
     }
 
     status = psa_cipher_abort(operation);
diff --git a/secure_fw/services/crypto/crypto_generator.c b/secure_fw/services/crypto/crypto_generator.c
new file mode 100644
index 0000000..1cf138d
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_generator.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
+ *        integrity checks but this will have to be revised
+ *        when the full set of error codes mandated by PSA FF
+ *        is available.
+ */
+#include "tfm_mbedcrypto_include.h"
+
+#include "tfm_crypto_api.h"
+#include "tfm_crypto_defs.h"
+
+/*!
+ * \defgroup public_psa Public functions, PSA
+ *
+ */
+
+/*!@{*/
+psa_status_t tfm_crypto_get_generator_capacity(psa_invec in_vec[],
+                                               size_t in_len,
+                                               psa_outvec out_vec[],
+                                               size_t out_len)
+{
+    psa_status_t status;
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(size_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    size_t *capacity = out_vec[0].base;
+    psa_crypto_generator_t *generator = NULL;
+
+    /* Look up the corresponding operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+                                         handle,
+                                         (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        *capacity = 0;
+        return status;
+    }
+
+    return psa_get_generator_capacity(generator, capacity);
+}
+
+psa_status_t tfm_crypto_generator_read(psa_invec in_vec[],
+                                       size_t in_len,
+                                       psa_outvec out_vec[],
+                                       size_t out_len)
+{
+    psa_status_t status;
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    uint8_t *output = out_vec[0].base;
+    size_t output_length = out_vec[0].len;
+    psa_crypto_generator_t *generator = NULL;
+
+    /* Look up the corresponding operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+                                         handle,
+                                         (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    return psa_generator_read(generator, output, output_length);
+}
+
+psa_status_t tfm_crypto_generator_import_key(psa_invec in_vec[],
+                                             size_t in_len,
+                                             psa_outvec out_vec[],
+                                             size_t out_len)
+{
+    psa_status_t status;
+    if ((in_len != 2) || (out_len != 0)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (in_vec[1].len != sizeof(size_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    psa_key_handle_t key_handle = iov->key_handle;
+    psa_key_type_t type = iov->type;
+    size_t bits = *(size_t *)(in_vec[1].base);
+    psa_crypto_generator_t *generator = NULL;
+
+    /* Look up the corresponding operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+                                         handle,
+                                         (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    return psa_generator_import_key(key_handle, type, bits, generator);
+}
+
+psa_status_t tfm_crypto_generator_abort(psa_invec in_vec[],
+                                        size_t in_len,
+                                        psa_outvec out_vec[],
+                                        size_t out_len)
+{
+    psa_status_t status;
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(uint32_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    uint32_t *handle_out = out_vec[0].base;
+    psa_crypto_generator_t *generator = NULL;
+
+    /* Init the handle in the operation with the one passed from the iov */
+    *handle_out = iov->op_handle;
+
+    /* Look up the corresponding operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
+                                         handle,
+                                         (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        /* Operation does not exist, so abort has no effect */
+        return PSA_SUCCESS;
+    }
+
+    *handle_out = handle;
+
+    status = psa_generator_abort(generator);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = tfm_crypto_operation_release(handle_out);
+
+    return status;
+}
+
+psa_status_t tfm_crypto_key_derivation(psa_invec in_vec[],
+                                       size_t in_len,
+                                       psa_outvec out_vec[],
+                                       size_t out_len)
+{
+    psa_status_t status;
+    if (!((in_len == 1) || (in_len == 2) || (in_len == 3)) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(uint32_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    uint32_t *handle_out = out_vec[0].base;
+    psa_key_handle_t key_handle = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *salt = NULL;
+    size_t salt_length = 0;
+    const uint8_t *label = NULL;
+    size_t label_length = 0;
+    size_t capacity = iov->capacity;
+    psa_crypto_generator_t *generator = NULL;
+
+    if (in_len > 1) {
+        salt = in_vec[2].base;
+        salt_length = in_vec[2].len;
+    }
+
+    if (in_len > 2) {
+        label = in_vec[3].base;
+        label_length = in_vec[3].len;
+    }
+
+    /* Allocate the generator context in the secure world */
+    status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
+                                        &handle,
+                                        (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    *handle_out = handle;
+
+    return psa_key_derivation(generator, key_handle, alg, salt, salt_length,
+                              label, label_length, capacity);
+}
+
+psa_status_t tfm_crypto_key_agreement(psa_invec in_vec[],
+                                      size_t in_len,
+                                      psa_outvec out_vec[],
+                                      size_t out_len)
+{
+    psa_status_t status;
+    if ((in_len != 2) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(uint32_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    uint32_t handle = iov->op_handle;
+    uint32_t *handle_out = out_vec[0].base;
+    psa_key_handle_t private_key = iov->key_handle;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *peer_key = in_vec[1].base;
+    size_t peer_key_length = in_vec[1].len;
+    psa_crypto_generator_t *generator = NULL;
+
+    /* Allocate the generator context in the secure world */
+    status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
+                                        &handle,
+                                        (void **)&generator);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    *handle_out = handle;
+
+    return psa_key_agreement(generator, private_key,
+                             peer_key, peer_key_length, alg);
+}
+
+psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
+                                        size_t in_len,
+                                        psa_outvec out_vec[],
+                                        size_t out_len)
+{
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    uint8_t *output = out_vec[0].base;
+    size_t output_size = out_vec[0].len;
+
+    return psa_generate_random(output, output_size);
+}
+
+psa_status_t tfm_crypto_generate_key(psa_invec in_vec[],
+                                     size_t in_len,
+                                     psa_outvec out_vec[],
+                                     size_t out_len)
+{
+    if (!((in_len == 2) || (in_len == 3)) || (out_len != 0)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (in_vec[1].len != sizeof(size_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    psa_key_handle_t key_handle = iov->key_handle;
+    psa_key_type_t type = iov->type;
+    size_t bits = *((size_t *)(in_vec[1].base));
+    const void *extra = NULL;
+    size_t extra_size = 0;
+
+    if (in_len == 3) {
+        extra = in_vec[2].base;
+        extra_size = in_vec[2].len;
+    }
+
+    return psa_generate_key(key_handle, type, bits, extra, extra_size);
+}
+/*!@}*/
diff --git a/secure_fw/services/crypto/crypto_hash.c b/secure_fw/services/crypto/crypto_hash.c
index 6468f0f..911227d 100644
--- a/secure_fw/services/crypto/crypto_hash.c
+++ b/secure_fw/services/crypto/crypto_hash.c
@@ -232,7 +232,8 @@
                                          handle,
                                          (void **)&operation);
     if (status != PSA_SUCCESS) {
-        return status;
+        /* Operation does not exist, so abort has no effect */
+        return PSA_SUCCESS;
     }
 
     status = psa_hash_abort(operation);
@@ -247,8 +248,50 @@
     return status;
 }
 
-/**
- * TODO: psa_hash_clone(...)
- *
- */
+psa_status_t tfm_crypto_hash_clone(psa_invec in_vec[],
+                                   size_t in_len,
+                                   psa_outvec out_vec[],
+                                   size_t out_len)
+{
+    psa_status_t status = PSA_SUCCESS;
+    psa_hash_operation_t *source_operation = NULL;
+    psa_hash_operation_t *target_operation = NULL;
+
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (out_vec[0].len != sizeof(uint32_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    uint32_t source_handle = iov->op_handle;
+    uint32_t *target_handle = out_vec[0].base;
+
+    /* Look up the corresponding source operation context */
+    status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
+                                         source_handle,
+                                         (void **)&source_operation);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    /* Allocate the target operation context in the secure world */
+    status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
+                                        target_handle,
+                                        (void **)&target_operation);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = psa_hash_clone(source_operation, target_operation);
+    if (status != PSA_SUCCESS) {
+        /* Release the target operation context, ignore if it fails. */
+        (void)tfm_crypto_operation_release(target_handle);
+        return status;
+    }
+
+    return status;
+}
 /*!@}*/
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
index 0144f02..a241f8a 100644
--- a/secure_fw/services/crypto/crypto_init.c
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -26,33 +26,9 @@
  *        by the TF-M Crypto partition
  */
 static const tfm_crypto_us_t sfid_func_table[TFM_CRYPTO_SFID_MAX] = {
-    tfm_crypto_allocate_key,
-    tfm_crypto_import_key,
-    tfm_crypto_destroy_key,
-    tfm_crypto_get_key_information,
-    tfm_crypto_export_key,
-    tfm_crypto_set_key_policy,
-    tfm_crypto_get_key_policy,
-    tfm_crypto_get_key_lifetime,
-    tfm_crypto_cipher_set_iv,
-    tfm_crypto_cipher_encrypt_setup,
-    tfm_crypto_cipher_decrypt_setup,
-    tfm_crypto_cipher_update,
-    tfm_crypto_cipher_abort,
-    tfm_crypto_cipher_finish,
-    tfm_crypto_hash_setup,
-    tfm_crypto_hash_update,
-    tfm_crypto_hash_finish,
-    tfm_crypto_hash_verify,
-    tfm_crypto_hash_abort,
-    tfm_crypto_mac_sign_setup,
-    tfm_crypto_mac_verify_setup,
-    tfm_crypto_mac_update,
-    tfm_crypto_mac_sign_finish,
-    tfm_crypto_mac_verify_finish,
-    tfm_crypto_mac_abort,
-    tfm_crypto_aead_encrypt,
-    tfm_crypto_aead_decrypt
+#define X(api_name) api_name,
+LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
+#undef X
 };
 
 /**
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
index 073203c..dc2d340 100644
--- a/secure_fw/services/crypto/crypto_key.c
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -128,9 +128,8 @@
     psa_key_handle_t key = iov->key_handle;
     uint8_t *data = out_vec[0].base;
     size_t data_size = out_vec[0].len;
-    size_t *data_length = &(out_vec[0].len);
 
-    return psa_export_key(key, data, data_size, data_length);
+    return psa_export_key(key, data, data_size, &(out_vec[0].len));
 }
 
 psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
@@ -138,13 +137,45 @@
                                           psa_outvec out_vec[],
                                           size_t out_len)
 {
-    (void)in_vec;
-    (void)in_len;
-    (void)out_vec;
-    (void)out_len;
+    if ((in_len != 1) || (out_len != 1)) {
+        return PSA_CONNECTION_REFUSED;
+    }
 
-    /* FIXME: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t key = iov->key_handle;
+    uint8_t *data = out_vec[0].base;
+    size_t data_size = out_vec[0].len;
+
+    return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
+}
+
+psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
+                                 size_t in_len,
+                                 psa_outvec out_vec[],
+                                 size_t out_len)
+{
+    (void)out_vec;
+
+    if ((in_len != 3) || (out_len != 0)) {
+        return PSA_CONNECTION_REFUSED;
+    }
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
+        (in_vec[1].len != sizeof(psa_key_handle_t)) ||
+        (in_vec[2].len != sizeof(psa_key_policy_t))) {
+        return PSA_CONNECTION_REFUSED;
+    }
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+
+    psa_key_handle_t source_handle = iov->key_handle;
+    psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
+    const psa_key_policy_t *policy = in_vec[2].base;
+
+    return psa_copy_key(source_handle, target_handle, policy);
 }
 
 psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
diff --git a/secure_fw/services/crypto/crypto_mac.c b/secure_fw/services/crypto/crypto_mac.c
index c9218fe..625aacd 100644
--- a/secure_fw/services/crypto/crypto_mac.c
+++ b/secure_fw/services/crypto/crypto_mac.c
@@ -278,7 +278,8 @@
                                          handle,
                                          (void **)&operation);
     if (status != PSA_SUCCESS) {
-        return status;
+        /* Operation does not exist, so abort has no effect */
+        return PSA_SUCCESS;
     }
 
     status = psa_mac_abort(operation);
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
index 688a919..67b679f 100644
--- a/secure_fw/services/crypto/manifest.yaml
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -56,6 +56,22 @@
       "minor_policy": "strict"
     },
     {
+      "sfid": "TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID",
+      "signal": "TFM_CRYPTO_EXPORT_PUBLIC_KEY",
+      "tfm_symbol": "tfm_crypto_export_public_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_COPY_KEY_SFID",
+      "signal": "TFM_CRYPTO_COPY_KEY",
+      "tfm_symbol": "tfm_crypto_copy_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
       "sfid": "TFM_CRYPTO_SET_KEY_POLICY_SFID",
       "signal": "TFM_CRYPTO_SET_KEY_POLICY",
       "tfm_symbol": "tfm_crypto_set_key_policy",
@@ -80,6 +96,14 @@
       "minor_policy": "strict"
     },
     {
+      "sfid": "TFM_CRYPTO_CIPHER_GENERATE_IV_SFID",
+      "signal": "TFM_CRYPTO_CIPHER_GENERATE_IV",
+      "tfm_symbol": "tfm_crypto_cipher_generate_iv",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
       "sfid": "TFM_CRYPTO_CIPHER_SET_IV_SFID",
       "signal": "TFM_CRYPTO_CIPHER_SET_IV",
       "tfm_symbol": "tfm_crypto_cipher_set_iv",
@@ -168,6 +192,14 @@
       "minor_policy": "strict"
     },
     {
+      "sfid": "TFM_CRYPTO_HASH_CLONE_SFID",
+      "signal": "TFM_CRYPTO_HASH_CLONE",
+      "tfm_symbol": "tfm_crypto_hash_clone",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
       "sfid": "TFM_CRYPTO_MAC_SIGN_SETUP_SFID",
       "signal": "TFM_CRYPTO_MAC_SIGN_SETUP",
       "tfm_symbol": "tfm_crypto_mac_sign_setup",
@@ -216,6 +248,14 @@
       "minor_policy": "strict"
     },
     {
+      "sfid": "TFM_CRYPTO_AEAD_ENCRYPT_SFID",
+      "signal": "TFM_CRYPTO_AEAD_ENCRYPT",
+      "tfm_symbol": "tfm_crypto_aead_encrypt",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
       "sfid": "TFM_CRYPTO_AEAD_DECRYPT_SFID",
       "signal": "TFM_CRYPTO_AEAD_DECRYPT",
       "tfm_symbol": "tfm_crypto_aead_decrypt",
@@ -224,9 +264,97 @@
       "minor_policy": "strict"
     },
     {
-      "sfid": "TFM_CRYPTO_AEAD_ENCRYPT_SFID",
-      "signal": "TFM_CRYPTO_AEAD_ENCRYPT",
-      "tfm_symbol": "tfm_crypto_aead_encrypt",
+      "sfid": "TFM_CRYPTO_ASYMMETRIC_SIGN_SFID",
+      "signal": "TFM_CRYPTO_ASYMMETRIC_SIGN",
+      "tfm_symbol": "tfm_crypto_asymmetric_sign",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID",
+      "signal": "TFM_CRYPTO_ASYMMETRIC_VERIFY",
+      "tfm_symbol": "tfm_crypto_asymmetric_verify",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID",
+      "signal": "TFM_CRYPTO_ASYMMETRIC_ENCRYPT",
+      "tfm_symbol": "tfm_crypto_asymmetric_encrypt",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID",
+      "signal": "TFM_CRYPTO_ASYMMETRIC_DECRYPT",
+      "tfm_symbol": "tfm_crypto_asymmetric_decrypt",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID",
+      "signal": "TFM_CRYPTO_GET_GENERATOR_CAPACITY",
+      "tfm_symbol": "tfm_crypto_get_generator_capacity",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GENERATOR_READ_SFID",
+      "signal": "TFM_CRYPTO_GENERATOR_READ",
+      "tfm_symbol": "tfm_crypto_generator_read",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID",
+      "signal": "TFM_CRYPTO_GENERATOR_IMPORT_KEY",
+      "tfm_symbol": "tfm_crypto_generator_import_key",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GENERATOR_ABORT_SFID",
+      "signal": "TFM_CRYPTO_GENERATOR_ABORT",
+      "tfm_symbol": "tfm_crypto_generator_abort",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_KEY_DERIVATION_SFID",
+      "signal": "TFM_CRYPTO_KEY_DERIVATION",
+      "tfm_symbol": "tfm_crypto_key_derivation",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_KEY_AGREEMENT_SFID",
+      "signal": "TFM_CRYPTO_KEY_AGREEMENT",
+      "tfm_symbol": "tfm_crypto_key_agreement",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GENERATE_RANDOM_SFID",
+      "signal": "TFM_CRYPTO_GENERATE_RANDOM",
+      "tfm_symbol": "tfm_crypto_generate_random",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    },
+    {
+      "sfid": "TFM_CRYPTO_GENERATE_KEY_SFID",
+      "signal": "TFM_CRYPTO_GENERATE_KEY",
+      "tfm_symbol": "tfm_crypto_generate_key",
       "non_secure_clients": true,
       "minor_version": 1,
       "minor_policy": "strict"
@@ -251,6 +379,8 @@
     "crypto_engine.c",
     "crypto_mac.c",
     "crypto_aead.c",
+    "crypto_asymmetric.c",
+    "crypto_generator.c"
   ],
   "tfm_linker_pattern": {
     "library_list": [
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
index 723e84a..e1d0f1d 100644
--- a/secure_fw/services/crypto/tfm_crypto_api.h
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -40,6 +40,7 @@
     TFM_CRYPTO_CIPHER_OPERATION = 1,
     TFM_CRYPTO_MAC_OPERATION = 2,
     TFM_CRYPTO_HASH_OPERATION = 3,
+    TFM_CRYPTO_GENERATOR_OPERATION = 4,
 
     /* Used to force the enum size */
     TFM_CRYPTO_OPERATION_TYPE_MAX = INT_MAX
@@ -94,36 +95,51 @@
                                          void **ctx);
 
 #define LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API \
-    X(tfm_crypto_allocate_key);               \
-    X(tfm_crypto_import_key);                 \
-    X(tfm_crypto_destroy_key);                \
-    X(tfm_crypto_get_key_information);        \
-    X(tfm_crypto_export_key);                 \
-    X(tfm_crypto_export_public_key);          \
-    X(tfm_crypto_set_key_policy);             \
-    X(tfm_crypto_get_key_policy);             \
-    X(tfm_crypto_get_key_lifetime);           \
-    X(tfm_crypto_cipher_set_iv);              \
-    X(tfm_crypto_cipher_encrypt_setup);       \
-    X(tfm_crypto_cipher_decrypt_setup);       \
-    X(tfm_crypto_cipher_update);              \
-    X(tfm_crypto_cipher_finish);              \
-    X(tfm_crypto_cipher_abort);               \
-    X(tfm_crypto_hash_setup);                 \
-    X(tfm_crypto_hash_update);                \
-    X(tfm_crypto_hash_finish);                \
-    X(tfm_crypto_hash_verify);                \
-    X(tfm_crypto_hash_abort);                 \
-    X(tfm_crypto_mac_sign_setup);             \
-    X(tfm_crypto_mac_verify_setup);           \
-    X(tfm_crypto_mac_update);                 \
-    X(tfm_crypto_mac_sign_finish);            \
-    X(tfm_crypto_mac_verify_finish);          \
-    X(tfm_crypto_mac_abort);                  \
-    X(tfm_crypto_aead_encrypt);               \
-    X(tfm_crypto_aead_decrypt);               \
+    X(tfm_crypto_allocate_key)                \
+    X(tfm_crypto_import_key)                  \
+    X(tfm_crypto_destroy_key)                 \
+    X(tfm_crypto_get_key_information)         \
+    X(tfm_crypto_export_key)                  \
+    X(tfm_crypto_export_public_key)           \
+    X(tfm_crypto_copy_key)                    \
+    X(tfm_crypto_set_key_policy)              \
+    X(tfm_crypto_get_key_policy)              \
+    X(tfm_crypto_get_key_lifetime)            \
+    X(tfm_crypto_cipher_generate_iv)          \
+    X(tfm_crypto_cipher_set_iv)               \
+    X(tfm_crypto_cipher_encrypt_setup)        \
+    X(tfm_crypto_cipher_decrypt_setup)        \
+    X(tfm_crypto_cipher_update)               \
+    X(tfm_crypto_cipher_abort)                \
+    X(tfm_crypto_cipher_finish)               \
+    X(tfm_crypto_hash_setup)                  \
+    X(tfm_crypto_hash_update)                 \
+    X(tfm_crypto_hash_finish)                 \
+    X(tfm_crypto_hash_verify)                 \
+    X(tfm_crypto_hash_abort)                  \
+    X(tfm_crypto_hash_clone)                  \
+    X(tfm_crypto_mac_sign_setup)              \
+    X(tfm_crypto_mac_verify_setup)            \
+    X(tfm_crypto_mac_update)                  \
+    X(tfm_crypto_mac_sign_finish)             \
+    X(tfm_crypto_mac_verify_finish)           \
+    X(tfm_crypto_mac_abort)                   \
+    X(tfm_crypto_aead_encrypt)                \
+    X(tfm_crypto_aead_decrypt)                \
+    X(tfm_crypto_asymmetric_sign)             \
+    X(tfm_crypto_asymmetric_verify)           \
+    X(tfm_crypto_asymmetric_encrypt)          \
+    X(tfm_crypto_asymmetric_decrypt)          \
+    X(tfm_crypto_get_generator_capacity)      \
+    X(tfm_crypto_generator_read)              \
+    X(tfm_crypto_generator_import_key)        \
+    X(tfm_crypto_generator_abort)             \
+    X(tfm_crypto_key_derivation)              \
+    X(tfm_crypto_key_agreement)               \
+    X(tfm_crypto_generate_random)             \
+    X(tfm_crypto_generate_key)                \
 
-#define X(api_name) UNIFORM_SIGNATURE_API(api_name)
+#define X(api_name) UNIFORM_SIGNATURE_API(api_name);
 LIST_TFM_CRYPTO_UNIFORM_SIGNATURE_API
 #undef X
 
diff --git a/secure_fw/services/crypto/tfm_crypto_secure_api.c b/secure_fw/services/crypto/tfm_crypto_secure_api.c
index 857a473..8c3fd47 100644
--- a/secure_fw/services/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/services/crypto/tfm_crypto_secure_api.c
@@ -93,7 +93,7 @@
     (void)id;
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -106,7 +106,7 @@
     (void)id;
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -115,7 +115,7 @@
 {
     (void)handle;
 
-    /* TODO: This API is not supported yet */
+    /* TODO: Persistent key APIs are not supported yet */
     return PSA_ERROR_NOT_SUPPORTED;
 }
 
@@ -245,13 +245,33 @@
                                    size_t data_size,
                                    size_t *data_length)
 {
-    (void)handle;
-    (void)data;
-    (void)data_size;
-    (void)data_length;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SFID,
+        .key_handle = handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = data, .len = data_size}
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_export_public_key,
+                          TFM_CRYPTO_EXPORT_PUBLIC_KEY);
+
+    *data_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 __attribute__((section("SFN")))
@@ -259,12 +279,29 @@
                           psa_key_handle_t target_handle,
                           const psa_key_policy_t *constraint)
 {
-    (void)source_handle;
-    (void)target_handle;
-    (void)constraint;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_COPY_KEY_SFID,
+        .key_handle = source_handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &target_handle, .len = sizeof(psa_key_handle_t)},
+        {.base = constraint, .len = sizeof(psa_key_policy_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_copy_key,
+                                    TFM_CRYPTO_COPY_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 __attribute__((section("SFN")))
@@ -382,13 +419,34 @@
                                     size_t iv_size,
                                     size_t *iv_length)
 {
-    (void) operation;
-    (void) iv;
-    (void) iv_size;
-    (void) iv_length;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SFID,
+        .op_handle = operation->handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = &(operation->handle), .len = sizeof(uint32_t)},
+        {.base = iv, .len = iv_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_cipher_generate_iv,
+                          TFM_CRYPTO_CIPHER_GENERATE_IV);
+
+    *iv_length = out_vec[1].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 __attribute__((section("SFN")))
@@ -759,11 +817,30 @@
 psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
                             psa_hash_operation_t *target_operation)
 {
-    (void)source_operation;
-    (void)target_operation;
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_HASH_CLONE_SFID,
+        .op_handle = source_operation->handle,
+    };
 
-    /* TODO: This API is not supported yet */
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+    psa_outvec out_vec[] = {
+        {.base = target_operation, .len = sizeof(psa_hash_operation_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_hash_clone,
+                          TFM_CRYPTO_HASH_CLONE);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
 }
 
 __attribute__((section("SFN")))
@@ -983,6 +1060,11 @@
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
 
+    /* Sanitize the optional input */
+    if ((additional_data == NULL) && (additional_data_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     size_t idx = 0;
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1049,6 +1131,11 @@
         .aead_in = {.nonce = {0}, .nonce_length = nonce_length}
     };
 
+    /* Sanitize the optional input */
+    if ((additional_data == NULL) && (additional_data_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
     size_t idx = 0;
     psa_invec in_vec[] = {
         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
@@ -1093,3 +1180,503 @@
 
     return status;
 }
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
+                                 psa_algorithm_t alg,
+                                 const uint8_t *hash,
+                                 size_t hash_length,
+                                 uint8_t *signature,
+                                 size_t signature_size,
+                                 size_t *signature_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_SIGN_SFID,
+        .key_handle = handle,
+        .alg = alg,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = hash, .len = hash_length},
+    };
+    psa_outvec out_vec[] = {
+        {.base = signature, .len = signature_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_asymmetric_sign,
+                          TFM_CRYPTO_ASYMMETRIC_SIGN);
+
+    *signature_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_verify(psa_key_handle_t handle,
+                                   psa_algorithm_t alg,
+                                   const uint8_t *hash,
+                                   size_t hash_length,
+                                   const uint8_t *signature,
+                                   size_t signature_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = hash, .len = hash_length},
+        {.base = signature, .len = signature_length}
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_asymmetric_verify,
+                                    TFM_CRYPTO_ASYMMETRIC_VERIFY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    const uint8_t *salt,
+                                    size_t salt_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+        {.base = salt, .len = salt_length}
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (salt == NULL) {
+        in_len--;
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_asymmetric_encrypt,
+                          TFM_CRYPTO_ASYMMETRIC_ENCRYPT);
+#endif
+
+    *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle,
+                                    psa_algorithm_t alg,
+                                    const uint8_t *input,
+                                    size_t input_length,
+                                    const uint8_t *salt,
+                                    size_t salt_length,
+                                    uint8_t *output,
+                                    size_t output_size,
+                                    size_t *output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SFID,
+        .key_handle = handle,
+        .alg = alg
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+        {.base = salt, .len = salt_length}
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (salt == NULL) {
+        in_len--;
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_asymmetric_decrypt,
+                          TFM_CRYPTO_ASYMMETRIC_DECRYPT);
+#endif
+
+    *output_length = out_vec[0].len;
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GET_GENERATOR_CAPACITY_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = capacity, .len = sizeof(size_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_get_generator_capacity,
+                          TFM_CRYPTO_GET_GENERATOR_CAPACITY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+                                uint8_t *output,
+                                size_t output_length)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_READ_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_length},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generator_read,
+                          TFM_CRYPTO_GENERATOR_READ);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_import_key(psa_key_handle_t handle,
+                                      psa_key_type_t type,
+                                      size_t bits,
+                                      psa_crypto_generator_t *generator)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_IMPORT_KEY_SFID,
+        .key_handle = handle,
+        .type = type,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &bits, .len = sizeof(size_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generator_import_key,
+                                    TFM_CRYPTO_GENERATOR_IMPORT_KEY);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATOR_ABORT_SFID,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generator_abort,
+                          TFM_CRYPTO_GENERATOR_ABORT);
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_key_derivation(psa_crypto_generator_t *generator,
+                                psa_key_handle_t handle,
+                                psa_algorithm_t alg,
+                                const uint8_t *salt,
+                                size_t salt_length,
+                                const uint8_t *label,
+                                size_t label_length,
+                                size_t capacity)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SFID,
+        .key_handle = handle,
+        .alg = alg,
+        .op_handle = generator->handle,
+        .capacity = capacity,
+    };
+
+    /* Sanitize the optional input */
+    if ((salt == NULL) && (salt_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if ((label == NULL) && (label_length != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = salt, .len = salt_length},
+        {.base = label, .len = label_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (label == NULL) {
+        in_len--;
+        if (salt == NULL) {
+            in_len--;
+        }
+    }
+    status = psa_call(ipc_handle, in_vec, in_len,
+                      out_vec, ARRAY_SIZE(out_vec));
+#else
+    status = API_DISPATCH(tfm_crypto_key_derivation,
+                          TFM_CRYPTO_KEY_DERIVATION);
+#endif
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_key_agreement(psa_crypto_generator_t *generator,
+                               psa_key_handle_t private_key,
+                               const uint8_t *peer_key,
+                               size_t peer_key_length,
+                               psa_algorithm_t alg)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_KEY_AGREEMENT_SFID,
+        .key_handle = private_key,
+        .alg = alg,
+        .op_handle = generator->handle,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = peer_key, .len = peer_key_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = &(generator->handle), .len = sizeof(uint32_t)},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_key_agreement,
+                          TFM_CRYPTO_KEY_AGREEMENT);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generate_random(uint8_t *output,
+                                 size_t output_size)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATE_RANDOM_SFID,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    if (output_size == 0) {
+        return PSA_SUCCESS;
+    }
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+    status = API_DISPATCH(tfm_crypto_generate_random,
+                          TFM_CRYPTO_GENERATE_RANDOM);
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
+
+__attribute__((section("SFN")))
+psa_status_t psa_generate_key(psa_key_handle_t handle,
+                              psa_key_type_t type,
+                              size_t bits,
+                              const void *extra,
+                              size_t extra_size)
+{
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_GENERATE_KEY_SFID,
+        .key_handle = handle,
+        .type = type,
+    };
+
+    /* Sanitize the optional input */
+    if ((extra == NULL) && (extra_size != 0)) {
+        return PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = &bits, .len = sizeof(size_t)},
+        {.base = extra, .len = extra_size},
+    };
+
+#ifdef TFM_PSA_API
+    PSA_CONNECT(TFM_CRYPTO);
+#endif
+
+#ifdef TFM_PSA_API
+    size_t in_len = ARRAY_SIZE(in_vec);
+    if (extra == NULL) {
+        in_len--;
+    }
+
+    status = psa_call(ipc_handle, in_vec, in_len, NULL, 0);
+#else
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_generate_key,
+                                    TFM_CRYPTO_GENERATE_KEY);
+#endif
+
+#ifdef TFM_PSA_API
+    PSA_CLOSE();
+#endif
+
+    return status;
+}
diff --git a/secure_fw/services/initial_attestation/attestation_crypto_stub.c b/secure_fw/services/initial_attestation/attestation_crypto_stub.c
index 6848ff8..65e84cc 100644
--- a/secure_fw/services/initial_attestation/attestation_crypto_stub.c
+++ b/secure_fw/services/initial_attestation/attestation_crypto_stub.c
@@ -15,13 +15,13 @@
  * simulates a real ECDSA P-256 over SHA256 signature generation. The size of
  * the signature will be equal with a real one.
  */
-psa_status_t psa_asymmetric_sign(psa_key_handle_t handle,
-                                 psa_algorithm_t alg,
-                                 const uint8_t *hash,
-                                 size_t hash_length,
-                                 uint8_t *signature,
-                                 size_t signature_size,
-                                 size_t *signature_length)
+psa_status_t psa_asymmetric_sign_stub(psa_key_handle_t handle,
+                                      psa_algorithm_t alg,
+                                      const uint8_t *hash,
+                                      size_t hash_length,
+                                      uint8_t *signature,
+                                      size_t signature_size,
+                                      size_t *signature_length)
 {
     if (2 * hash_length > signature_size) {
         return PSA_ERROR_BUFFER_TOO_SMALL;