Separate sign/verify message and hash operations

Previous versions of mbedtls didn't distinguish between
asymmetric sign and verify operations on a hash or message.
They are now treated as separate operations from a usage
control perspective. This change makes the corresponding
hash/message sepration in client and service provider
components.

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I134286d66c3943090055171adfdf16270f395aa3
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
index e807773..4a9ed20 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_sign_hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,8 @@
 extern "C" {
 #endif
 
-static inline psa_status_t crypto_caller_sign_hash(struct service_client *context,
+static inline psa_status_t crypto_caller_asym_sign_commom(struct service_client *context,
+	uint32_t opcode,
 	psa_key_id_t id,
 	psa_algorithm_t alg,
 	const uint8_t *hash, size_t hash_length,
@@ -60,7 +61,7 @@
 
 		context->rpc_status =
 			rpc_caller_invoke(context->caller, call_handle,
-						TS_CRYPTO_OPCODE_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
+						opcode, &opstatus, &resp_buf, &resp_len);
 
 		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) {
 
@@ -98,6 +99,28 @@
 	return psa_status;
 }
 
+static inline psa_status_t crypto_caller_sign_hash(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *hash, size_t hash_length,
+	uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return crypto_caller_asym_sign_commom(context, TS_CRYPTO_OPCODE_SIGN_HASH,
+		id, alg, hash, hash_length,
+		signature, signature_size, signature_length);
+}
+
+static inline psa_status_t crypto_caller_sign_message(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *hash, size_t hash_length,
+	uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return crypto_caller_asym_sign_commom(context, TS_CRYPTO_OPCODE_SIGN_MESSAGE,
+		id, alg, hash, hash_length,
+		signature, signature_size, signature_length);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
index 4715294..daa1133 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_verify_hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,8 @@
 extern "C" {
 #endif
 
-static inline psa_status_t crypto_caller_verify_hash(struct service_client *context,
+static inline psa_status_t crypto_caller_asym_verify_common(struct service_client *context,
+	uint32_t opcode,
 	psa_key_id_t id,
 	psa_algorithm_t alg,
 	const uint8_t *hash, size_t hash_length,
@@ -65,7 +66,7 @@
 
 		context->rpc_status =
 			rpc_caller_invoke(context->caller, call_handle,
-					TS_CRYPTO_OPCODE_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
+					opcode, &opstatus, &resp_buf, &resp_len);
 
 		if (context->rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
 
@@ -75,6 +76,32 @@
 	return psa_status;
 }
 
+static inline psa_status_t crypto_caller_verify_hash(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *hash, size_t hash_length,
+	const uint8_t *signature, size_t signature_length)
+{
+	return crypto_caller_asym_verify_common(context,
+		TS_CRYPTO_OPCODE_VERIFY_HASH,
+		id, alg,
+		hash, hash_length,
+		signature, signature_length);
+}
+
+static inline psa_status_t crypto_caller_verify_message(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *input, size_t input_length,
+	const uint8_t *signature, size_t signature_length)
+{
+	return crypto_caller_asym_verify_common(context,
+		TS_CRYPTO_OPCODE_VERIFY_MESSAGE,
+		id, alg,
+		input, input_length,
+		signature, signature_length);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/caller/stub/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/stub/crypto_caller_sign_hash.h
index d09369a..09049f5 100644
--- a/components/service/crypto/client/caller/stub/crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/stub/crypto_caller_sign_hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,6 +23,15 @@
 	return PSA_ERROR_NOT_SUPPORTED;
 }
 
+static inline psa_status_t crypto_caller_sign_message(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *hash, size_t hash_length,
+	uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return PSA_ERROR_NOT_SUPPORTED;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/caller/stub/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/stub/crypto_caller_verify_hash.h
index 20d11dc..3f3eb87 100644
--- a/components/service/crypto/client/caller/stub/crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/stub/crypto_caller_verify_hash.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,6 +23,15 @@
 	return PSA_ERROR_NOT_SUPPORTED;
 }
 
+static inline psa_status_t crypto_caller_verify_message(struct service_client *context,
+	psa_key_id_t id,
+	psa_algorithm_t alg,
+	const uint8_t *input, size_t input_length,
+	const uint8_t *signature, size_t signature_length)
+{
+	return PSA_ERROR_NOT_SUPPORTED;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/cpp/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h
index 2a5e5b9..ccb0714 100644
--- a/components/service/crypto/client/cpp/crypto_client.h
+++ b/components/service/crypto/client/cpp/crypto_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,7 +57,7 @@
 		psa_key_id_t id,
 		uint8_t *data, size_t data_size, size_t *data_length) = 0;
 
-	/* Sign/verify methods */
+	/* Sign/verify hash methods */
 	virtual psa_status_t sign_hash(
 		psa_key_id_t id,
 		psa_algorithm_t alg,
@@ -70,6 +70,19 @@
 		const uint8_t *hash, size_t hash_length,
 		const uint8_t *signature, size_t signature_length) = 0;
 
+	/* Sign/verify message methods */
+	virtual psa_status_t sign_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		uint8_t *signature, size_t signature_size, size_t *signature_length) = 0;
+
+	virtual psa_status_t verify_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		const uint8_t *signature, size_t signature_length) = 0;
+
 	/* Asymmetric encrypt/decrypt */
 	virtual psa_status_t asymmetric_encrypt(
 		psa_key_id_t id,
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
index 4d9d8f4..4e10f9b 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -107,6 +107,26 @@
 		signature, signature_length);
 }
 
+psa_status_t packedc_crypto_client::sign_message(
+	psa_key_id_t id, psa_algorithm_t alg,
+	const uint8_t *message, size_t message_length,
+	uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return crypto_caller_sign_message(&m_client, id, alg,
+		message, message_length,
+		signature, signature_size, signature_length);
+}
+
+psa_status_t packedc_crypto_client::verify_message(
+	psa_key_id_t id, psa_algorithm_t alg,
+	const uint8_t *message, size_t message_length,
+	const uint8_t *signature, size_t signature_length)
+{
+	return crypto_caller_verify_message(&m_client, id, alg,
+		message, message_length,
+		signature, signature_length);
+}
+
 psa_status_t packedc_crypto_client::asymmetric_encrypt(
 	psa_key_id_t id, psa_algorithm_t alg,
 	const uint8_t *input, size_t input_length,
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
index 377b51d..d74ba60 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@
 		psa_key_id_t id,
 		uint8_t *data, size_t data_size, size_t *data_length);
 
-	/* Sign/verify methods */
+	/* Sign/verify hash methods */
 	psa_status_t sign_hash(
 		psa_key_id_t id,
 		psa_algorithm_t alg,
@@ -67,6 +67,19 @@
 		const uint8_t *hash, size_t hash_length,
 		const uint8_t *signature, size_t signature_length);
 
+	/* Sign/verify message methods */
+	psa_status_t sign_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		uint8_t *signature, size_t signature_size, size_t *signature_length);
+
+	psa_status_t verify_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		const uint8_t *signature, size_t signature_length);
+
 	/* Asymmetric encrypt/decrypt */
 	psa_status_t asymmetric_encrypt(
 		psa_key_id_t id,
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
index 9712ca0..845c9fa 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
@@ -387,6 +387,25 @@
 							const uint8_t *hash, size_t hash_length,
 							uint8_t *signature, size_t signature_size, size_t *signature_length)
 {
+	return asym_sign(ts_crypto_Opcode_SIGN_HASH, id, alg,
+				hash, hash_length,
+				signature, signature_size, signature_length);
+}
+
+psa_status_t protobuf_crypto_client::sign_message(psa_key_id_t id, psa_algorithm_t alg,
+							const uint8_t *message, size_t message_length,
+							uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return asym_sign(ts_crypto_Opcode_SIGN_MESSAGE, id, alg,
+				message, message_length,
+				signature, signature_size, signature_length);
+}
+
+psa_status_t protobuf_crypto_client::asym_sign(uint32_t opcode,
+							psa_key_id_t id, psa_algorithm_t alg,
+							const uint8_t *hash, size_t hash_length,
+							uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
 	size_t req_len;
 	pb_bytes_array_t *hash_byte_array =
 		pb_malloc_byte_array_containing_bytes(hash, hash_length);
@@ -416,7 +435,7 @@
 			pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg);
 
 			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						ts_crypto_Opcode_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
+						opcode, &opstatus, &resp_buf, &resp_len);
 
 			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
 
