Add namespaced key ids to crypto provider

To allow for partitioning of keys stored by an instance of the
crypto provider, a new namespaced_key_id type has been introduced.
Different crypto backends may have their own way or dealing with
key store partitioning or will not support it at all. For example,
mbedtls uses its own key_id type at the psa crypto API that gets
specialized for different build configurations. A crypto client
backend that just exposes the standard psa crypto API doesn't
support any form of partitioning. Functionality is unchanged
by this commit but it prepares for enabling the mbedtls key
owner facility.

Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Ia6f25caf231662bf8609b38820ea5afdb9d984c9
diff --git a/components/service/crypto/backend/crypto_backend.h b/components/service/crypto/backend/crypto_backend.h
new file mode 100644
index 0000000..ceb223a
--- /dev/null
+++ b/components/service/crypto/backend/crypto_backend.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CRYPTO_BACKEND_H
+#define CRYPTO_BACKEND_H
+
+/**
+ * The crypto backend implements the backend interface used by a crypto
+ * provider.  By default, the backend interface is the standard psa
+ * crypto api with additional functions to provide a common interface
+ * for partitioning the keystore into separate namespaces.  Alternative
+ * backends can provide their own version of the interface with overridden
+ * types and keystore namespacing functions.
+ */
+#ifdef ALTERNATIVE_CRYPTO_BACKEND
+#include ALTERNATIVE_CRYPTO_BACKEND
+#else
+#include "default_psa_crypto_backend.h"
+#endif
+
+#endif /* CRYPTO_BACKEND_H */
diff --git a/components/service/crypto/backend/default_psa_crypto_backend.h b/components/service/crypto/backend/default_psa_crypto_backend.h
new file mode 100644
index 0000000..4637010
--- /dev/null
+++ b/components/service/crypto/backend/default_psa_crypto_backend.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEFAULT_PSA_CRYPTO_BACKEND_H
+#define DEFAULT_PSA_CRYPTO_BACKEND_H
+
+#include <stdint.h>
+
+/**
+ * Provides the common crypto backend interface, based on the psa crypto
+ * API. To accommodate backend specific overrides to API types, a
+ * backend may provide its own API definitions.
+ */
+#include <psa/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Crypto frontends that support some kind of key id namespacing, should
+ * use this type for key ids. Namespacing allows for partitioning of
+ * the key id namespace. The nature of the partitioning is up to a
+ * crypto frontend. Note that a backend may override this typedef to
+ * suite the backend's handling of namespaces.
+ */
+typedef psa_key_id_t namespaced_key_id_t;
+#define NAMESPACED_KEY_ID_INIT PSA_KEY_ID_NULL
+
+/**
+ * An overridable type for a key id namespace.
+ */
+typedef int32_t key_id_namespace_t;
+#define KEY_ID_NAMESPACE_INIT 0
+
+/**
+ * \brief Initialize a namespaced key id
+ *
+ * This default implementation just discards the namespace.
+ *
+ * \param namespaced_key_id	The object to initialize
+ * \param key_namespace		The namespace
+ * \param key_id		The key id
+ */
+static inline void namespaced_key_id_init(namespaced_key_id_t *namespaced_key_id,
+					  key_id_namespace_t key_namespace,
+					  psa_key_id_t key_id)
+{
+	(void)key_namespace;
+	*namespaced_key_id = key_id;
+}
+
+/**
+ * \brief Get the key id from a namespaced_key_id_t
+ *
+ * \param namespaced_key_id	Namespaced key id
+ * \return Key id without namespace
+ */
+static inline psa_key_id_t namespaced_key_id_get_key_id(namespaced_key_id_t namespaced_key_id)
+{
+	return namespaced_key_id;
+}
+
+/**
+ * \brief Set the key id namespace associated with a key attributes object
+ *
+ * The default implementation discards the namespace
+ *
+ * \param attributes		Key attributes object
+ * \param key_namespace		Key id namespace
+ */
+static inline void namespaced_key_id_set_namespace(psa_key_attributes_t *attributes,
+						   key_id_namespace_t key_namespace)
+{
+	(void)attributes;
+	(void)key_namespace;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* DEFAULT_PSA_CRYPTO_BACKEND_H */
diff --git a/components/service/crypto/provider/component.cmake b/components/service/crypto/provider/component.cmake
index 68f32de..4e4b0de 100644
--- a/components/service/crypto/provider/component.cmake
+++ b/components/service/crypto/provider/component.cmake
@@ -11,4 +11,5 @@
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/crypto_provider.c"
 	"${CMAKE_CURRENT_LIST_DIR}/crypto_context_pool.c"
+	"${CMAKE_CURRENT_LIST_DIR}/crypto_partition.c"
 	)
