Integrate CBOR support into ts-service-test deployment

Integrates CBOR support with CDDL code generation into the
ts-service-test/linux-pc deployment. Includes end-to-end tests that
invoke crypto operations using CBOR encoded messages.

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ic3a56ce2dd9bf1f5c5a8fbbc927a914ab23ec351
diff --git a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.c b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.c
index 7895df4..99448f6 100644
--- a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.c
+++ b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.c
@@ -64,3 +64,13 @@
 
 	return psa_status;
 }
+
+psa_status_t cbor_crypto_caller_sign_message(
+	struct service_client *context,
+	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 PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.h b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.h
index be0d00b..28c2ddd 100644
--- a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.h
+++ b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_sign_hash.h
@@ -22,6 +22,13 @@
 	const uint8_t *hash, size_t hash_length,
 	uint8_t *signature, size_t signature_size, size_t *signature_length);
 
+psa_status_t cbor_crypto_caller_sign_message(
+	struct service_client *context,
+	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);
+
 static inline psa_status_t crypto_caller_sign_hash(struct service_client *context,
 	psa_key_id_t id,
 	psa_algorithm_t alg,
@@ -34,6 +41,18 @@
 		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 *message, size_t message_length,
+	uint8_t *signature, size_t signature_size, size_t *signature_length)
+{
+	return cbor_crypto_caller_sign_message(
+		context, id, alg,
+		message, message_length,
+		signature, signature_size, signature_length);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.c b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.c
index ed238c1..b776a49 100644
--- a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.c
+++ b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.c
@@ -47,3 +47,13 @@
 
 	return psa_status;
 }
+
+psa_status_t cbor_crypto_caller_verify_message(
+	struct service_client *context,
+	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 PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.h b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.h
index 6dc7ea5..3f25b48 100644
--- a/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.h
+++ b/components/service/crypto/client/caller/cbor/cbor_crypto_caller_verify_hash.h
@@ -22,6 +22,13 @@
 	const uint8_t *hash, size_t hash_length,
 	const uint8_t *signature, size_t signature_length);
 
+psa_status_t cbor_crypto_caller_verify_message(
+	struct service_client *context,
+	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);
+
 static inline psa_status_t crypto_caller_verify_hash(
 	struct service_client *context,
 	psa_key_id_t id,
@@ -35,6 +42,19 @@
 		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 *message, size_t message_length,
+	const uint8_t *signature, size_t signature_length)
+{
+	return cbor_crypto_caller_verify_message(
+		context, id, alg,
+		message, message_length,
+		signature, signature_length);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.cpp
index bb43fb1..3dbff83 100644
--- a/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.cpp
@@ -107,6 +107,26 @@
 		signature, signature_length);
 }
 