@@ -462,11 +481,29 @@
 	return psa_status;
 }
 
-
 psa_status_t protobuf_crypto_client::verify_hash(psa_key_id_t id, psa_algorithm_t alg,
 						const uint8_t *hash, size_t hash_length,
 						const uint8_t *signature, size_t signature_length)
 {
+	return asym_verify(ts_crypto_Opcode_VERIFY_HASH, id, alg,
+				hash, hash_length,
+				signature, signature_length);
+}
+
+psa_status_t protobuf_crypto_client::verify_message(psa_key_id_t id, psa_algorithm_t alg,
+						const uint8_t *message, size_t message_length,
+						const uint8_t *signature, size_t signature_length)
+{
+	return asym_verify(ts_crypto_Opcode_VERIFY_MESSAGE, id, alg,
+				message, message_length,
+				signature, signature_length);
+}
+
+psa_status_t protobuf_crypto_client::asym_verify(uint32_t opcode,
+						psa_key_id_t id, psa_algorithm_t alg,
+						const uint8_t *hash, size_t hash_length,
+						const uint8_t *signature, size_t signature_length)
+{
 	size_t req_len;
 	pb_bytes_array_t *hash_byte_array =
 		pb_malloc_byte_array_containing_bytes(hash, hash_length);
@@ -497,7 +534,7 @@
 			pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg);
 
 			m_client.rpc_status = rpc_caller_invoke(m_client.caller, call_handle,
-						ts_crypto_Opcode_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
+						opcode, &opstatus, &resp_buf, &resp_len);
 
 			if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
 
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
index 085d9cf..abe4439 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -54,7 +54,7 @@
 		psa_key_id_t id,
 		uint8_t *data, size_t data_size, size_t *data_length);
 