diff --git a/components/service/crypto/provider/crypto_context_pool.h b/components/service/crypto/provider/crypto_context_pool.h
index 1710050..1f7b58e 100644
--- a/components/service/crypto/provider/crypto_context_pool.h
+++ b/components/service/crypto/provider/crypto_context_pool.h
@@ -8,7 +8,7 @@
 #define CRYPTO_CONTEXT_POOL_H
 
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 
 /**
  * Some crypto transactions require state to be held between separate
diff --git a/components/service/crypto/provider/crypto_partition.c b/components/service/crypto/provider/crypto_partition.c
new file mode 100644
index 0000000..23f305f
--- /dev/null
+++ b/components/service/crypto/provider/crypto_partition.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "crypto_partition.h"
+
+key_id_namespace_t crypto_partition_get_namespace(uint32_t client_id)
+{
+	/*
+	 * Current just use the client_id as the namespace so keys are strictly
+	 * partitioned by client id.
+	 */
+	return (key_id_namespace_t)client_id;
+}
+
+namespaced_key_id_t crypto_partition_get_namespaced_key_id(uint32_t client_id, psa_key_id_t key_id)
+{
+	namespaced_key_id_t ns_id = NAMESPACED_KEY_ID_INIT;
+
+	namespaced_key_id_init(&ns_id, crypto_partition_get_namespace(client_id), key_id);
+
+	return ns_id;
+}
+
+void crypto_partition_bind_to_owner(psa_key_attributes_t *attributes, uint32_t client_id)
+{
+	key_id_namespace_t ns = crypto_partition_get_namespace(client_id);
+
+	namespaced_key_id_set_namespace(attributes, ns);
+}
diff --git a/components/service/crypto/provider/crypto_partition.h b/components/service/crypto/provider/crypto_partition.h
new file mode 100644
index 0000000..5e7e0ce
--- /dev/null
+++ b/components/service/crypto/provider/crypto_partition.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CRYPTO_PARTITION_H
+#define CRYPTO_PARTITION_H
+
+#include "service/crypto/backend/crypto_backend.h"
+#include <stdint.h>
+
+/**
+ * Concerned with partitioning of the crypto service backed key store to protect
+ * keys and key store resource. Key partitioning for stored keys is handled by
+ * associating keys with a namespace that reflects the owner.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Returns the key id namespace associated with a client id
+ *
+ * \param client_id	The uniform identifier for the client
+ * \return The associated key id namespace
+ */
+key_id_namespace_t crypto_partition_get_namespace(uint32_t client_id);
+
+/**
+ * \brief Returns a namespaced key id
+ *
+ * \param client_id	The uniform identifier for the client
+ * \param key_id	The key id
+ * \return The namespaced key id
+ */
+namespaced_key_id_t crypto_partition_get_namespaced_key_id(uint32_t client_id, psa_key_id_t key_id);
+
+/**
+ * \brief Associate a key with an owner
+ *
+ * \param attributes	Key attributes object
+ * \param client_id	The uniform identifier for the client
+ */
+void crypto_partition_bind_to_owner(psa_key_attributes_t *attributes, uint32_t client_id);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CRYPTO_PARTITION_H */
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index 8992b93..bc0e90e 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -8,11 +8,12 @@
 #include <mbedtls/x509_crt.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <protocols/service/crypto/packed-c/opcodes.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <service/crypto/provider/crypto_provider.h>
 #include <stdint.h>
 #include <stdlib.h>
 
