Crypto: Add support for message signing operation

Add support for crypto message signing operation:
-psa_sign_message()
-psa_verify_message()

Signed-off-by: Summer Qin <summer.qin@arm.com>
Change-Id: I685d4c12c8c132ce4ce0c79542ad9143076f3600
diff --git a/secure_fw/partitions/crypto/crypto_asymmetric.c b/secure_fw/partitions/crypto/crypto_asymmetric.c
index 1291562..f0bda4e 100644
--- a/secure_fw/partitions/crypto/crypto_asymmetric.c
+++ b/secure_fw/partitions/crypto/crypto_asymmetric.c
@@ -20,6 +20,83 @@
  */
 
 /*!@{*/
+psa_status_t tfm_crypto_sign_message(psa_invec in_vec[],
+                                     size_t in_len,
+                                     psa_outvec out_vec[],
+                                     size_t out_len)
+{
+#ifdef TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    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 *signature = out_vec[0].base;
+    size_t signature_size = out_vec[0].len;
+    mbedtls_svc_key_id_t encoded_key;
+
+    psa_status_t 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_sign_message(encoded_key, alg, input, input_length,
+                            signature, signature_size, &(out_vec[0].len));
+#endif /* TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED */
+}
+
+psa_status_t tfm_crypto_verify_message(psa_invec in_vec[],
+                                       size_t in_len,
+                                       psa_outvec out_vec[],
+                                       size_t out_len)
+{
+#ifdef TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 3, out_len, 0, 0);
+
+    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;
+    const uint8_t *signature = in_vec[2].base;
+    size_t signature_length = in_vec[2].len;
+    mbedtls_svc_key_id_t encoded_key;
+    psa_status_t 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_verify_message(encoded_key, alg, input, input_length,
+                              signature, signature_length);
+#endif /* TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED */
+}
+
 psa_status_t tfm_crypto_sign_hash(psa_invec in_vec[],
                                   size_t in_len,
                                   psa_outvec out_vec[],
diff --git a/secure_fw/partitions/crypto/crypto_spe.h b/secure_fw/partitions/crypto/crypto_spe.h
index 58f761f..9308bbd 100644
--- a/secure_fw/partitions/crypto/crypto_spe.h
+++ b/secure_fw/partitions/crypto/crypto_spe.h
@@ -126,6 +126,10 @@
         PSA_FUNCTION_NAME(psa_mac_verify)
 #define psa_mac_abort \
         PSA_FUNCTION_NAME(psa_mac_abort)
+#define psa_sign_message \
+        PSA_FUNCTION_NAME(psa_sign_message)
+#define psa_verify_message \
+        PSA_FUNCTION_NAME(psa_verify_message)
 #define psa_sign_hash \
         PSA_FUNCTION_NAME(psa_sign_hash)
 #define psa_verify_hash \
diff --git a/secure_fw/partitions/crypto/tfm_crypto.yaml b/secure_fw/partitions/crypto/tfm_crypto.yaml
index 449668a..740745f 100644
--- a/secure_fw/partitions/crypto/tfm_crypto.yaml
+++ b/secure_fw/partitions/crypto/tfm_crypto.yaml
@@ -344,6 +344,20 @@
       "minor_policy": "STRICT"
     },
     {
+      "name": "TFM_CRYPTO_SIGN_MESSAGE",
+      "signal": "TFM_CRYPTO_SIGN_MESSAGE",
+      "non_secure_clients": true,
+      "version": 1,
+      "version_policy": "STRICT"
+    },
+    {
+      "name": "TFM_CRYPTO_VERIFY_MESSAGE",
+      "signal": "TFM_CRYPTO_VERIFY_MESSAGE",
+      "non_secure_clients": true,
+      "version": 1,
+      "version_policy": "STRICT"
+    },
+    {
       "name": "TFM_CRYPTO_SIGN_HASH",
       "signal": "TFM_CRYPTO_SIGN_HASH",
       "non_secure_clients": true,
diff --git a/secure_fw/partitions/crypto/tfm_crypto_api.h b/secure_fw/partitions/crypto/tfm_crypto_api.h
index 7e85b22..ff1d17b 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_api.h
+++ b/secure_fw/partitions/crypto/tfm_crypto_api.h
@@ -218,6 +218,8 @@
     X(tfm_crypto_aead_finish)                 \
     X(tfm_crypto_aead_verify)                 \
     X(tfm_crypto_aead_abort)                  \
+    X(tfm_crypto_sign_message)                \
+    X(tfm_crypto_verify_message)              \
     X(tfm_crypto_sign_hash)                   \
     X(tfm_crypto_verify_hash)                 \
     X(tfm_crypto_asymmetric_encrypt)          \
diff --git a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
index 3dd2366..1d90e92 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
@@ -1038,6 +1038,73 @@
 #endif /* TFM_CRYPTO_AEAD_MODULE_DISABLED */
 }
 
+psa_status_t psa_sign_message(psa_key_id_t key_id,
+                              psa_algorithm_t alg,
+                              const uint8_t *input,
+                              size_t input_length,
+                              uint8_t *signature,
+                              size_t signature_size,
+                              size_t *signature_length)
+{
+#ifdef TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_SIGN_MESSAGE_SID,
+        .key_id = key_id,
+        .alg = alg,
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+    };
+    psa_outvec out_vec[] = {
+        {.base = signature, .len = signature_size},
+    };
+
+    status = API_DISPATCH(tfm_crypto_sign_message,
+                          TFM_CRYPTO_SIGN_MESSAGE);
+
+    if (status == PSA_SUCCESS) {
+        *signature_length = out_vec[0].len;
+    }
+
+    return status;
+#endif /* TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED */
+}
+
+psa_status_t psa_verify_message(psa_key_id_t key_id,
+                                psa_algorithm_t alg,
+                                const uint8_t *input,
+                                size_t input_length,
+                                const uint8_t *signature,
+                                size_t signature_length)
+{
+#ifdef TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED
+    return PSA_ERROR_NOT_SUPPORTED;
+#else
+    psa_status_t status;
+    struct tfm_crypto_pack_iovec iov = {
+        .sfn_id = TFM_CRYPTO_VERIFY_MESSAGE_SID,
+        .key_id = key_id,
+        .alg = alg
+    };
+
+    psa_invec in_vec[] = {
+        {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
+        {.base = input, .len = input_length},
+        {.base = signature, .len = signature_length}
+    };
+
+    status = API_DISPATCH_NO_OUTVEC(tfm_crypto_verify_message,
+                                    TFM_CRYPTO_VERIFY_MESSAGE);
+
+    return status;
+#endif /* TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED */
+}
+
 psa_status_t psa_sign_hash(psa_key_id_t key_id,
                            psa_algorithm_t alg,
                            const uint8_t *hash,