-	/* Sign/verify methods */
+	/* Sign/verify hash methods */
 	psa_status_t sign_hash(
 		psa_key_id_t id,
 		psa_algorithm_t alg,
@@ -67,6 +67,19 @@
 		const uint8_t *hash, size_t hash_length,
 		const uint8_t *signature, size_t signature_length);
 
+	/* Sign/verify message methods */
+	psa_status_t sign_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		uint8_t *signature, size_t signature_size, size_t *signature_length);
+
+	psa_status_t verify_message(
+		psa_key_id_t id,
+		psa_algorithm_t alg,
+		const uint8_t *message, size_t message_length,
+		const uint8_t *signature, size_t signature_length);
+
 	/* Asymmetric encrypt/decrypt */
 	psa_status_t asymmetric_encrypt(
 		psa_key_id_t id,
@@ -221,6 +234,16 @@
 
 private:
 
+	psa_status_t asym_sign(uint32_t opcode,
+		psa_key_id_t id, 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 asym_verify(uint32_t opcode,
+		psa_key_id_t id, psa_algorithm_t alg,
+		const uint8_t *hash, size_t hash_length,
+		const uint8_t *signature, size_t signature_length);
+
 	void translate_key_attributes(
 		ts_crypto_KeyAttributes &proto_attributes,
 		const psa_key_attributes_t &psa_attributes);
diff --git a/components/service/crypto/client/psa/psa_sign_message.c b/components/service/crypto/client/psa/psa_sign_message.c
index dc2f7e8..b644625 100644
--- a/components/service/crypto/client/psa/psa_sign_message.c
+++ b/components/service/crypto/client/psa/psa_sign_message.c
@@ -1,13 +1,15 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <psa/crypto.h>
+#include "psa_crypto_client.h"
+#include "crypto_caller_selector.h"
 
 psa_status_t psa_sign_message(
-	psa_key_id_t key,
+	psa_key_id_t id,
 	psa_algorithm_t alg,
 	const uint8_t *input,
 	size_t input_length,
@@ -15,19 +17,11 @@
 	size_t signature_size,
 	size_t *signature_length)
 {
-	size_t hash_len;
-	uint8_t hash[PSA_HASH_MAX_SIZE];
+	if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+		return psa_crypto_client_instance.init_status;
 
-	psa_status_t psa_status = psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg),
+	return crypto_caller_sign_message(&psa_crypto_client_instance.base,
+		id, alg,
 		input, input_length,
-		hash, sizeof(hash), &hash_len);
-
-	if (psa_status == PSA_SUCCESS) {
-
-		psa_status = psa_sign_hash(key, alg,
-			hash, hash_len,
-			signature, signature_size, signature_length);
-	}
-
-	return psa_status;
+		signature, signature_size, signature_length);
 }
