Crypto: Add support for single-shot Cipher APIs

This patch introduces support for Cipher single-shot
APIs. This needs to be aligned with a recent enough
version of mbedTLS that has support for these APIs in
the backend.

Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I607996b211586a8dcc4e19de8e3251128103623a
diff --git a/interface/src/tfm_crypto_func_api.c b/interface/src/tfm_crypto_func_api.c
index 9e015fa..f22887b 100644
--- a/interface/src/tfm_crypto_func_api.c
+++ b/interface/src/tfm_crypto_func_api.c
@@ -1296,7 +1296,7 @@
     return status;
 }
 
-psa_status_t psa_cipher_encrypt(psa_key_id_t key,
+psa_status_t psa_cipher_encrypt(psa_key_id_t key_id,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1304,14 +1304,35 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_encrypt,
+                          TFM_CRYPTO_CIPHER_ENCRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
-psa_status_t psa_cipher_decrypt(psa_key_id_t key,
+psa_status_t psa_cipher_decrypt(psa_key_id_t key_id,
                                 psa_algorithm_t alg,
                                 const uint8_t *input,
                                 size_t input_length,
@@ -1319,11 +1340,32 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_decrypt,
+                          TFM_CRYPTO_CIPHER_DECRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
diff --git a/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index 953dd11..7496190 100644
--- a/interface/src/tfm_crypto_ipc_api.c
+++ b/interface/src/tfm_crypto_ipc_api.c
@@ -1329,11 +1329,32 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_encrypt,
+                          TFM_CRYPTO_CIPHER_ENCRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t psa_cipher_decrypt(psa_key_id_t key,
@@ -1344,11 +1365,32 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_decrypt,
+                          TFM_CRYPTO_CIPHER_DECRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
diff --git a/secure_fw/partitions/crypto/crypto_cipher.c b/secure_fw/partitions/crypto/crypto_cipher.c
index 6318d0f..aea6c46 100644
--- a/secure_fw/partitions/crypto/crypto_cipher.c
+++ b/secure_fw/partitions/crypto/crypto_cipher.c
@@ -355,8 +355,42 @@
                                        psa_outvec out_vec[],
                                        size_t out_len)
 {
-    /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
+#else
+    psa_status_t status = PSA_SUCCESS;
+
+    CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 1);
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    psa_key_id_t key_id = iov->key_id;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *input = in_vec[1].base;
+    size_t input_length = in_vec[1].len;
+    uint8_t *output = out_vec[0].base;
+    size_t output_size = out_vec[0].len;
+    mbedtls_svc_key_id_t encoded_key;
+
+    /* Initialise plaintext_length to zero. */
+    out_vec[0].len = 0;
+
+    status = tfm_crypto_check_handle_owner(key_id);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    return psa_cipher_encrypt(encoded_key, alg, input, input_length,
+                              output, output_size, &out_vec[0].len);
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t tfm_crypto_cipher_decrypt(psa_invec in_vec[],
@@ -364,7 +398,41 @@
                                        psa_outvec out_vec[],
                                        size_t out_len)
 {
-    /* FixMe: To be implemented */
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
     return PSA_ERROR_NOT_SUPPORTED;
+#else
+    psa_status_t status = PSA_SUCCESS;
+
+    CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 1);
+
+    if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
+        return PSA_ERROR_PROGRAMMER_ERROR;
+    }
+
+    const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
+    psa_key_id_t key_id = iov->key_id;
+    psa_algorithm_t alg = iov->alg;
+    const uint8_t *input = in_vec[1].base;
+    size_t input_length = in_vec[1].len;
+    uint8_t *output = out_vec[0].base;
+    size_t output_size = out_vec[0].len;
+    mbedtls_svc_key_id_t encoded_key;
+
+    /* Initialise plaintext_length to zero. */
+    out_vec[0].len = 0;
+
+    status = tfm_crypto_check_handle_owner(key_id);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
+    if (status != PSA_SUCCESS) {
+        return status;
+    }
+
+    return psa_cipher_decrypt(encoded_key, alg, input, input_length,
+                              output, output_size, &out_vec[0].len);
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 /*!@}*/
diff --git a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
index 7f57fea..118e289 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
@@ -1547,11 +1547,32 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_encrypt,
+                          TFM_CRYPTO_CIPHER_ENCRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t psa_cipher_decrypt(psa_key_id_t key_id,
@@ -1562,11 +1583,32 @@
                                 size_t output_size,
                                 size_t *output_length)
 {
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
     psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
+        .alg = alg,
+        .key_id = key_id
+    };
 
-    status = PSA_ERROR_NOT_SUPPORTED;
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+
+    psa_outvec out_vec[] = {
+        {.base = output, .len = output_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_cipher_decrypt,
+                          TFM_CRYPTO_CIPHER_DECRYPT);
+
+    *output_length = out_vec[0].len;
 
     return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
 }
 
 psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,