+#include "crypto_partition.h"
 #include "crypto_uuid.h"
 
 /* Service request handlers */
@@ -109,13 +110,16 @@
 
 	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
-		psa_key_id_t id;
+		namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
 
-		psa_status = psa_generate_key(&attributes, &id);
+		crypto_partition_bind_to_owner(&attributes, req->source_id);
+
+		psa_status = psa_generate_key(&attributes, &ns_key_id);
 
 		if (psa_status == PSA_SUCCESS) {
+			psa_key_id_t key_id = namespaced_key_id_get_key_id(ns_key_id);
 			struct rpc_buffer *resp_buf = &req->response;
-			rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
+			rpc_status = serializer->serialize_generate_key_resp(resp_buf, key_id);
 		}
 
 		req->service_status = psa_status;
@@ -132,15 +136,17 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
+		rpc_status = serializer->deserialize_destroy_key_req(req_buf, &key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
-		psa_status = psa_destroy_key(id);
+		psa_status = psa_destroy_key(ns_key_id);
 		req->service_status = psa_status;
 	}
 
@@ -153,19 +159,21 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
+		rpc_status = serializer->deserialize_export_key_req(req_buf, &key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 		size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
 		uint8_t *key_buffer = malloc(max_export_size);
 
 		if (key_buffer) {
 			size_t export_size;
 			psa_status_t psa_status =
-				psa_export_key(id, key_buffer, max_export_size, &export_size);
+				psa_export_key(ns_key_id, key_buffer, max_export_size, &export_size);
 
 			if (psa_status == PSA_SUCCESS) {
 				struct rpc_buffer *resp_buf = &req->response;
@@ -191,19 +199,21 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
+		rpc_status = serializer->deserialize_export_public_key_req(req_buf, &key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 		size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
 		uint8_t *key_buffer = malloc(max_export_size);
 
 		if (key_buffer) {
 			size_t export_size;
 			psa_status_t psa_status = psa_export_public_key(
-				id, key_buffer, max_export_size, &export_size);
+				ns_key_id, key_buffer, max_export_size, &export_size);
 
 			if (psa_status == PSA_SUCCESS) {
 				struct rpc_buffer *resp_buf = &req->response;
@@ -240,16 +250,20 @@
 
 			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
-				psa_key_id_t id;
+				namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
+
+				crypto_partition_bind_to_owner(&attributes, req->source_id);
 
 				psa_status =
-					psa_import_key(&attributes, key_buffer, key_data_len, &id);
+					psa_import_key(&attributes, key_buffer, key_data_len, &ns_key_id);
 
 				if (psa_status == PSA_SUCCESS) {
+					psa_key_id_t key_id =
+						namespaced_key_id_get_key_id(ns_key_id);
 					struct rpc_buffer *resp_buf = &req->response;
 
 					rpc_status =
-						serializer->serialize_import_key_resp(resp_buf, id);
+						serializer->serialize_import_key_resp(resp_buf, key_id);
 				}
 
 				req->service_status = psa_status;
@@ -271,25 +285,25 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 	psa_algorithm_t alg;
 	size_t hash_len = PSA_HASH_MAX_SIZE;
 	uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
 
 	if (serializer)
-		rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg,
+		rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &key_id, &alg,
 									 hash_buffer, &hash_len);
 
 	if (rpc_status == RPC_SUCCESS) {
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 		psa_status_t psa_status;
 		size_t sig_len;
 		uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
 
 		psa_status = (req->opcode == 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);
+			psa_sign_hash(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sizeof(sig_buffer), &sig_len) :
+			psa_sign_message(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sizeof(sig_buffer), &sig_len);
 
 		if (psa_status == PSA_SUCCESS) {
 			struct rpc_buffer *resp_buf = &req->response;
@@ -310,7 +324,7 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 	psa_algorithm_t alg;
 	size_t hash_len = PSA_HASH_MAX_SIZE;
 	uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
@@ -319,16 +333,16 @@
 
 	if (serializer)
 		rpc_status = serializer->deserialize_asymmetric_verify_req(
-			req_buf, &id, &alg, hash_buffer, &hash_len, sig_buffer, &sig_len);
+			req_buf, &key_id, &alg, hash_buffer, &hash_len, sig_buffer, &sig_len);
 
 	if (rpc_status == RPC_SUCCESS) {
 		psa_status_t psa_status;
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
 		psa_status = (req->opcode == 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);
+			psa_verify_hash(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sig_len) :
+			psa_verify_message(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sig_len);
 
 		req->service_status = psa_status;
 	}
@@ -345,7 +359,7 @@
 	if (serializer) {
 		size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
 
-		psa_key_id_t id;
+		psa_key_id_t key_id = PSA_KEY_ID_NULL;
 		psa_algorithm_t alg;
 		size_t ciphertext_len = max_param_size;
 		uint8_t *ciphertext_buffer = malloc(ciphertext_len);
@@ -354,14 +368,16 @@
 
 		if (ciphertext_buffer && salt_buffer) {
 			rpc_status = serializer->deserialize_asymmetric_decrypt_req(
-				req_buf, &id, &alg, ciphertext_buffer, &ciphertext_len, salt_buffer,
+				req_buf, &key_id, &alg, ciphertext_buffer, &ciphertext_len, salt_buffer,
 				&salt_len);
 
 			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
 				psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+				namespaced_key_id_t ns_key_id =
+					crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
-				psa_status = psa_get_key_attributes(id, &attributes);
+				psa_status = psa_get_key_attributes(ns_key_id, &attributes);
 
 				if (psa_status == PSA_SUCCESS) {
 					size_t max_decrypt_size =
@@ -377,7 +393,7 @@
 						uint8_t *salt = (salt_len) ? salt_buffer : NULL;
 
 						psa_status = psa_asymmetric_decrypt(
-							id, alg, ciphertext_buffer, ciphertext_len,
+							ns_key_id, alg, ciphertext_buffer, ciphertext_len,
 							salt, salt_len, plaintext_buffer,
 							max_decrypt_size, &plaintext_len);
 
@@ -419,7 +435,7 @@
 	if (serializer) {
 		size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
 
-		psa_key_id_t id;
+		psa_key_id_t key_id = PSA_KEY_ID_NULL;
 		psa_algorithm_t alg;
 		size_t plaintext_len = max_param_size;
 		uint8_t *plaintext_buffer = malloc(plaintext_len);
@@ -428,14 +444,16 @@
 
 		if (plaintext_buffer && salt_buffer) {
 			rpc_status = serializer->deserialize_asymmetric_encrypt_req(
-				req_buf, &id, &alg, plaintext_buffer, &plaintext_len, salt_buffer,
+				req_buf, &key_id, &alg, plaintext_buffer, &plaintext_len, salt_buffer,
 				&salt_len);
 
 			if (rpc_status == RPC_SUCCESS) {
 				psa_status_t psa_status;
 				psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+				namespaced_key_id_t ns_key_id =
+					crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
-				psa_status = psa_get_key_attributes(id, &attributes);
+				psa_status = psa_get_key_attributes(ns_key_id, &attributes);
 
 				if (psa_status == PSA_SUCCESS) {
 					size_t max_encrypt_size =
@@ -451,7 +469,7 @@
 						uint8_t *salt = (salt_len) ? salt_buffer : NULL;
 
 						psa_status = psa_asymmetric_encrypt(
-							id, alg, plaintext_buffer, plaintext_len,
+							ns_key_id, alg, plaintext_buffer, plaintext_len,
 							salt, salt_len, ciphertext_buffer,
 							max_encrypt_size, &ciphertext_len);
 
@@ -528,18 +546,23 @@
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
 	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-	psa_key_id_t source_key_id;
+	psa_key_id_t source_key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
 		rpc_status =
 			serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
-		psa_key_id_t target_key_id;
+		namespaced_key_id_t target_ns_key_id = NAMESPACED_KEY_ID_INIT;
+		namespaced_key_id_t source_ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, source_key_id);
 
-		psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
+		crypto_partition_bind_to_owner(&attributes, req->source_id);
+
+		psa_status_t psa_status = psa_copy_key(source_ns_key_id, &attributes, &target_ns_key_id);
 
 		if (psa_status == PSA_SUCCESS) {
+			psa_key_id_t target_key_id = namespaced_key_id_get_key_id(target_ns_key_id);
 			struct rpc_buffer *resp_buf = &req->response;
 			rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
 		}
@@ -558,13 +581,15 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
+		rpc_status = serializer->deserialize_purge_key_req(req_buf, &key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
-		psa_status_t psa_status = psa_purge_key(id);
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
+		psa_status_t psa_status = psa_purge_key(ns_key_id);
 		req->service_status = psa_status;
 	}
 
@@ -577,15 +602,17 @@
 	struct rpc_buffer *req_buf = &req->request;
 	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
 
-	psa_key_id_t id;
+	psa_key_id_t key_id = PSA_KEY_ID_NULL;
 
 	if (serializer)
-		rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
+		rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &key_id);
 
 	if (rpc_status == RPC_SUCCESS) {
 		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+		namespaced_key_id_t ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
-		psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
+		psa_status_t psa_status = psa_get_key_attributes(ns_key_id, &attributes);
 
 		if (psa_status == PSA_SUCCESS) {
 			struct rpc_buffer *resp_buf = &req->response;
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index 696474e..b73d88d 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -8,7 +8,8 @@
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/provider/extension/aead/aead_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
+#include <service/crypto/provider/crypto_partition.h>
 
 /* Service request handlers */
 static rpc_status_t aead_setup_handler(void *context, struct rpc_request *req);
@@ -94,12 +95,14 @@
 		if (crypto_context) {
 
 			psa_status_t psa_status;
+			namespaced_key_id_t ns_key_id =
+				crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
 			crypto_context->op.aead = psa_aead_operation_init();
 
 			psa_status = (req->opcode == TS_CRYPTO_OPCODE_AEAD_ENCRYPT_SETUP) ?
-				psa_aead_encrypt_setup(&crypto_context->op.aead, key_id, alg) :
-				psa_aead_decrypt_setup(&crypto_context->op.aead, key_id, alg);
+				psa_aead_encrypt_setup(&crypto_context->op.aead, ns_key_id, alg) :
+				psa_aead_decrypt_setup(&crypto_context->op.aead, ns_key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
diff --git a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
index 2bf7a01..be76d2b 100644
--- a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
+++ b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
diff --git a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
index 738d5f2..8f8c3c7 100644
--- a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
+++ b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <protocols/service/crypto/packed-c/aead.h>
 #include "packedc_aead_provider_serializer.h"
 
diff --git a/components/service/crypto/provider/extension/cipher/cipher_provider.c b/components/service/crypto/provider/extension/cipher/cipher_provider.c
index ceecdee..550c140 100644
--- a/components/service/crypto/provider/extension/cipher/cipher_provider.c
+++ b/components/service/crypto/provider/extension/cipher/cipher_provider.c
@@ -8,7 +8,8 @@
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/provider/extension/cipher/cipher_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
+#include <service/crypto/provider/crypto_partition.h>
 
 /* Service request handlers */
 static rpc_status_t cipher_setup_handler(void *context, struct rpc_request *req);
@@ -88,12 +89,14 @@
 		if (crypto_context) {
 
 			psa_status_t psa_status;
+			namespaced_key_id_t ns_key_id =
+				crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
 			crypto_context->op.cipher = psa_cipher_operation_init();
 
 			psa_status = (req->opcode == TS_CRYPTO_OPCODE_CIPHER_ENCRYPT_SETUP) ?
-				psa_cipher_encrypt_setup(&crypto_context->op.cipher, key_id, alg) :
-				psa_cipher_decrypt_setup(&crypto_context->op.cipher, key_id, alg);
+				psa_cipher_encrypt_setup(&crypto_context->op.cipher, ns_key_id, alg) :
+				psa_cipher_decrypt_setup(&crypto_context->op.cipher, ns_key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
diff --git a/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h b/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
index 21169d9..8e8dba8 100644
--- a/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
+++ b/components/service/crypto/provider/extension/cipher/serializer/cipher_provider_serializer.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
diff --git a/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c b/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
index eb9cce3..ea3f944 100644
--- a/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
+++ b/components/service/crypto/provider/extension/cipher/serializer/packed-c/packedc_cipher_provider_serializer.c
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <protocols/service/crypto/packed-c/cipher.h>
 #include "packedc_cipher_provider_serializer.h"
 
diff --git a/components/service/crypto/provider/extension/hash/hash_provider.c b/components/service/crypto/provider/extension/hash/hash_provider.c
index 1c4da5d..16f86de 100644
--- a/components/service/crypto/provider/extension/hash/hash_provider.c
+++ b/components/service/crypto/provider/extension/hash/hash_provider.c
@@ -8,7 +8,7 @@
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/provider/extension/hash/hash_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 
 /* Service request handlers */
 static rpc_status_t hash_setup_handler(void *context, struct rpc_request *req);
diff --git a/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h b/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
index bfb4d8b..683ed68 100644
--- a/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
+++ b/components/service/crypto/provider/extension/hash/serializer/hash_provider_serializer.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
diff --git a/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c b/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
index 6f131c5..06f235f 100644
--- a/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
+++ b/components/service/crypto/provider/extension/hash/serializer/packed-c/packedc_hash_provider_serializer.c
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <protocols/service/crypto/packed-c/hash.h>
 #include "packedc_hash_provider_serializer.h"
 
diff --git a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
index 9503f7c..a3435e7 100644
--- a/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
+++ b/components/service/crypto/provider/extension/key_derivation/key_derivation_provider.c
@@ -8,7 +8,8 @@
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/provider/extension/key_derivation/key_derivation_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
+#include <service/crypto/provider/crypto_partition.h>
 
 /* Service request handlers */
 static rpc_status_t key_derivation_setup_handler(void *context, struct rpc_request *req);
@@ -262,9 +263,12 @@
 					op_handle);
 
 			if (crypto_context) {
+				namespaced_key_id_t ns_key_id =
+					crypto_partition_get_namespaced_key_id(req->source_id,
+									       key_id);
 
 				psa_status = psa_key_derivation_input_key(&crypto_context->op.key_derivation,
-					step, key_id);
+					step, ns_key_id);
 			}
 		}
 
@@ -352,14 +356,16 @@
 
 		if (crypto_context) {
 
-			psa_key_id_t key_id;
+			namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
+
+			crypto_partition_bind_to_owner(&attributes, req->source_id);
 
 			psa_status = psa_key_derivation_output_key(&attributes,
 				&crypto_context->op.key_derivation,
-				&key_id);
+				&ns_key_id);
 
 			if (psa_status == PSA_SUCCESS) {
-
+				psa_key_id_t key_id = namespaced_key_id_get_key_id(ns_key_id);
 				struct rpc_buffer *resp_buf = &req->response;
 				rpc_status = serializer->serialize_key_derivation_output_key_resp(resp_buf,
 					key_id);
@@ -437,9 +443,12 @@
 				op_handle);
 
 		if (crypto_context) {
+			namespaced_key_id_t private_ns_key_id =
+				crypto_partition_get_namespaced_key_id(req->source_id,
+								       private_key_id);
 
 			psa_status = psa_key_derivation_key_agreement(&crypto_context->op.key_derivation,
-				step, private_key_id, peer_key, peer_key_len);
+				step, private_ns_key_id, peer_key, peer_key_len);
 		}
 
 		req->service_status = psa_status;
@@ -468,8 +477,11 @@
 		size_t output_len;
 		uint8_t output[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
 
+		namespaced_key_id_t private_ns_key_id =
+			crypto_partition_get_namespaced_key_id(req->source_id, private_key_id);
+
 		psa_status_t psa_status = psa_raw_key_agreement(
-			alg, private_key_id, peer_key, peer_key_len,
+			alg, private_ns_key_id, peer_key, peer_key_len,
 			output, sizeof(output), &output_len);
 
 		if (psa_status == PSA_SUCCESS) {
diff --git a/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h b/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
index bff1a64..0f60109 100644
--- a/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
+++ b/components/service/crypto/provider/extension/key_derivation/serializer/key_derivation_provider_serializer.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
diff --git a/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c b/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
index 03bb3dc..e0962dd 100644
--- a/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
+++ b/components/service/crypto/provider/extension/key_derivation/serializer/packed-c/packedc_key_derivation_provider_serializer.c
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <protocols/service/crypto/packed-c/key_derivation.h>
 #include <service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h>
 #include "packedc_key_derivation_provider_serializer.h"
diff --git a/components/service/crypto/provider/extension/mac/mac_provider.c b/components/service/crypto/provider/extension/mac/mac_provider.c
index 1e2081e..d9dc7ce 100644
--- a/components/service/crypto/provider/extension/mac/mac_provider.c
+++ b/components/service/crypto/provider/extension/mac/mac_provider.c
@@ -8,7 +8,8 @@
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/provider/extension/mac/mac_provider.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
+#include <service/crypto/provider/crypto_partition.h>
 
 /* Service request handlers */
 static rpc_status_t mac_setup_handler(void *context, struct rpc_request *req);
@@ -84,13 +85,15 @@
 				&op_handle);
 
 		if (crypto_context) {
+			namespaced_key_id_t ns_key_id =
+				crypto_partition_get_namespaced_key_id(req->source_id, key_id);
 
 			crypto_context->op.mac = psa_mac_operation_init();
 
 			psa_status_t psa_status =
 				(req->opcode == TS_CRYPTO_OPCODE_MAC_SIGN_SETUP) ?
-					psa_mac_sign_setup(&crypto_context->op.mac, key_id, alg) :
-					psa_mac_verify_setup(&crypto_context->op.mac, key_id, alg);
+				psa_mac_sign_setup(&crypto_context->op.mac, ns_key_id, alg) :
+				psa_mac_verify_setup(&crypto_context->op.mac, ns_key_id, alg);
 
 			if (psa_status == PSA_SUCCESS) {
 
diff --git a/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
index 0ad0465..a6799e1 100644
--- a/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
+++ b/components/service/crypto/provider/extension/mac/serializer/mac_provider_serializer.h
@@ -9,7 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
 
 /* Provides a common interface for parameter serialization operations
diff --git a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
index a82b98d..935472d 100644
--- a/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
+++ b/components/service/crypto/provider/extension/mac/serializer/packed-c/packedc_mac_provider_serializer.c
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <common/tlv/tlv.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <protocols/service/crypto/packed-c/mac.h>
 #include "packedc_mac_provider_serializer.h"
 
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index 1a0ce3c..bd5336c 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -7,7 +7,7 @@
 #ifndef CRYPTO_PROVIDER_SERIALIZER_H
 #define CRYPTO_PROVIDER_SERIALIZER_H
 
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <stddef.h>
 #include <stdint.h>
 
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 f59173d..050ef2f 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
@@ -22,7 +22,7 @@
 #include <protocols/service/crypto/packed-c/sign_hash.h>
 #include <protocols/service/crypto/packed-c/verify_hash.h>
 #include <protocols/service/crypto/packed-c/verify_pkcs7_signature.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c
index a42ed29..1123c73 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.c
@@ -14,8 +14,11 @@
     psa_set_key_lifetime(psa_attributes, proto_attributes->lifetime);
 
     if (proto_attributes->lifetime == PSA_KEY_LIFETIME_PERSISTENT) {
+        namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
 
-        psa_set_key_id(psa_attributes, proto_attributes->id);
+        /* Note: that namespace is set later */
+        namespaced_key_id_init(&ns_key_id, 0, proto_attributes->id);
+        psa_set_key_id(psa_attributes, ns_key_id);
     }
 
     psa_set_key_usage_flags(psa_attributes, proto_attributes->policy.usage);
@@ -26,10 +29,13 @@
     struct ts_crypto_key_attributes *proto_attributes,
     const psa_key_attributes_t *psa_attributes)
 {
+    namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
+
     proto_attributes->type = psa_get_key_type(psa_attributes);
     proto_attributes->key_bits = psa_get_key_bits(psa_attributes);
     proto_attributes->lifetime = psa_get_key_lifetime(psa_attributes);
-    proto_attributes->id = psa_get_key_id(psa_attributes);
+    ns_key_id = psa_get_key_id(psa_attributes);
+    proto_attributes->id = namespaced_key_id_get_key_id(ns_key_id);
 
     proto_attributes->policy.usage = psa_get_key_usage_flags(psa_attributes);
     proto_attributes->policy.alg = psa_get_key_algorithm(psa_attributes);
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h
index 4567254..2ceffb4 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_key_attributes_translator.h
@@ -8,7 +8,7 @@
 #define PACKEDC_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H
 
 #include <protocols/service/crypto/packed-c/key_attributes.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 
 void packedc_crypto_provider_translate_key_attributes_from_proto(
     psa_key_attributes_t *psa_attributes,
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 34cc326..cc6a9ee 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
@@ -8,7 +8,7 @@
 #include <pb_decode.h>
 #include <pb_encode.h>
 #include <protocols/rpc/common/packed-c/status.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 #include <service/common/serializer/protobuf/pb_helper.h>
 #include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
 #include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c
index 14286a3..df576d0 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c
+++ b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c
@@ -13,8 +13,11 @@
     psa_set_key_lifetime(psa_attributes, proto_attributes->lifetime);
 
     if (proto_attributes->lifetime == PSA_KEY_LIFETIME_PERSISTENT) {
+        namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
 
-        psa_set_key_id(psa_attributes, proto_attributes->id);
+        /* Note: that namespace is set later */
+        namespaced_key_id_init(&ns_key_id, 0, proto_attributes->id);
+        psa_set_key_id(psa_attributes, ns_key_id);
     }
 
     if (proto_attributes->has_policy) {
diff --git a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
index ef77c73..b3721dd 100644
--- a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
+++ b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h
@@ -8,10 +8,10 @@
 #define PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H
 
 #include <service/crypto/protobuf/key_attributes.pb.h>
-#include <psa/crypto.h>
+#include <service/crypto/backend/crypto_backend.h>
 
 void pb_crypto_provider_translate_key_attributes(
     psa_key_attributes_t *psa_attributes,
     const ts_crypto_KeyAttributes *proto_attributes);
 
-#endif /* PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H */
\ No newline at end of file
+#endif /* PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H */