diff --git a/components/service/crypto/client/psa/psa_verify_message.c b/components/service/crypto/client/psa/psa_verify_message.c
index d0fbc7c..57c2c5e 100644
--- a/components/service/crypto/client/psa/psa_verify_message.c
+++ b/components/service/crypto/client/psa/psa_verify_message.c
@@ -1,32 +1,26 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <psa/crypto.h>
+#include "psa_crypto_client.h"
+#include "crypto_caller_selector.h"
 
 psa_status_t psa_verify_message(
-	psa_key_id_t key,
+	psa_key_id_t id,
 	psa_algorithm_t alg,
 	const uint8_t *input,
 	size_t input_length,
 	const uint8_t * signature,
 	size_t signature_length)
 {
-	size_t hash_len;
-	uint8_t hash[PSA_HASH_MAX_SIZE];
+	if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+		return psa_crypto_client_instance.init_status;
 
-	psa_status_t psa_status = psa_hash_compute(PSA_ALG_SIGN_GET_HASH(alg),
+	return crypto_caller_verify_message(&psa_crypto_client_instance.base,
+		id, alg,
 		input, input_length,
-		hash, sizeof(hash), &hash_len);
-
-	if (psa_status == PSA_SUCCESS) {
-
-		psa_status = psa_verify_hash(key, alg,
-			hash, hash_len,
-			signature, signature_length);
-	}
-
-	return psa_status;
+		signature, signature_length);
 }
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index d0fc7ca..67a5b34 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,8 +16,8 @@
 static rpc_status_t export_key_handler(void *context, struct call_req* req);
 static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
 static rpc_status_t import_key_handler(void *context, struct call_req* req);
-static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
-static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
+static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req);
+static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req);
 static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
 static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
 static rpc_status_t generate_random_handler(void *context, struct call_req* req);
@@ -32,14 +32,16 @@
 	{TS_CRYPTO_OPCODE_EXPORT_KEY,           export_key_handler},
 	{TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY,    export_public_key_handler},
 	{TS_CRYPTO_OPCODE_IMPORT_KEY,           import_key_handler},
-	{TS_CRYPTO_OPCODE_SIGN_HASH,            sign_hash_handler},
-	{TS_CRYPTO_OPCODE_VERIFY_HASH,          verify_hash_handler},
+	{TS_CRYPTO_OPCODE_SIGN_HASH,            asymmetric_sign_handler},
+	{TS_CRYPTO_OPCODE_VERIFY_HASH,          asymmetric_verify_handler},
 	{TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT,   asymmetric_decrypt_handler},
 	{TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT,   asymmetric_encrypt_handler},
 	{TS_CRYPTO_OPCODE_GENERATE_RANDOM,      generate_random_handler},
 	{TS_CRYPTO_OPCODE_COPY_KEY,          	copy_key_handler},
 	{TS_CRYPTO_OPCODE_PURGE_KEY,          	purge_key_handler},
 	{TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, 	get_key_attributes_handler},
+	{TS_CRYPTO_OPCODE_SIGN_MESSAGE,         asymmetric_sign_handler},
+	{TS_CRYPTO_OPCODE_VERIFY_MESSAGE,       asymmetric_verify_handler},
 };
 
 struct rpc_interface *crypto_provider_init(struct crypto_provider *context)
@@ -272,7 +274,7 @@
 	return rpc_status;
 }
 