+psa_status_t cbor_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 cbor_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 cbor_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/cbor/cbor_crypto_client.h b/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.h
index 2f2c3c8..80d4ee2 100644
--- a/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/cbor/cbor_crypto_client.h
@@ -66,6 +66,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/factory/full/crypto_provider_factory.c b/components/service/crypto/factory/full/crypto_provider_factory.c
index ee2b447..d4cb38e 100644
--- a/components/service/crypto/factory/full/crypto_provider_factory.c
+++ b/components/service/crypto/factory/full/crypto_provider_factory.c
@@ -23,7 +23,7 @@
 #include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h>
 
 /**
- * A crypto provider factory that constucts a crypto provider
+ * A crypto provider factory that constructs a crypto provider
  * that is extended to support the full set of crypto operations.
  * This factory is only capable of constructing a single service
  * provider instance.
diff --git a/components/service/crypto/factory/full_cbor/component.cmake b/components/service/crypto/factory/full_cbor/component.cmake
new file mode 100644
index 0000000..658d294
--- /dev/null
+++ b/components/service/crypto/factory/full_cbor/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/crypto_provider_factory.c"
+	)
diff --git a/components/service/crypto/factory/full_cbor/crypto_provider_factory.c b/components/service/crypto/factory/full_cbor/crypto_provider_factory.c
new file mode 100644
index 0000000..70e4275
--- /dev/null
+++ b/components/service/crypto/factory/full_cbor/crypto_provider_factory.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <service/crypto/factory/crypto_provider_factory.h>
+#include <service/crypto/provider/crypto_provider.h>
+#include <service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.h>
+#include <service/crypto/provider/serializer/cbor/cbor_crypto_provider_serializer.h>
+#include <service/crypto/provider/extension/hash/hash_provider.h>
+#include <service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.h>
+#include <service/crypto/provider/extension/cipher/cipher_provider.h>
+#include <service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.h>
+#include <service/crypto/provider/extension/key_derivation/key_derivation_provider.h>
+#include <service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.h>
+#include <service/crypto/provider/extension/mac/mac_provider.h>
+#include <service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.h>
+#include <service/crypto/provider/extension/aead/aead_provider.h>
+#include <service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.h>
+#include <service/discovery/provider/discovery_provider.h>
+#include <service/discovery/provider/serializer/packed-c/packedc_discovery_provider_serializer.h>
+
+/**
+ * A crypto provider factory that constructs a crypto provider
+ * that is extended to support the full set of crypto operations
+ * with support for CBOR encoding.
+ */
+
+static struct full_crypto_provider
+{
+	struct crypto_provider crypto_provider;
+	struct hash_provider hash_provider;
+	struct cipher_provider cipher_provider;
+	struct key_derivation_provider key_derivation_provider;
+	struct mac_provider mac_provider;
+	struct aead_provider aead_provider;
+
+} instance;
+
+struct crypto_provider *crypto_provider_factory_create(void)
+{
+	/**
+	 * Initialize the core crypto provider
+	 */
+	crypto_provider_init(&instance.crypto_provider);
+
+	/* Register serializers for the core crypto provider */
+	crypto_provider_register_serializer(&instance.crypto_provider,
+		TS_RPC_ENCODING_PROTOBUF, pb_crypto_provider_serializer_instance());
+	crypto_provider_register_serializer(&instance.crypto_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_crypto_provider_serializer_instance());
+	crypto_provider_register_serializer(&instance.crypto_provider,
+		TS_RPC_ENCODING_CBOR, cbor_crypto_provider_serializer_instance());
+
+	/* Register serializer for the associated discovery provider */
+	discovery_provider_register_serializer(&instance.crypto_provider.discovery_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_discovery_provider_serializer_instance());
+
+	/**
+	 * Extend with hash operations
+	 */
+	hash_provider_init(&instance.hash_provider);
+
+	hash_provider_register_serializer(&instance.hash_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_hash_provider_serializer_instance());
+
+	crypto_provider_extend(&instance.crypto_provider,
+		&instance.hash_provider.base_provider);
+
+	/**
+	 *  Extend with symmetric cipher operations
+	 * */
+	cipher_provider_init(&instance.cipher_provider);
+
+	cipher_provider_register_serializer(&instance.cipher_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_cipher_provider_serializer_instance());
+
+	crypto_provider_extend(&instance.crypto_provider,
+		&instance.cipher_provider.base_provider);
+
+	/**
+	 *  Extend with key derivation operations
+	 */
+	key_derivation_provider_init(&instance.key_derivation_provider);
+
+	key_derivation_provider_register_serializer(&instance.key_derivation_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_key_derivation_provider_serializer_instance());
+
+	crypto_provider_extend(&instance.crypto_provider,
+		&instance.key_derivation_provider.base_provider);
+
+	/**
+	 * Extend with mac operations
+	 */
+	mac_provider_init(&instance.mac_provider);
+
+	mac_provider_register_serializer(&instance.mac_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_mac_provider_serializer_instance());
+
+	crypto_provider_extend(&instance.crypto_provider,
+		&instance.mac_provider.base_provider);
+
+	/**
+	 * Extend with aead operations
+	 */
+	aead_provider_init(&instance.aead_provider);
+
+	aead_provider_register_serializer(&instance.aead_provider,
+		TS_RPC_ENCODING_PACKED_C, packedc_aead_provider_serializer_instance());
+
+	crypto_provider_extend(&instance.crypto_provider,
+		&instance.aead_provider.base_provider);
+
+	return &instance.crypto_provider;
+}
+
+/**
+ * \brief Destroys a created crypto provider
+ *
+ * \param[in] provider    The crypto provider to destroy
+  */
+void crypto_provider_factory_destroy(struct crypto_provider *provider)
+{
+	(void)provider;
+	crypto_provider_deinit(&instance.crypto_provider);
+	hash_provider_deinit(&instance.hash_provider);
+	cipher_provider_deinit(&instance.cipher_provider);
+	key_derivation_provider_deinit(&instance.key_derivation_provider);
+	mac_provider_deinit(&instance.mac_provider);
+}
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index cce2989..5911ef1 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -63,6 +63,7 @@
 		"components/service/crypto/provider"
 		"components/service/crypto/provider/serializer/protobuf"
 		"components/service/crypto/provider/serializer/packed-c"
+		"components/service/crypto/provider/serializer/cbor"
 		"components/service/crypto/provider/extension/hash"
 		"components/service/crypto/provider/extension/hash/serializer/packed-c"
 		"components/service/crypto/provider/extension/cipher"
@@ -73,7 +74,7 @@
 		"components/service/crypto/provider/extension/mac/serializer/packed-c"
 		"components/service/crypto/provider/extension/aead"
 		"components/service/crypto/provider/extension/aead/serializer/packed-c"
-		"components/service/crypto/factory/full"
+		"components/service/crypto/factory/full_cbor"
 		"components/service/crypto/backend/mbedcrypto"
 		"components/service/crypto/backend/mbedcrypto/trng_adapter/linux"
 		"components/service/secure_storage/include"
@@ -91,6 +92,7 @@
 		"protocols/rpc/common/packed-c"
 		"protocols/service/crypto/packed-c"
 		"protocols/service/crypto/protobuf"
+		"protocols/service/crypto/cddl"
 		"protocols/service/secure_storage/packed-c"
 )
 
@@ -123,6 +125,10 @@
 include(${TS_ROOT}/external/t_cose/t_cose.cmake)
 target_link_libraries(ts PRIVATE t_cose)
 
+# zcbor
+include(${TS_ROOT}/external/zcbor/zcbor.cmake)
+zcbor_generate_all(TGT "ts" BASE_DIR "${TS_ROOT}/protocols")
+
 #-------------------------------------------------------------------------------
 #  Test executable (libts-test) for testing libts static library
 #
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index b3739c0..4378a54 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -82,6 +82,10 @@
 		"components/service/test_runner/test/service"
 		"components/service/smm_variable/client/cpp"
 		"components/service/smm_variable/test/service"
+		"components/service/crypto/test/service/cbor"
+		"components/service/crypto/client/cpp/protocol/cbor"
+		"components/service/crypto/client/caller/cbor"
+		"protocols/service/crypto/cddl"
 )
 
 #-------------------------------------------------------------------------------
@@ -90,3 +94,12 @@
 #
 #-------------------------------------------------------------------------------
 include(../ts-service-test.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Components used from external projects
+#
+#-------------------------------------------------------------------------------
+
+# zcbor
+include(${TS_ROOT}/external/zcbor/zcbor.cmake)
+zcbor_generate_all(TGT "ts-service-test" BASE_DIR "${TS_ROOT}/protocols")