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,