-static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req)
 {
 	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
 	struct call_param_buf *req_buf = call_req_get_req_buf(req);
@@ -284,7 +286,7 @@
 	uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
 
 	if (serializer)
-		rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
+		rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg, hash_buffer, &hash_len);
 
 	if (rpc_status == TS_RPC_CALL_ACCEPTED) {
 
@@ -292,14 +294,16 @@
 		size_t sig_len;
 		uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
 
-		psa_status = psa_sign_hash(id, alg,
-					hash_buffer, hash_len,
-					sig_buffer, sizeof(sig_buffer), &sig_len);
+		psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_SIGN_HASH) ?
+			psa_sign_hash(id, alg, hash_buffer, hash_len,
+				sig_buffer, sizeof(sig_buffer), &sig_len) :
+			psa_sign_message(id, alg, hash_buffer, hash_len,
+				sig_buffer, sizeof(sig_buffer), &sig_len);
 
 		if (psa_status == PSA_SUCCESS) {
 
 			struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
-			rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
+			rpc_status = serializer->serialize_asymmetric_sign_resp(resp_buf, sig_buffer, sig_len);
 		}
 
 		call_req_set_opstatus(req, psa_status);
@@ -308,7 +312,7 @@
 	return rpc_status;
 }
 
-static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
+static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req)
 {
 	rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
 	struct call_param_buf *req_buf = call_req_get_req_buf(req);
@@ -322,7 +326,7 @@
 	uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
 
 	if (serializer)
-		rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
+		rpc_status = serializer->deserialize_asymmetric_verify_req(req_buf, &id, &alg,
 											hash_buffer, &hash_len,
 											sig_buffer, &sig_len);
 
@@ -330,9 +334,13 @@
 
 		psa_status_t psa_status;
 
-		psa_status = psa_verify_hash(id, alg,
-					hash_buffer, hash_len,
-					sig_buffer, sig_len);
+		psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
+			psa_verify_hash(id, alg,
+				hash_buffer, hash_len,
+				sig_buffer, sig_len) :
+			psa_verify_message(id, alg,
+				hash_buffer, hash_len,
+				sig_buffer, sig_len);
 
 		call_req_set_opstatus(req, psa_status);
 	}
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index 68940ca..57364f2 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -79,15 +79,15 @@
                                         const psa_key_attributes_t *attributes);
 
     /* Operation: sign_hash */
-    rpc_status_t (*deserialize_sign_hash_req)(const struct call_param_buf *req_buf,
+    rpc_status_t (*deserialize_asymmetric_sign_req)(const struct call_param_buf *req_buf,
                                         psa_key_id_t *id, psa_algorithm_t *alg,
                                         uint8_t *hash, size_t *hash_len);
 
-    rpc_status_t (*serialize_sign_hash_resp)(struct call_param_buf *resp_buf,
+    rpc_status_t (*serialize_asymmetric_sign_resp)(struct call_param_buf *resp_buf,
                                         const uint8_t *sig, size_t sig_len);
 
     /* Operation: verify_hash */
-    rpc_status_t (*deserialize_verify_hash_req)(const struct call_param_buf *req_buf,
+    rpc_status_t (*deserialize_asymmetric_verify_req)(const struct call_param_buf *req_buf,
                                         psa_key_id_t *id, psa_algorithm_t *alg,
                                         uint8_t *hash, size_t *hash_len,
                                         uint8_t *sig, size_t *sig_len);
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
index c70db86..4a7e59f 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -333,7 +333,7 @@
 }
 
 /* Operation: sign_hash */
-static rpc_status_t deserialize_sign_hash_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_asymmetric_sign_req(const struct call_param_buf *req_buf,
                             psa_key_id_t *id, psa_algorithm_t *alg,
                             uint8_t *hash, size_t *hash_len)
 {
@@ -378,7 +378,7 @@
     return rpc_status;
 }
 
-static rpc_status_t serialize_sign_hash_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_asymmetric_sign_resp(struct call_param_buf *resp_buf,
                             const uint8_t *sig, size_t sig_len)
 {
     rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
@@ -401,7 +401,7 @@
 }
 
 /* Operation: verify_hash */
-static rpc_status_t deserialize_verify_hash_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_asymmetric_verify_req(const struct call_param_buf *req_buf,
                                 psa_key_id_t *id, psa_algorithm_t *alg,
                                 uint8_t *hash, size_t *hash_len,
                                 uint8_t *sig, size_t *sig_len)
@@ -695,9 +695,9 @@
         deserialize_purge_key_req,
         deserialize_get_key_attributes_req,
         serialize_get_key_attributes_resp,
-        deserialize_sign_hash_req,
-        serialize_sign_hash_resp,
-        deserialize_verify_hash_req,
+        deserialize_asymmetric_sign_req,
+        serialize_asymmetric_sign_resp,
+        deserialize_asymmetric_verify_req,
         deserialize_asymmetric_decrypt_req,
         serialize_asymmetric_decrypt_resp,
         deserialize_asymmetric_encrypt_req,
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
index bd6bc15..8a4e2b1 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c
@@ -268,7 +268,7 @@
 }
 
 /* Operation: sign_hash */
-static rpc_status_t deserialize_sign_hash_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_asymmetric_sign_req(const struct call_param_buf *req_buf,
 							psa_key_id_t *id, psa_algorithm_t *alg,
 							uint8_t *hash, size_t *hash_len)
 {
@@ -296,7 +296,7 @@
 	return rpc_status;
 }
 
-static rpc_status_t serialize_sign_hash_resp(struct call_param_buf *resp_buf,
+static rpc_status_t serialize_asymmetric_sign_resp(struct call_param_buf *resp_buf,
 							const uint8_t *sig, size_t sig_len)
 {
 	size_t packed_resp_size;
@@ -324,7 +324,7 @@
 }
 
 /* Operation: verify_hash */
-static rpc_status_t deserialize_verify_hash_req(const struct call_param_buf *req_buf,
+static rpc_status_t deserialize_asymmetric_verify_req(const struct call_param_buf *req_buf,
 								psa_key_id_t *id, psa_algorithm_t *alg,
 								uint8_t *hash, size_t *hash_len,
 								uint8_t *sig, size_t *sig_len)
@@ -565,9 +565,9 @@
 		deserialize_purge_key_req,
 		deserialize_get_key_attributes_req,
 		serialize_get_key_attributes_resp,
-		deserialize_sign_hash_req,
-		serialize_sign_hash_resp,
-		deserialize_verify_hash_req,
+		deserialize_asymmetric_sign_req,
+		serialize_asymmetric_sign_resp,
+		deserialize_asymmetric_verify_req,
 		deserialize_asymmetric_decrypt_req,
 		serialize_asymmetric_decrypt_resp,
 		deserialize_asymmetric_encrypt_req,
diff --git a/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp b/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp
index bd6c66e..da01abf 100644
--- a/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp
+++ b/components/service/crypto/test/protocol/check_crypto_opcode_alignment.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -18,15 +18,16 @@
 
 TEST(CryptoProtocolOpcodeChecks, checkPackedcToProtobuf)
 {
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_KEY, ts_crypto_Opcode_GENERATE_KEY);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_DESTROY_KEY, ts_crypto_Opcode_DESTROY_KEY);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_KEY, ts_crypto_Opcode_EXPORT_KEY);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, ts_crypto_Opcode_EXPORT_PUBLIC_KEY);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_IMPORT_KEY, ts_crypto_Opcode_IMPORT_KEY);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_SIGN_HASH, ts_crypto_Opcode_SIGN_HASH);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_VERIFY_HASH, ts_crypto_Opcode_VERIFY_HASH);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, ts_crypto_Opcode_ASYMMETRIC_DECRYPT);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, ts_crypto_Opcode_ASYMMETRIC_ENCRYPT);
-    CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_RANDOM, ts_crypto_Opcode_GENERATE_RANDOM);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_KEY, ts_crypto_Opcode_GENERATE_KEY);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_DESTROY_KEY, ts_crypto_Opcode_DESTROY_KEY);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_KEY, ts_crypto_Opcode_EXPORT_KEY);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, ts_crypto_Opcode_EXPORT_PUBLIC_KEY);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_IMPORT_KEY, ts_crypto_Opcode_IMPORT_KEY);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_SIGN_HASH, ts_crypto_Opcode_SIGN_HASH);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_VERIFY_HASH, ts_crypto_Opcode_VERIFY_HASH);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, ts_crypto_Opcode_ASYMMETRIC_DECRYPT);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, ts_crypto_Opcode_ASYMMETRIC_ENCRYPT);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_GENERATE_RANDOM, ts_crypto_Opcode_GENERATE_RANDOM);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_SIGN_MESSAGE, ts_crypto_Opcode_SIGN_MESSAGE);
+	CHECK_EQUAL(TS_CRYPTO_OPCODE_VERIFY_MESSAGE, ts_crypto_Opcode_VERIFY_MESSAGE);
 }
-
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.cpp b/components/service/crypto/test/service/crypto_service_scenarios.cpp
index ec2c673..b334555 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.cpp
+++ b/components/service/crypto/test/service/crypto_service_scenarios.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -290,6 +290,56 @@
 	CHECK_EQUAL(PSA_SUCCESS, status);
 }
 
+void crypto_service_scenarios::signAndVerifyMessage()
+{
+	psa_status_t status;
+	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+	psa_key_id_t key_id;
+
+	psa_set_key_id(&attributes, 14);
+	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_MESSAGE | PSA_KEY_USAGE_VERIFY_MESSAGE);
+	psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+	psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+	psa_set_key_bits(&attributes, 256);
+
+	/* Generate a key */
+	status = m_crypto_client->generate_key(&attributes, &key_id);
+	CHECK_EQUAL(PSA_SUCCESS, status);
+
+	psa_reset_key_attributes(&attributes);
+
+	/* Sign a message */
+	uint8_t message[21];
+	uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
+	size_t signature_length;
+
+	memset(message, 0x99, sizeof(message));
+
+	status = m_crypto_client->sign_message(key_id,
+		PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), message, sizeof(message),
+		signature, sizeof(signature), &signature_length);
+
+	CHECK_EQUAL(PSA_SUCCESS, status);
+	CHECK(signature_length > 0);
+
+	/* Verify the signature */
+	status = m_crypto_client->verify_message(key_id,
+		PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), message, sizeof(message),
+		signature, signature_length);
+	CHECK_EQUAL(PSA_SUCCESS, status);
+
+	/* Change the message and expect verify to fail */
+	message[0] = 0x72;
+	status = m_crypto_client->verify_message(key_id,
+		PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), message, sizeof(message),
+		signature, signature_length);
+	CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status);
+
+	/* Remove the key */
+	status = m_crypto_client->destroy_key(key_id);
+	CHECK_EQUAL(PSA_SUCCESS, status);
+}
+
 void crypto_service_scenarios::signAndVerifyEat()
 {
 	/* Sign and verify a hash using EAT key type and algorithm */
@@ -348,7 +398,7 @@
 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 	psa_key_id_t key_id;
 
-	psa_set_key_id(&attributes, 14);
+	psa_set_key_id(&attributes, 15);
 	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
 	psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
 	psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
@@ -394,7 +444,7 @@
 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 	psa_key_id_t key_id;
 
-	psa_set_key_id(&attributes, 15);
+	psa_set_key_id(&attributes, 16);
 	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
 	psa_set_key_algorithm(&attributes,  PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256));
 	psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.h b/components/service/crypto/test/service/crypto_service_scenarios.h
index c65eba2..2367164 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.h
+++ b/components/service/crypto/test/service/crypto_service_scenarios.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,6 +24,7 @@
 	void asymEncryptDecrypt();
 	void asymEncryptDecryptWithSalt();
 	void signAndVerifyHash();
+	void signAndVerifyMessage();
 	void signAndVerifyEat();
 	void exportAndImportKeyPair();
 	void exportPublicKey();
diff --git a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
index 79eddfb..ea23843 100644
--- a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -87,6 +87,11 @@
 	m_scenarios->signAndVerifyHash();
 }
 
+TEST(CryptoServicePackedcTests, signAndVerifyMessage)
+{
+	m_scenarios->signAndVerifyMessage();
+}
+
 TEST(CryptoServicePackedcTests, signAndVerifyEat)
 {
 	m_scenarios->signAndVerifyEat();
diff --git a/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
index 1230752..c172ad4 100644
--- a/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
+++ b/components/service/crypto/test/service/protobuf/crypto_service_protobuf_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -77,6 +77,11 @@
     m_scenarios->signAndVerifyHash();
 }
 
+TEST(CryptoServiceProtobufTests, signAndVerifyMessage)
+{
+    m_scenarios->signAndVerifyMessage();
+}
+
 TEST(CryptoServiceProtobufTests, asymEncryptDecrypt)
 {
     m_scenarios->asymEncryptDecrypt();