blob: a20a6a48ef02f3b7b79a555d1b2b813d10f931c0 [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 5af98a77887c2aa60bc93dbdddb174e03501b733 Mon Sep 17 00:00:00 2001
2From: Rui Miguel Silva <rui.silva@linaro.org>
3Date: Thu, 9 Dec 2021 14:17:39 +0000
4Subject: [PATCH] add psa ipc crypto backend
5
6Add psa ipc crypto backend and attach it to se proxy
7deployment.
8
9Signed-off-by: Rui Miguel Silva <rui.silva@arm.com>
10Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
11
12Upstream-Status: Pending [Not submitted to upstream yet]
13Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
14
15
16---
17 components/service/common/include/psa/sid.h | 73 +++++
18 .../crypto/backend/psa_ipc/component.cmake | 21 ++
19 .../backend/psa_ipc/crypto_ipc_backend.c | 26 ++
20 .../backend/psa_ipc/crypto_ipc_backend.h | 70 ++++
21 .../client/caller/psa_ipc/crypto_caller.h | 34 ++
22 .../caller/psa_ipc/crypto_caller_aead.h | 252 +++++++++++++++
23 .../crypto_caller_asymmetric_decrypt.h | 76 +++++
24 .../crypto_caller_asymmetric_encrypt.h | 76 +++++
25 .../caller/psa_ipc/crypto_caller_cipher.h | 246 +++++++++++++++
26 .../caller/psa_ipc/crypto_caller_copy_key.h | 57 ++++
27 .../psa_ipc/crypto_caller_destroy_key.h | 51 +++
28 .../caller/psa_ipc/crypto_caller_export_key.h | 59 ++++
29 .../psa_ipc/crypto_caller_export_public_key.h | 59 ++++
30 .../psa_ipc/crypto_caller_generate_key.h | 55 ++++
31 .../psa_ipc/crypto_caller_generate_random.h | 57 ++++
32 .../crypto_caller_get_key_attributes.h | 56 ++++
33 .../caller/psa_ipc/crypto_caller_hash.h | 220 +++++++++++++
34 .../caller/psa_ipc/crypto_caller_import_key.h | 57 ++++
35 .../psa_ipc/crypto_caller_key_attributes.h | 51 +++
36 .../psa_ipc/crypto_caller_key_derivation.h | 298 ++++++++++++++++++
37 .../client/caller/psa_ipc/crypto_caller_mac.h | 207 ++++++++++++
38 .../caller/psa_ipc/crypto_caller_purge_key.h | 51 +++
39 .../caller/psa_ipc/crypto_caller_sign_hash.h | 64 ++++
40 .../psa_ipc/crypto_caller_verify_hash.h | 59 ++++
41 .../crypto/include/psa/crypto_client_struct.h | 8 +-
42 .../service/crypto/include/psa/crypto_sizes.h | 2 +-
43 deployments/se-proxy/opteesp/CMakeLists.txt | 2 +-
44 .../se-proxy/opteesp/service_proxy_factory.c | 15 +-
45 .../providers/arm/corstone1000/platform.cmake | 2 +
46 29 files changed, 2293 insertions(+), 11 deletions(-)
47 create mode 100644 components/service/crypto/backend/psa_ipc/component.cmake
48 create mode 100644 components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
49 create mode 100644 components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
50 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller.h
51 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
52 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
53 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
54 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
55 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
56 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
57 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
58 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
59 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
60 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
61 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
62 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
63 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
64 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_key_attributes.h
65 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
66 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
67 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
68 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
69 create mode 100644 components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
70
71diff --git a/components/service/common/include/psa/sid.h b/components/service/common/include/psa/sid.h
72index 4a951d4a..7a29cc25 100644
73--- a/components/service/common/include/psa/sid.h
74+++ b/components/service/common/include/psa/sid.h
75@@ -37,6 +37,79 @@ extern "C" {
76 #define TFM_CRYPTO_VERSION (1U)
77 #define TFM_CRYPTO_HANDLE (0x40000100U)
78
79+/**
80+ * \brief Define a progressive numerical value for each SID which can be used
81+ * when dispatching the requests to the service
82+ */
83+enum {
84+ TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID = (0u),
85+ TFM_CRYPTO_RESET_KEY_ATTRIBUTES_SID,
86+ TFM_CRYPTO_OPEN_KEY_SID,
87+ TFM_CRYPTO_CLOSE_KEY_SID,
88+ TFM_CRYPTO_IMPORT_KEY_SID,
89+ TFM_CRYPTO_DESTROY_KEY_SID,
90+ TFM_CRYPTO_EXPORT_KEY_SID,
91+ TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
92+ TFM_CRYPTO_PURGE_KEY_SID,
93+ TFM_CRYPTO_COPY_KEY_SID,
94+ TFM_CRYPTO_HASH_COMPUTE_SID,
95+ TFM_CRYPTO_HASH_COMPARE_SID,
96+ TFM_CRYPTO_HASH_SETUP_SID,
97+ TFM_CRYPTO_HASH_UPDATE_SID,
98+ TFM_CRYPTO_HASH_FINISH_SID,
99+ TFM_CRYPTO_HASH_VERIFY_SID,
100+ TFM_CRYPTO_HASH_ABORT_SID,
101+ TFM_CRYPTO_HASH_CLONE_SID,
102+ TFM_CRYPTO_MAC_COMPUTE_SID,
103+ TFM_CRYPTO_MAC_VERIFY_SID,
104+ TFM_CRYPTO_MAC_SIGN_SETUP_SID,
105+ TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
106+ TFM_CRYPTO_MAC_UPDATE_SID,
107+ TFM_CRYPTO_MAC_SIGN_FINISH_SID,
108+ TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
109+ TFM_CRYPTO_MAC_ABORT_SID,
110+ TFM_CRYPTO_CIPHER_ENCRYPT_SID,
111+ TFM_CRYPTO_CIPHER_DECRYPT_SID,
112+ TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
113+ TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
114+ TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
115+ TFM_CRYPTO_CIPHER_SET_IV_SID,
116+ TFM_CRYPTO_CIPHER_UPDATE_SID,
117+ TFM_CRYPTO_CIPHER_FINISH_SID,
118+ TFM_CRYPTO_CIPHER_ABORT_SID,
119+ TFM_CRYPTO_AEAD_ENCRYPT_SID,
120+ TFM_CRYPTO_AEAD_DECRYPT_SID,
121+ TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
122+ TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
123+ TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
124+ TFM_CRYPTO_AEAD_SET_NONCE_SID,
125+ TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
126+ TFM_CRYPTO_AEAD_UPDATE_AD_SID,
127+ TFM_CRYPTO_AEAD_UPDATE_SID,
128+ TFM_CRYPTO_AEAD_FINISH_SID,
129+ TFM_CRYPTO_AEAD_VERIFY_SID,
130+ TFM_CRYPTO_AEAD_ABORT_SID,
131+ TFM_CRYPTO_SIGN_MESSAGE_SID,
132+ TFM_CRYPTO_VERIFY_MESSAGE_SID,
133+ TFM_CRYPTO_SIGN_HASH_SID,
134+ TFM_CRYPTO_VERIFY_HASH_SID,
135+ TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
136+ TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
137+ TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
138+ TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
139+ TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
140+ TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
141+ TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
142+ TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
143+ TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
144+ TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
145+ TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
146+ TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
147+ TFM_CRYPTO_GENERATE_RANDOM_SID,
148+ TFM_CRYPTO_GENERATE_KEY_SID,
149+ TFM_CRYPTO_SID_MAX,
150+};
151+
152 /******** TFM_SP_PLATFORM ********/
153 #define TFM_SP_PLATFORM_SYSTEM_RESET_SID (0x00000040U)
154 #define TFM_SP_PLATFORM_SYSTEM_RESET_VERSION (1U)
155diff --git a/components/service/crypto/backend/psa_ipc/component.cmake b/components/service/crypto/backend/psa_ipc/component.cmake
156new file mode 100644
157index 00000000..93c297a8
158--- /dev/null
159+++ b/components/service/crypto/backend/psa_ipc/component.cmake
160@@ -0,0 +1,21 @@
161+#-------------------------------------------------------------------------------
162+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
163+#
164+# SPDX-License-Identifier: BSD-3-Clause
165+#
166+#-------------------------------------------------------------------------------
167+if (NOT DEFINED TGT)
168+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
169+endif()
170+
171+target_sources(${TGT} PRIVATE
172+ "${CMAKE_CURRENT_LIST_DIR}/crypto_ipc_backend.c"
173+ )
174+
175+# The ipc crypto backend uses the psa crypto client to realize the
176+# psa crypto API that the crypto provider depends on. This define
177+# configures the psa crypto client to be built with the ipc crypto
178+# caller.
179+target_compile_definitions(${TGT} PRIVATE
180+ PSA_CRYPTO_CLIENT_CALLER_SELECTION_H="service/crypto/client/caller/psa_ipc/crypto_caller.h"
181+)
182diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
183new file mode 100644
184index 00000000..e47cd4ff
185--- /dev/null
186+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.c
187@@ -0,0 +1,26 @@
188+/*
189+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
190+ *
191+ * SPDX-License-Identifier: BSD-3-Clause
192+ */
193+
194+#include <stddef.h>
195+#include <psa/crypto.h>
196+#include <service/crypto/client/psa/psa_crypto_client.h>
197+#include <protocols/rpc/common/packed-c/status.h>
198+#include "crypto_ipc_backend.h"
199+
200+psa_status_t crypto_ipc_backend_init(struct rpc_caller *caller)
201+{
202+ psa_status_t status = psa_crypto_client_init(caller);
203+
204+ if (status == PSA_SUCCESS)
205+ status = psa_crypto_init();
206+
207+ return status;
208+}
209+
210+void crypto_ipc_backend_deinit(void)
211+{
212+ psa_crypto_client_deinit();
213+}
214diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
215new file mode 100644
216index 00000000..c13c20e8
217--- /dev/null
218+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
219@@ -0,0 +1,70 @@
220+/*
221+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
222+ *
223+ * SPDX-License-Identifier: BSD-3-Clause
224+ */
225+
226+#ifndef CRYPTO_IPC_BACKEND_H
227+#define CRYPTO_IPC_BACKEND_H
228+
229+#include <service/crypto/client/psa/psa_crypto_client.h>
230+#include <psa/error.h>
231+#include <rpc_caller.h>
232+
233+#ifdef __cplusplus
234+extern "C" {
235+#endif
236+
237+/**
238+ * \brief This type is used to overcome a limitation in the number of maximum
239+ * IOVECs that can be used especially in psa_aead_encrypt and
240+ * psa_aead_decrypt. To be removed in case the AEAD APIs number of
241+ * parameters passed gets restructured
242+ */
243+#define TFM_CRYPTO_MAX_NONCE_LENGTH (16u)
244+struct psa_ipc_crypto_aead_pack_input {
245+ uint8_t nonce[TFM_CRYPTO_MAX_NONCE_LENGTH];
246+ uint32_t nonce_length;
247+};
248+
249+struct psa_ipc_crypto_pack_iovec {
250+ uint32_t sfn_id; /*!< Secure function ID used to dispatch the
251+ * request
252+ */
253+ uint16_t step; /*!< Key derivation step */
254+ psa_key_id_t key_id; /*!< Key id */
255+ psa_algorithm_t alg; /*!< Algorithm */
256+ uint32_t op_handle; /*!< Frontend context handle associated to a
257+ * multipart operation
258+ */
259+ uint32_t capacity; /*!< Key derivation capacity */
260+
261+ struct psa_ipc_crypto_aead_pack_input aead_in; /*!< FixMe: Temporarily used for
262+ * AEAD until the API is
263+ * restructured
264+ */
265+};
266+
267+#define iov_size sizeof(struct psa_ipc_crypto_pack_iovec)
268+
269+/**
270+ * \brief Initialize the psa ipc crypto backend
271+ *
272+ * Initializes a crypto backend that uses the psa API client with a
273+ * psa_ipc_backend caller to realize the PSA crypto API used by the crypto
274+ * service proviser.
275+ *
276+ * \return PSA_SUCCESS if backend initialized successfully
277+ */
278+psa_status_t crypto_ipc_backend_init(struct rpc_caller *caller);
279+
280+/**
281+ * \brief Clean-up to free any resource used by the crypto backend
282+ */
283+void crypto_ipc_backend_deinit(void);
284+
285+#ifdef __cplusplus
286+} /* extern "C" */
287+#endif
288+
289+#endif /* CRYPTO_IPC_BACKEND_H */
290diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller.h
291new file mode 100644
292index 00000000..0a972187
293--- /dev/null
294+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller.h
295@@ -0,0 +1,34 @@
296+/*
297+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
298+ *
299+ * SPDX-License-Identifier: BSD-3-Clause
300+ */
301+
302+#ifndef PSA_IPC_CRYPTO_CALLER_H
303+#define PSA_IPC_CRYPTO_CALLER_H
304+
305+/**
306+ * Includes all header files that form the psa ipc crypto caller
307+ * interface. May be used by a client that needs to call operations
308+ * provided by a crypto service instance using the psa ipc interface.
309+ */
310+#include "crypto_caller_aead.h"
311+#include "crypto_caller_asymmetric_decrypt.h"
312+#include "crypto_caller_asymmetric_encrypt.h"
313+#include "crypto_caller_cipher.h"
314+#include "crypto_caller_copy_key.h"
315+#include "crypto_caller_destroy_key.h"
316+#include "crypto_caller_export_key.h"
317+#include "crypto_caller_export_public_key.h"
318+#include "crypto_caller_generate_key.h"
319+#include "crypto_caller_generate_random.h"
320+#include "crypto_caller_get_key_attributes.h"
321+#include "crypto_caller_hash.h"
322+#include "crypto_caller_import_key.h"
323+#include "crypto_caller_key_derivation.h"
324+#include "crypto_caller_mac.h"
325+#include "crypto_caller_purge_key.h"
326+#include "crypto_caller_sign_hash.h"
327+#include "crypto_caller_verify_hash.h"
328+
329+#endif /* PSA_IPC_CRYPTO_CALLER_H */
330diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
331new file mode 100644
332index 00000000..78517fe3
333--- /dev/null
334+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_aead.h
335@@ -0,0 +1,252 @@
336+/*
337+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
338+ *
339+ * SPDX-License-Identifier: BSD-3-Clause
340+ */
341+
342+#ifndef PSA_IPC_CRYPTO_CALLER_AEAD_H
343+#define PSA_IPC_CRYPTO_CALLER_AEAD_H
344+
345+#include <string.h>
346+#include <stdlib.h>
347+#include <psa/crypto.h>
348+#include <psa/client.h>
349+#include <psa/sid.h>
350+#include <service/common/client/service_client.h>
351+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
352+#include <protocols/rpc/common/packed-c/status.h>
353+#include <protocols/service/crypto/packed-c/opcodes.h>
354+#include <protocols/service/crypto/packed-c/key_attributes.h>
355+#include <protocols/service/crypto/packed-c/import_key.h>
356+#include "crypto_caller_key_attributes.h"
357+
358+#ifdef __cplusplus
359+extern "C" {
360+#endif
361+
362+static inline psa_status_t crypto_caller_aead_encrypt(
363+ struct service_client *context,
364+ psa_key_id_t key,
365+ psa_algorithm_t alg,
366+ const uint8_t *nonce,
367+ size_t nonce_length,
368+ const uint8_t *additional_data,
369+ size_t additional_data_length,
370+ const uint8_t *plaintext,
371+ size_t plaintext_length,
372+ uint8_t *aeadtext,
373+ size_t aeadtext_size,
374+ size_t *aeadtext_length)
375+{
376+ struct service_client *ipc = context;
377+ struct rpc_caller *caller = ipc->caller;
378+ psa_status_t status;
379+ size_t in_len;
380+ int i;
381+ struct psa_ipc_crypto_pack_iovec iov = {
382+ .sfn_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
383+ .key_id = key,
384+ .alg = alg,
385+ .aead_in = { .nonce = {0}, .nonce_length = nonce_length },
386+ };
387+
388+ if (!additional_data && additional_data_length)
389+ return PSA_ERROR_INVALID_ARGUMENT;
390+
391+ struct psa_invec in_vec[] = {
392+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
393+ { .base = psa_ptr_const_to_u32(plaintext),
394+ .len = plaintext_length },
395+ { .base = psa_ptr_const_to_u32(additional_data),
396+ .len = additional_data_length},
397+ };
398+ struct psa_outvec out_vec[] = {
399+ { .base = psa_ptr_to_u32(aeadtext), .len = aeadtext_size },
400+ };
401+
402+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH)
403+ return PSA_ERROR_INVALID_ARGUMENT;
404+
405+ if (nonce) {
406+ for (i = 0; i < nonce_length; i++)
407+ iov.aead_in.nonce[i] = nonce[i];
408+ }
409+
410+ in_len = IOVEC_LEN(in_vec);
411+
412+ if (!additional_data)
413+ in_len--;
414+
415+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
416+ in_len, out_vec, IOVEC_LEN(out_vec));
417+
418+ *aeadtext_length = out_vec[0].len;
419+
420+ return status;
421+}
422+
423+static inline psa_status_t crypto_caller_aead_decrypt(
424+ struct service_client *context,
425+ psa_key_id_t key,
426+ psa_algorithm_t alg,
427+ const uint8_t *nonce,
428+ size_t nonce_length,
429+ const uint8_t *additional_data,
430+ size_t additional_data_length,
431+ const uint8_t *aeadtext,
432+ size_t aeadtext_length,
433+ uint8_t *plaintext,
434+ size_t plaintext_size,
435+ size_t *plaintext_length)
436+{
437+ struct service_client *ipc = context;
438+ struct rpc_caller *caller = ipc->caller;
439+ psa_status_t status;
440+ size_t in_len;
441+ int i;
442+ struct psa_ipc_crypto_pack_iovec iov = {
443+ .sfn_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
444+ .key_id = key,
445+ .alg = alg,
446+ .aead_in = { .nonce = {0}, .nonce_length = nonce_length },
447+ };
448+
449+ if (!additional_data && additional_data_length)
450+ return PSA_ERROR_INVALID_ARGUMENT;
451+
452+ struct psa_invec in_vec[] = {
453+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
454+ { .base = psa_ptr_const_to_u32(aeadtext),
455+ .len = aeadtext_length },
456+ { .base = psa_ptr_const_to_u32(additional_data),
457+ .len = additional_data_length},
458+ };
459+ struct psa_outvec out_vec[] = {
460+ { .base = psa_ptr_to_u32(plaintext), .len = plaintext_size },
461+ };
462+
463+ if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH)
464+ return PSA_ERROR_INVALID_ARGUMENT;
465+
466+ if (nonce) {
467+ for (i = 0; i < nonce_length; i++)
468+ iov.aead_in.nonce[i] = nonce[i];
469+ }
470+
471+ in_len = IOVEC_LEN(in_vec);
472+
473+ if (!additional_data)
474+ in_len--;
475+
476+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
477+ in_len, out_vec, IOVEC_LEN(out_vec));
478+
479+ *plaintext_length = out_vec[0].len;
480+
481+ return status;
482+}
483+
484+static inline psa_status_t crypto_caller_aead_encrypt_setup(
485+ struct service_client *context,
486+ uint32_t *op_handle,
487+ psa_key_id_t key,
488+ psa_algorithm_t alg)
489+{
490+ return PSA_ERROR_NOT_SUPPORTED;
491+}
492+
493+static inline psa_status_t crypto_caller_aead_decrypt_setup(
494+ struct service_client *context,
495+ uint32_t *op_handle,
496+ psa_key_id_t key,
497+ psa_algorithm_t alg)
498+{
499+ return PSA_ERROR_NOT_SUPPORTED;
500+}
501+
502+static inline psa_status_t crypto_caller_aead_generate_nonce(
503+ struct service_client *context,
504+ uint32_t op_handle,
505+ uint8_t *nonce,
506+ size_t nonce_size,
507+ size_t *nonce_length)
508+{
509+ return PSA_ERROR_NOT_SUPPORTED;
510+}
511+
512+static inline psa_status_t crypto_caller_aead_set_nonce(
513+ struct service_client *context,
514+ uint32_t op_handle,
515+ const uint8_t *nonce,
516+ size_t nonce_length)
517+{
518+ return PSA_ERROR_NOT_SUPPORTED;
519+}
520+
521+static inline psa_status_t crypto_caller_aead_set_lengths(
522+ struct service_client *context,
523+ uint32_t op_handle,
524+ size_t ad_length,
525+ size_t plaintext_length)
526+{
527+ return PSA_ERROR_NOT_SUPPORTED;
528+}
529+
530+static inline psa_status_t crypto_caller_aead_update_ad(
531+ struct service_client *context,
532+ uint32_t op_handle,
533+ const uint8_t *input,
534+ size_t input_length)
535+{
536+ return PSA_ERROR_NOT_SUPPORTED;
537+}
538+
539+static inline psa_status_t crypto_caller_aead_update(
540+ struct service_client *context,
541+ uint32_t op_handle,
542+ const uint8_t *input,
543+ size_t input_length,
544+ uint8_t *output,
545+ size_t output_size,
546+ size_t *output_length)
547+{
548+ return PSA_ERROR_NOT_SUPPORTED;
549+}
550+
551+static inline psa_status_t crypto_caller_aead_finish(
552+ struct service_client *context,
553+ uint32_t op_handle,
554+ uint8_t *aeadtext,
555+ size_t aeadtext_size,
556+ size_t *aeadtext_length,
557+ uint8_t *tag,
558+ size_t tag_size,
559+ size_t *tag_length)
560+{
561+ return PSA_ERROR_NOT_SUPPORTED;
562+}
563+
564+static inline psa_status_t crypto_caller_aead_verify(
565+ struct service_client *context,
566+ uint32_t op_handle,
567+ uint8_t *plaintext,
568+ size_t plaintext_size,
569+ size_t *plaintext_length,
570+ const uint8_t *tag,
571+ size_t tag_length)
572+{
573+ return PSA_ERROR_NOT_SUPPORTED;
574+}
575+
576+static inline psa_status_t crypto_caller_aead_abort(
577+ struct service_client *context,
578+ uint32_t op_handle)
579+{
580+ return PSA_ERROR_NOT_SUPPORTED;
581+}
582+
583+#ifdef __cplusplus
584+}
585+#endif
586+
587+#endif /* PSA_IPC_CRYPTO_CALLER_AEAD_H */
588diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
589new file mode 100644
590index 00000000..ff01815c
591--- /dev/null
592+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_decrypt.h
593@@ -0,0 +1,76 @@
594+/*
595+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
596+ *
597+ * SPDX-License-Identifier: BSD-3-Clause
598+ */
599+
600+#ifndef PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_DECRYPT_H
601+#define PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_DECRYPT_H
602+
603+#include <string.h>
604+#include <stdlib.h>
605+#include <psa/crypto.h>
606+#include <psa/client.h>
607+#include <psa/sid.h>
608+#include <service/common/client/service_client.h>
609+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
610+#include <protocols/rpc/common/packed-c/status.h>
611+#include <protocols/service/crypto/packed-c/opcodes.h>
612+#include <protocols/service/crypto/packed-c/key_attributes.h>
613+#include <protocols/service/crypto/packed-c/import_key.h>
614+#include "crypto_caller_key_attributes.h"
615+
616+#ifdef __cplusplus
617+extern "C" {
618+#endif
619+
620+static inline psa_status_t crypto_caller_asymmetric_decrypt(
621+ struct service_client *context,
622+ psa_key_id_t id,
623+ psa_algorithm_t alg,
624+ const uint8_t *input, size_t input_length,
625+ const uint8_t *salt, size_t salt_length,
626+ uint8_t *output, size_t output_size,
627+ size_t *output_length)
628+{
629+ struct service_client *ipc = context;
630+ struct rpc_caller *caller = ipc->caller;
631+ psa_status_t status;
632+ size_t in_len;
633+ struct psa_ipc_crypto_pack_iovec iov = {
634+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
635+ .key_id = id,
636+ .alg = alg,
637+ };
638+
639+ /* Sanitize optional input */
640+ if (!salt && salt_length)
641+ return PSA_ERROR_INVALID_ARGUMENT;
642+
643+ struct psa_invec in_vec[] = {
644+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
645+ { .base = psa_ptr_const_to_u32(input), .len = input_length },
646+ { .base = psa_ptr_const_to_u32(salt), .len = salt_length },
647+ };
648+ struct psa_outvec out_vec[] = {
649+ { .base = psa_ptr_to_u32(output), .len = output_size },
650+ };
651+
652+
653+ in_len = IOVEC_LEN(in_vec);
654+ if (!salt)
655+ in_len--;
656+
657+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
658+ in_len, out_vec, IOVEC_LEN(out_vec));
659+
660+ *output_length = out_vec[0].len;
661+
662+ return status;
663+}
664+
665+#ifdef __cplusplus
666+}
667+#endif
668+
669+#endif /* PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_DECRYPT_H */
670diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
671new file mode 100644
672index 00000000..1daf1689
673--- /dev/null
674+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_asymmetric_encrypt.h
675@@ -0,0 +1,76 @@
676+/*
677+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
678+ *
679+ * SPDX-License-Identifier: BSD-3-Clause
680+ */
681+
682+#ifndef PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_ENCRYPT_H
683+#define PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_ENCRYPT_H
684+
685+#include <string.h>
686+#include <stdlib.h>
687+#include <psa/crypto.h>
688+#include <psa/client.h>
689+#include <psa/sid.h>
690+#include <service/common/client/service_client.h>
691+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
692+#include <protocols/rpc/common/packed-c/status.h>
693+#include <protocols/service/crypto/packed-c/opcodes.h>
694+#include <protocols/service/crypto/packed-c/key_attributes.h>
695+#include <protocols/service/crypto/packed-c/import_key.h>
696+#include "crypto_caller_key_attributes.h"
697+
698+#ifdef __cplusplus
699+extern "C" {
700+#endif
701+
702+static inline psa_status_t crypto_caller_asymmetric_encrypt(
703+ struct service_client *context,
704+ psa_key_id_t id,
705+ psa_algorithm_t alg,
706+ const uint8_t *input, size_t input_length,
707+ const uint8_t *salt, size_t salt_length,
708+ uint8_t *output, size_t output_size,
709+ size_t *output_length)
710+{
711+ struct service_client *ipc = context;
712+ struct rpc_caller *caller = ipc->caller;
713+ psa_status_t status;
714+ size_t in_len;
715+ struct psa_ipc_crypto_pack_iovec iov = {
716+ .sfn_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
717+ .key_id = id,
718+ .alg = alg,
719+ };
720+
721+ /* Sanitize optional input */
722+ if (!salt && salt_length)
723+ return PSA_ERROR_INVALID_ARGUMENT;
724+
725+ struct psa_invec in_vec[] = {
726+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
727+ { .base = psa_ptr_const_to_u32(input), .len = input_length },
728+ { .base = psa_ptr_const_to_u32(salt), .len = salt_length },
729+ };
730+ struct psa_outvec out_vec[] = {
731+ { .base = psa_ptr_to_u32(output), .len = output_size },
732+ };
733+
734+
735+ in_len = IOVEC_LEN(in_vec);
736+ if (!salt)
737+ in_len--;
738+
739+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
740+ in_len, out_vec, IOVEC_LEN(out_vec));
741+
742+ *output_length = out_vec[0].len;
743+
744+ return status;
745+}
746+
747+#ifdef __cplusplus
748+}
749+#endif
750+
751+#endif /* PSA_IPC_CRYPTO_CALLER_ASYMMETRIC_ENCRYPT_H */
752diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
753new file mode 100644
754index 00000000..fbefb28d
755--- /dev/null
756+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_cipher.h
757@@ -0,0 +1,246 @@
758+/*
759+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
760+ *
761+ * SPDX-License-Identifier: BSD-3-Clause
762+ */
763+
764+#ifndef PSA_IPC_CRYPTO_CALLER_CIPHER_H
765+#define PSA_IPC_CRYPTO_CALLER_CIPHER_H
766+
767+#include <string.h>
768+#include <stdlib.h>
769+#include <psa/crypto.h>
770+#include <psa/client.h>
771+#include <psa/sid.h>
772+#include <service/common/client/service_client.h>
773+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
774+#include <protocols/rpc/common/packed-c/status.h>
775+#include <protocols/service/crypto/packed-c/opcodes.h>
776+#include <protocols/service/crypto/packed-c/key_attributes.h>
777+#include <protocols/service/crypto/packed-c/import_key.h>
778+#include "crypto_caller_key_attributes.h"
779+
780+#ifdef __cplusplus
781+extern "C" {
782+#endif
783+
784+static inline psa_status_t crypto_caller_cipher_encrypt_setup(
785+ struct service_client *context,
786+ uint32_t *op_handle,
787+ psa_key_id_t key,
788+ psa_algorithm_t alg)
789+{
790+ struct service_client *ipc = context;
791+ struct rpc_caller *caller = ipc->caller;
792+ psa_status_t status;
793+ struct psa_ipc_crypto_pack_iovec iov = {
794+ .sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
795+ .key_id = key,
796+ .alg = alg,
797+ .op_handle = *op_handle,
798+ };
799+ struct psa_invec in_vec[] = {
800+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
801+ };
802+ struct psa_outvec out_vec[] = {
803+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) }
804+ };
805+
806+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
807+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
808+
809+ return status;
810+}
811+
812+static inline psa_status_t crypto_caller_cipher_decrypt_setup(
813+ struct service_client *context,
814+ uint32_t *op_handle,
815+ psa_key_id_t key,
816+ psa_algorithm_t alg)
817+{
818+ struct service_client *ipc = context;
819+ struct rpc_caller *caller = ipc->caller;
820+ psa_status_t status;
821+ struct psa_ipc_crypto_pack_iovec iov = {
822+ .sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
823+ .key_id = key,
824+ .alg = alg,
825+ .op_handle = *op_handle,
826+ };
827+ struct psa_invec in_vec[] = {
828+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
829+ };
830+ struct psa_outvec out_vec[] = {
831+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) }
832+ };
833+
834+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
835+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
836+
837+ return status;
838+}
839+
840+static inline psa_status_t crypto_caller_cipher_generate_iv(
841+ struct service_client *context,
842+ uint32_t op_handle,
843+ uint8_t *iv,
844+ size_t iv_size,
845+ size_t *iv_length)
846+{
847+ struct service_client *ipc = context;
848+ struct rpc_caller *caller = ipc->caller;
849+ psa_status_t status;
850+ struct psa_ipc_crypto_pack_iovec iov = {
851+ .sfn_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
852+ .op_handle = op_handle,
853+ };
854+ struct psa_invec in_vec[] = {
855+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
856+ };
857+ struct psa_outvec out_vec[] = {
858+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
859+ { .base = psa_ptr_to_u32(iv), .len = iv_size },
860+ };
861+
862+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
863+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
864+
865+ *iv_length = out_vec[1].len;
866+
867+ return status;
868+}
869+
870+static inline psa_status_t crypto_caller_cipher_set_iv(
871+ struct service_client *context,
872+ uint32_t op_handle,
873+ const uint8_t *iv,
874+ size_t iv_length)
875+{
876+ struct service_client *ipc = context;
877+ struct rpc_caller *caller = ipc->caller;
878+ psa_status_t status;
879+ struct psa_ipc_crypto_pack_iovec iov = {
880+ .sfn_id = TFM_CRYPTO_CIPHER_SET_IV_SID,
881+ .op_handle = op_handle,
882+ };
883+ struct psa_invec in_vec[] = {
884+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
885+ { .base = psa_ptr_const_to_u32(iv), .len = iv_length },
886+ };
887+ struct psa_outvec out_vec[] = {
888+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
889+ };
890+
891+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
892+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
893+
894+ return status;
895+}
896+
897+static inline psa_status_t crypto_caller_cipher_update(
898+ struct service_client *context,
899+ uint32_t op_handle,
900+ const uint8_t *input,
901+ size_t input_length,
902+ uint8_t *output,
903+ size_t output_size,
904+ size_t *output_length)
905+{
906+ struct service_client *ipc = context;
907+ struct rpc_caller *caller = ipc->caller;
908+ psa_status_t status;
909+ struct psa_ipc_crypto_pack_iovec iov = {
910+ .sfn_id = TFM_CRYPTO_CIPHER_UPDATE_SID,
911+ .op_handle = op_handle,
912+ };
913+ struct psa_invec in_vec[] = {
914+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
915+ { .base = psa_ptr_const_to_u32(input), .len = input_length },
916+ };
917+ struct psa_outvec out_vec[] = {
918+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
919+ { .base = psa_ptr_to_u32(output), .len = output_size },
920+ };
921+
922+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
923+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
924+
925+ *output_length = out_vec[1].len;
926+
927+ return status;
928+}
929+
930+static inline psa_status_t crypto_caller_cipher_finish(
931+ struct service_client *context,
932+ uint32_t op_handle,
933+ uint8_t *output,
934+ size_t output_size,
935+ size_t *output_length)
936+{
937+ struct service_client *ipc = context;
938+ struct rpc_caller *caller = ipc->caller;
939+ psa_status_t status;
940+ struct psa_ipc_crypto_pack_iovec iov = {
941+ .sfn_id = TFM_CRYPTO_CIPHER_FINISH_SID,
942+ .op_handle = op_handle,
943+ };
944+ struct psa_invec in_vec[] = {
945+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
946+ };
947+ struct psa_outvec out_vec[] = {
948+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
949+ { .base = psa_ptr_to_u32(output), .len = output_size },
950+ };
951+
952+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
953+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
954+
955+ *output_length = out_vec[1].len;
956+
957+ return status;
958+}
959+
960+static inline psa_status_t crypto_caller_cipher_abort(
961+ struct service_client *context,
962+ uint32_t op_handle)
963+{
964+ struct service_client *ipc = context;
965+ struct rpc_caller *caller = ipc->caller;
966+ psa_status_t status;
967+ struct psa_ipc_crypto_pack_iovec iov = {
968+ .sfn_id = TFM_CRYPTO_CIPHER_ABORT_SID,
969+ .op_handle = op_handle,
970+ };
971+ struct psa_invec in_vec[] = {
972+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
973+ };
974+ struct psa_outvec out_vec[] = {
975+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
976+ };
977+
978+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
979+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
980+
981+ return status;
982+}
983+
984+static inline size_t crypto_caller_cipher_max_update_size(const struct service_client *context)
985+{
986+ /* Returns the maximum number of bytes that may be
987+ * carried as a parameter of the cipher_update operation
988+ * using the ipc encoding.
989+ */
990+ size_t payload_space = context->service_info.max_payload;
991+ size_t overhead = iov_size;
992+
993+ /* Allow for output to be a whole number of blocks */
994+ overhead += PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE;
995+
996+ return (payload_space > overhead) ? payload_space - overhead : 0;
997+}
998+
999+#ifdef __cplusplus
1000+}
1001+#endif
1002+
1003+#endif /* PSA_IPC_CRYPTO_CALLER_CIPHER_H */
1004diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
1005new file mode 100644
1006index 00000000..9a988171
1007--- /dev/null
1008+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_copy_key.h
1009@@ -0,0 +1,57 @@
1010+/*
1011+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1012+ *
1013+ * SPDX-License-Identifier: BSD-3-Clause
1014+ */
1015+
1016+#ifndef PSA_IPC_CRYPTO_CALLER_COPY_KEY_H
1017+#define PSA_IPC_CRYPTO_CALLER_COPY_KEY_H
1018+
1019+#include <string.h>
1020+#include <stdlib.h>
1021+#include <psa/crypto.h>
1022+#include <psa/client.h>
1023+#include <psa/sid.h>
1024+#include <service/common/client/service_client.h>
1025+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1026+#include <protocols/rpc/common/packed-c/status.h>
1027+#include <protocols/service/crypto/packed-c/opcodes.h>
1028+#include <protocols/service/crypto/packed-c/key_attributes.h>
1029+#include <protocols/service/crypto/packed-c/import_key.h>
1030+#include "crypto_caller_key_attributes.h"
1031+
1032+#ifdef __cplusplus
1033+extern "C" {
1034+#endif
1035+
1036+static inline psa_status_t crypto_caller_copy_key(struct service_client *context,
1037+ psa_key_id_t source_key,
1038+ const psa_key_attributes_t *attributes,
1039+ psa_key_id_t *target_key)
1040+{
1041+ struct service_client *ipc = context;
1042+ struct rpc_caller *caller = ipc->caller;
1043+ psa_status_t status;
1044+ struct psa_ipc_crypto_pack_iovec iov = {
1045+ .sfn_id = TFM_CRYPTO_COPY_KEY_SID,
1046+ .key_id = source_key,
1047+ };
1048+ struct psa_invec in_vec[] = {
1049+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1050+ { .base = psa_ptr_const_to_u32(attributes), .len = sizeof(psa_key_attributes_t) },
1051+ };
1052+ struct psa_outvec out_vec[] = {
1053+ { .base = psa_ptr_to_u32(target_key), .len = sizeof(psa_key_id_t) }
1054+ };
1055+
1056+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1057+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1058+
1059+ return status;
1060+}
1061+
1062+#ifdef __cplusplus
1063+}
1064+#endif
1065+
1066+#endif /* PSA_IPC_CRYPTO_CALLER_COPY_KEY_H */
1067diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
1068new file mode 100644
1069index 00000000..d00f4faa
1070--- /dev/null
1071+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_destroy_key.h
1072@@ -0,0 +1,51 @@
1073+/*
1074+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1075+ *
1076+ * SPDX-License-Identifier: BSD-3-Clause
1077+ */
1078+
1079+#ifndef PSA_IPC_CRYPTO_CALLER_DESTROY_KEY_H
1080+#define PSA_IPC_CRYPTO_CALLER_DESTROY_KEY_H
1081+
1082+#include <string.h>
1083+#include <stdlib.h>
1084+#include <psa/crypto.h>
1085+#include <psa/client.h>
1086+#include <psa/sid.h>
1087+#include <service/common/client/service_client.h>
1088+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1089+#include <protocols/rpc/common/packed-c/status.h>
1090+#include <protocols/service/crypto/packed-c/opcodes.h>
1091+#include <protocols/service/crypto/packed-c/key_attributes.h>
1092+#include <protocols/service/crypto/packed-c/import_key.h>
1093+#include "crypto_caller_key_attributes.h"
1094+
1095+#ifdef __cplusplus
1096+extern "C" {
1097+#endif
1098+
1099+static inline psa_status_t crypto_caller_destroy_key(struct service_client *context,
1100+ psa_key_id_t id)
1101+{
1102+ struct service_client *ipc = context;
1103+ struct rpc_caller *caller = ipc->caller;
1104+ psa_status_t status;
1105+ struct psa_ipc_crypto_pack_iovec iov = {
1106+ .sfn_id = TFM_CRYPTO_DESTROY_KEY_SID,
1107+ .key_id = id,
1108+ };
1109+ struct psa_invec in_vec[] = {
1110+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1111+ };
1112+
1113+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1114+ IOVEC_LEN(in_vec), NULL, 0);
1115+
1116+ return status;
1117+}
1118+
1119+#ifdef __cplusplus
1120+}
1121+#endif
1122+
1123+#endif /* PSA_IPC_CRYPTO_CALLER_DESTROY_KEY_H */
1124diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
1125new file mode 100644
1126index 00000000..8ac5477f
1127--- /dev/null
1128+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_key.h
1129@@ -0,0 +1,59 @@
1130+/*
1131+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1132+ *
1133+ * SPDX-License-Identifier: BSD-3-Clause
1134+ */
1135+
1136+#ifndef PSA_IPC_CRYPTO_CALLER_EXPORT_KEY_H
1137+#define PSA_IPC_CRYPTO_CALLER_EXPORT_KEY_H
1138+
1139+#include <string.h>
1140+#include <stdlib.h>
1141+#include <psa/crypto.h>
1142+#include <psa/client.h>
1143+#include <psa/sid.h>
1144+#include <service/common/client/service_client.h>
1145+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1146+#include <protocols/rpc/common/packed-c/status.h>
1147+#include <protocols/service/crypto/packed-c/opcodes.h>
1148+#include <protocols/service/crypto/packed-c/key_attributes.h>
1149+#include <protocols/service/crypto/packed-c/import_key.h>
1150+#include "crypto_caller_key_attributes.h"
1151+
1152+#ifdef __cplusplus
1153+extern "C" {
1154+#endif
1155+
1156+static inline psa_status_t crypto_caller_export_key(struct service_client *context,
1157+ psa_key_id_t id,
1158+ uint8_t *data,
1159+ size_t data_size,
1160+ size_t *data_length)
1161+{
1162+ struct service_client *ipc = context;
1163+ struct rpc_caller *caller = ipc->caller;
1164+ psa_status_t status;
1165+ struct psa_ipc_crypto_pack_iovec iov = {
1166+ .sfn_id = TFM_CRYPTO_EXPORT_KEY_SID,
1167+ .key_id = id,
1168+ };
1169+ struct psa_invec in_vec[] = {
1170+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1171+ };
1172+ struct psa_outvec out_vec[] = {
1173+ { .base = psa_ptr_to_u32(data), .len = data_size }
1174+ };
1175+
1176+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1177+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1178+
1179+ *data_length = out_vec[0].len;
1180+
1181+ return status;
1182+}
1183+
1184+#ifdef __cplusplus
1185+}
1186+#endif
1187+
1188+#endif /* PSA_IPC_CRYPTO_CALLER_EXPORT_KEY_H */
1189diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
1190new file mode 100644
1191index 00000000..b24c47f1
1192--- /dev/null
1193+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_export_public_key.h
1194@@ -0,0 +1,59 @@
1195+/*
1196+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1197+ *
1198+ * SPDX-License-Identifier: BSD-3-Clause
1199+ */
1200+
1201+#ifndef PSA_IPC_CRYPTO_CALLER_EXPORT_PUBLIC_KEY_H
1202+#define PSA_IPC_CRYPTO_CALLER_EXPORT_PUBLIC_KEY_H
1203+
1204+#include <string.h>
1205+#include <stdlib.h>
1206+#include <psa/crypto.h>
1207+#include <psa/client.h>
1208+#include <psa/sid.h>
1209+#include <service/common/client/service_client.h>
1210+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1211+#include <protocols/rpc/common/packed-c/status.h>
1212+#include <protocols/service/crypto/packed-c/opcodes.h>
1213+#include <protocols/service/crypto/packed-c/key_attributes.h>
1214+#include <protocols/service/crypto/packed-c/import_key.h>
1215+#include "crypto_caller_key_attributes.h"
1216+
1217+#ifdef __cplusplus
1218+extern "C" {
1219+#endif
1220+
1221+static inline psa_status_t crypto_caller_export_public_key(struct service_client *context,
1222+ psa_key_id_t id,
1223+ uint8_t *data,
1224+ size_t data_size,
1225+ size_t *data_length)
1226+{
1227+ struct service_client *ipc = context;
1228+ struct rpc_caller *caller = ipc->caller;
1229+ psa_status_t status;
1230+ struct psa_ipc_crypto_pack_iovec iov = {
1231+ .sfn_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
1232+ .key_id = id,
1233+ };
1234+ struct psa_invec in_vec[] = {
1235+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1236+ };
1237+ struct psa_outvec out_vec[] = {
1238+ { .base = psa_ptr_to_u32(data), .len = data_size }
1239+ };
1240+
1241+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1242+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1243+
1244+ *data_length = out_vec[0].len;
1245+
1246+ return status;
1247+}
1248+
1249+#ifdef __cplusplus
1250+}
1251+#endif
1252+
1253+#endif /* PSA_IPC_CRYPTO_CALLER_EXPORT_PUBLIC_KEY_H */
1254diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
1255new file mode 100644
1256index 00000000..1b66ed40
1257--- /dev/null
1258+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_key.h
1259@@ -0,0 +1,55 @@
1260+/*
1261+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1262+ *
1263+ * SPDX-License-Identifier: BSD-3-Clause
1264+ */
1265+
1266+#ifndef PSA_IPC_CRYPTO_CALLER_GENERATE_KEY_H
1267+#define PSA_IPC_CRYPTO_CALLER_GENERATE_KEY_H
1268+
1269+#include <string.h>
1270+#include <stdlib.h>
1271+#include <psa/crypto.h>
1272+#include <psa/client.h>
1273+#include <psa/sid.h>
1274+#include <service/common/client/service_client.h>
1275+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1276+#include <protocols/rpc/common/packed-c/status.h>
1277+#include <protocols/service/crypto/packed-c/opcodes.h>
1278+#include <protocols/service/crypto/packed-c/key_attributes.h>
1279+#include <protocols/service/crypto/packed-c/import_key.h>
1280+#include "crypto_caller_key_attributes.h"
1281+
1282+#ifdef __cplusplus
1283+extern "C" {
1284+#endif
1285+
1286+static inline psa_status_t crypto_caller_generate_key(struct service_client *context,
1287+ const psa_key_attributes_t *attributes,
1288+ psa_key_id_t *id)
1289+{
1290+ struct service_client *ipc = context;
1291+ struct rpc_caller *caller = ipc->caller;
1292+ psa_status_t status;
1293+ struct psa_ipc_crypto_pack_iovec iov = {
1294+ .sfn_id = TFM_CRYPTO_GENERATE_KEY_SID,
1295+ };
1296+ struct psa_invec in_vec[] = {
1297+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1298+ { .base = psa_ptr_const_to_u32(attributes), .len = sizeof(psa_key_attributes_t) },
1299+ };
1300+ struct psa_outvec out_vec[] = {
1301+ { .base = psa_ptr_to_u32(id), .len = sizeof(psa_key_id_t) }
1302+ };
1303+
1304+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1305+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1306+
1307+ return status;
1308+}
1309+
1310+#ifdef __cplusplus
1311+}
1312+#endif
1313+
1314+#endif /* PSA_IPC_CRYPTO_CALLER_GENERATE_KEY_H */
1315diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
1316new file mode 100644
1317index 00000000..7c538237
1318--- /dev/null
1319+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_generate_random.h
1320@@ -0,0 +1,57 @@
1321+/*
1322+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1323+ *
1324+ * SPDX-License-Identifier: BSD-3-Clause
1325+ */
1326+
1327+#ifndef PSA_IPC_CRYPTO_CALLER_GENERATE_RANDOM_H
1328+#define PSA_IPC_CRYPTO_CALLER_GENERATE_RANDOM_H
1329+
1330+#include <string.h>
1331+#include <stdlib.h>
1332+#include <psa/crypto.h>
1333+#include <psa/client.h>
1334+#include <psa/sid.h>
1335+#include <service/common/client/service_client.h>
1336+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1337+#include <protocols/rpc/common/packed-c/status.h>
1338+#include <protocols/service/crypto/packed-c/opcodes.h>
1339+#include <protocols/service/crypto/packed-c/key_attributes.h>
1340+#include <protocols/service/crypto/packed-c/import_key.h>
1341+#include "crypto_caller_key_attributes.h"
1342+
1343+#ifdef __cplusplus
1344+extern "C" {
1345+#endif
1346+
1347+static inline psa_status_t crypto_caller_generate_random(struct service_client *context,
1348+ uint8_t *output,
1349+ size_t output_size)
1350+{
1351+ struct service_client *ipc = context;
1352+ struct rpc_caller *caller = ipc->caller;
1353+ psa_status_t status;
1354+ struct psa_ipc_crypto_pack_iovec iov = {
1355+ .sfn_id = TFM_CRYPTO_GENERATE_RANDOM_SID,
1356+ };
1357+ struct psa_invec in_vec[] = {
1358+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1359+ };
1360+ struct psa_outvec out_vec[] = {
1361+ { .base = psa_ptr_to_u32(output), .len = output_size }
1362+ };
1363+
1364+ if (!output_size)
1365+ return PSA_SUCCESS;
1366+
1367+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1368+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1369+
1370+ return status;
1371+}
1372+
1373+#ifdef __cplusplus
1374+}
1375+#endif
1376+
1377+#endif /* PSA_IPC_CRYPTO_CALLER_GENERATE_RANDOM_H */
1378diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
1379new file mode 100644
1380index 00000000..22f1d18f
1381--- /dev/null
1382+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_key_attributes.h
1383@@ -0,0 +1,56 @@
1384+/*
1385+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1386+ *
1387+ * SPDX-License-Identifier: BSD-3-Clause
1388+ */
1389+
1390+#ifndef PSA_IPC_CRYPTO_CALLER_GET_KEY_ATTRIBUTES_H
1391+#define PSA_IPC_CRYPTO_CALLER_GET_KEY_ATTRIBUTES_H
1392+
1393+#include <string.h>
1394+#include <stdlib.h>
1395+#include <psa/crypto.h>
1396+#include <psa/client.h>
1397+#include <psa/sid.h>
1398+#include <service/common/client/service_client.h>
1399+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1400+#include <protocols/rpc/common/packed-c/status.h>
1401+#include <protocols/service/crypto/packed-c/opcodes.h>
1402+#include <protocols/service/crypto/packed-c/key_attributes.h>
1403+#include <protocols/service/crypto/packed-c/import_key.h>
1404+#include "crypto_caller_key_attributes.h"
1405+
1406+#ifdef __cplusplus
1407+extern "C" {
1408+#endif
1409+
1410+static inline psa_status_t crypto_caller_get_key_attributes(
1411+ struct service_client *context,
1412+ psa_key_id_t key,
1413+ psa_key_attributes_t *attributes)
1414+{
1415+ struct service_client *ipc = context;
1416+ struct rpc_caller *caller = ipc->caller;
1417+ psa_status_t status;
1418+ struct psa_ipc_crypto_pack_iovec iov = {
1419+ .sfn_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
1420+ .key_id = key,
1421+ };
1422+ struct psa_invec in_vec[] = {
1423+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1424+ };
1425+ struct psa_outvec out_vec[] = {
1426+ { .base = psa_ptr_to_u32(attributes), .len = sizeof(psa_key_attributes_t) }
1427+ };
1428+
1429+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1430+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1431+
1432+ return status;
1433+}
1434+
1435+#ifdef __cplusplus
1436+}
1437+#endif
1438+
1439+#endif /* PSA_IPC_CRYPTO_CALLER_GET_KEY_ATTRIBUTES_H */
1440diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
1441new file mode 100644
1442index 00000000..9f37908a
1443--- /dev/null
1444+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_hash.h
1445@@ -0,0 +1,220 @@
1446+/*
1447+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1448+ *
1449+ * SPDX-License-Identifier: BSD-3-Clause
1450+ */
1451+
1452+#ifndef PSA_IPC_CRYPTO_CALLER_HASH_H
1453+#define PSA_IPC_CRYPTO_CALLER_HASH_H
1454+
1455+#include <string.h>
1456+#include <stdlib.h>
1457+#include <psa/crypto.h>
1458+#include <psa/client.h>
1459+#include <psa/sid.h>
1460+#include <service/common/client/service_client.h>
1461+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1462+#include <protocols/rpc/common/packed-c/status.h>
1463+#include <protocols/service/crypto/packed-c/opcodes.h>
1464+#include <protocols/service/crypto/packed-c/key_attributes.h>
1465+#include <protocols/service/crypto/packed-c/import_key.h>
1466+#include "crypto_caller_key_attributes.h"
1467+
1468+#ifdef __cplusplus
1469+extern "C" {
1470+#endif
1471+
1472+static inline psa_status_t crypto_caller_hash_setup(
1473+ struct service_client *context,
1474+ uint32_t *op_handle,
1475+ psa_algorithm_t alg)
1476+{
1477+ struct service_client *ipc = context;
1478+ struct rpc_caller *caller = ipc->caller;
1479+ psa_status_t status;
1480+ struct psa_ipc_crypto_pack_iovec iov = {
1481+ .sfn_id = TFM_CRYPTO_HASH_SETUP_SID,
1482+ .alg = alg,
1483+ .op_handle = *op_handle,
1484+ };
1485+ struct psa_invec in_vec[] = {
1486+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1487+ };
1488+ struct psa_outvec out_vec[] = {
1489+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) }
1490+ };
1491+
1492+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1493+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1494+
1495+ return status;
1496+}
1497+
1498+static inline psa_status_t crypto_caller_hash_update(
1499+ struct service_client *context,
1500+ uint32_t op_handle,
1501+ const uint8_t *input,
1502+ size_t input_length)
1503+{
1504+ struct service_client *ipc = context;
1505+ struct rpc_caller *caller = ipc->caller;
1506+ psa_status_t status;
1507+ struct psa_ipc_crypto_pack_iovec iov = {
1508+ .sfn_id = TFM_CRYPTO_HASH_UPDATE_SID,
1509+ .op_handle = op_handle,
1510+ };
1511+ struct psa_invec in_vec[] = {
1512+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1513+ { .base = psa_ptr_const_to_u32(input), .len = input_length },
1514+ };
1515+ struct psa_outvec out_vec[] = {
1516+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
1517+ };
1518+
1519+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1520+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1521+
1522+ return status;
1523+}
1524+
1525+static inline psa_status_t crypto_caller_hash_finish(
1526+ struct service_client *context,
1527+ uint32_t op_handle,
1528+ uint8_t *hash,
1529+ size_t hash_size,
1530+ size_t *hash_length)
1531+{
1532+ struct service_client *ipc = context;
1533+ struct rpc_caller *caller = ipc->caller;
1534+ psa_status_t status;
1535+ struct psa_ipc_crypto_pack_iovec iov = {
1536+ .sfn_id = TFM_CRYPTO_HASH_FINISH_SID,
1537+ .op_handle = op_handle,
1538+ };
1539+ struct psa_invec in_vec[] = {
1540+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1541+ };
1542+ struct psa_outvec out_vec[] = {
1543+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
1544+ { .base = psa_ptr_to_u32(hash), .len = hash_size},
1545+ };
1546+
1547+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1548+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1549+
1550+ *hash_length = out_vec[1].len;
1551+
1552+ return status;
1553+}
1554+
1555+static inline psa_status_t crypto_caller_hash_abort(
1556+ struct service_client *context,
1557+ uint32_t op_handle)
1558+{
1559+ struct service_client *ipc = context;
1560+ struct rpc_caller *caller = ipc->caller;
1561+ psa_status_t status;
1562+ struct psa_ipc_crypto_pack_iovec iov = {
1563+ .sfn_id = TFM_CRYPTO_HASH_ABORT_SID,
1564+ .op_handle = op_handle,
1565+ };
1566+ struct psa_invec in_vec[] = {
1567+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1568+ };
1569+ struct psa_outvec out_vec[] = {
1570+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
1571+ };
1572+
1573+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1574+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1575+
1576+ return status;
1577+}
1578+
1579+static inline psa_status_t crypto_caller_hash_verify(
1580+ struct service_client *context,
1581+ uint32_t op_handle,
1582+ const uint8_t *hash,
1583+ size_t hash_length)
1584+{
1585+ struct service_client *ipc = context;
1586+ struct rpc_caller *caller = ipc->caller;
1587+ psa_status_t status;
1588+ struct psa_ipc_crypto_pack_iovec iov = {
1589+ .sfn_id = TFM_CRYPTO_HASH_VERIFY_SID,
1590+ .op_handle = op_handle,
1591+ };
1592+ struct psa_invec in_vec[] = {
1593+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1594+ { .base = psa_ptr_const_to_u32(hash), .len = hash_length},
1595+ };
1596+ struct psa_outvec out_vec[] = {
1597+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
1598+ };
1599+
1600+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1601+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1602+
1603+ return status;
1604+}
1605+
1606+static inline psa_status_t crypto_caller_hash_clone(
1607+ struct service_client *context,
1608+ uint32_t source_op_handle,
1609+ uint32_t *target_op_handle)
1610+{
1611+ struct service_client *ipc = context;
1612+ struct rpc_caller *caller = ipc->caller;
1613+ psa_status_t status;
1614+ struct psa_ipc_crypto_pack_iovec iov = {
1615+ .sfn_id = TFM_CRYPTO_HASH_CLONE_SID,
1616+ .op_handle = source_op_handle,
1617+ };
1618+ struct psa_invec in_vec[] = {
1619+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1620+ };
1621+ struct psa_outvec out_vec[] = {
1622+ { .base = psa_ptr_to_u32(target_op_handle),
1623+ .len = sizeof(uint32_t) },
1624+ };
1625+
1626+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1627+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1628+
1629+ return status;
1630+}
1631+
1632+static inline psa_status_t crypto_caller_hash_suspend(struct service_client *context,
1633+ uint32_t op_handle,
1634+ uint8_t *hash_state,
1635+ size_t hash_state_size,
1636+ size_t *hash_state_length)
1637+{
1638+ return PSA_ERROR_NOT_SUPPORTED;
1639+}
1640+
1641+static inline psa_status_t crypto_caller_hash_resume(struct service_client *context,
1642+ uint32_t op_handle,
1643+ const uint8_t *hash_state,
1644+ size_t hash_state_length)
1645+{
1646+ return PSA_ERROR_NOT_SUPPORTED;
1647+}
1648+
1649+static inline size_t crypto_caller_hash_max_update_size(const struct service_client *context)
1650+{
1651+ /* Returns the maximum number of bytes that may be
1652+ * carried as a parameter of the hash_update operation
1653+ * using the packed-c encoding.
1654+ */
1655+ size_t payload_space = context->service_info.max_payload;
1656+ size_t overhead = iov_size;
1657+
1658+ return (payload_space > overhead) ? payload_space - overhead : 0;
1659+}
1660+
1661+#ifdef __cplusplus
1662+}
1663+#endif
1664+
1665+#endif /* PSA_IPC_CRYPTO_CALLER_HASH_H */
1666diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
1667new file mode 100644
1668index 00000000..d4703366
1669--- /dev/null
1670+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_import_key.h
1671@@ -0,0 +1,57 @@
1672+/*
1673+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1674+ *
1675+ * SPDX-License-Identifier: BSD-3-Clause
1676+ */
1677+
1678+#ifndef PSA_IPC_CRYPTO_CALLER_IMPORT_KEY_H
1679+#define PSA_IPC_CRYPTO_CALLER_IMPORT_KEY_H
1680+
1681+#include <string.h>
1682+#include <stdlib.h>
1683+#include <psa/crypto.h>
1684+#include <psa/client.h>
1685+#include <psa/sid.h>
1686+#include <service/common/client/service_client.h>
1687+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1688+#include <protocols/rpc/common/packed-c/status.h>
1689+#include <protocols/service/crypto/packed-c/opcodes.h>
1690+#include <protocols/service/crypto/packed-c/key_attributes.h>
1691+#include <protocols/service/crypto/packed-c/import_key.h>
1692+#include "crypto_caller_key_attributes.h"
1693+
1694+#ifdef __cplusplus
1695+extern "C" {
1696+#endif
1697+
1698+static inline psa_status_t crypto_caller_import_key(struct service_client *context,
1699+ const psa_key_attributes_t *attributes,
1700+ const uint8_t *data, size_t data_length,
1701+ psa_key_id_t *id)
1702+{
1703+ struct service_client *ipc = context;
1704+ struct rpc_caller *caller = ipc->caller;
1705+ psa_status_t status;
1706+ struct psa_ipc_crypto_pack_iovec iov = {
1707+ .sfn_id = TFM_CRYPTO_IMPORT_KEY_SID,
1708+ };
1709+ struct psa_invec in_vec[] = {
1710+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
1711+ { .base = psa_ptr_const_to_u32(attributes), .len = sizeof(psa_key_attributes_t) },
1712+ { .base = psa_ptr_const_to_u32(data), .len = data_length }
1713+ };
1714+ struct psa_outvec out_vec[] = {
1715+ { .base = psa_ptr_to_u32(id), .len = sizeof(psa_key_id_t) }
1716+ };
1717+
1718+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1719+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1720+
1721+ return status;
1722+}
1723+
1724+#ifdef __cplusplus
1725+}
1726+#endif
1727+
1728+#endif /* PACKEDC_CRYPTO_CALLER_IMPORT_KEY_H */
1729diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_attributes.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_attributes.h
1730new file mode 100644
1731index 00000000..2fad2f0a
1732--- /dev/null
1733+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_attributes.h
1734@@ -0,0 +1,51 @@
1735+/*
1736+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1737+ *
1738+ * SPDX-License-Identifier: BSD-3-Clause
1739+ */
1740+
1741+#ifndef PACKEDC_CRYPTO_CALLER_KEY_ATTRIBUTES_H
1742+#define PACKEDC_CRYPTO_CALLER_KEY_ATTRIBUTES_H
1743+
1744+#include <psa/crypto.h>
1745+#include <protocols/service/crypto/packed-c/key_attributes.h>
1746+
1747+#ifdef __cplusplus
1748+extern "C" {
1749+#endif
1750+
1751+static inline void packedc_crypto_caller_translate_key_attributes_to_proto(
1752+ struct ts_crypto_key_attributes *proto_attributes,
1753+ const psa_key_attributes_t *psa_attributes)
1754+{
1755+ proto_attributes->type = psa_get_key_type(psa_attributes);
1756+ proto_attributes->key_bits = psa_get_key_bits(psa_attributes);
1757+ proto_attributes->lifetime = psa_get_key_lifetime(psa_attributes);
1758+ proto_attributes->id = psa_get_key_id(psa_attributes);
1759+
1760+ proto_attributes->policy.usage = psa_get_key_usage_flags(psa_attributes);
1761+ proto_attributes->policy.alg = psa_get_key_algorithm(psa_attributes);
1762+ }
1763+
1764+static inline void packedc_crypto_caller_translate_key_attributes_from_proto(
1765+ psa_key_attributes_t *psa_attributes,
1766+ const struct ts_crypto_key_attributes *proto_attributes)
1767+{
1768+ psa_set_key_type(psa_attributes, proto_attributes->type);
1769+ psa_set_key_bits(psa_attributes, proto_attributes->key_bits);
1770+ psa_set_key_lifetime(psa_attributes, proto_attributes->lifetime);
1771+
1772+ if (proto_attributes->lifetime == PSA_KEY_LIFETIME_PERSISTENT) {
1773+
1774+ psa_set_key_id(psa_attributes, proto_attributes->id);
1775+ }
1776+
1777+ psa_set_key_usage_flags(psa_attributes, proto_attributes->policy.usage);
1778+ psa_set_key_algorithm(psa_attributes, proto_attributes->policy.alg);
1779+}
1780+
1781+#ifdef __cplusplus
1782+}
1783+#endif
1784+
1785+#endif /* PACKEDC_CRYPTO_CALLER_KEY_ATTRIBUTES_H */
1786diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
1787new file mode 100644
1788index 00000000..5ce4fb6c
1789--- /dev/null
1790+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_key_derivation.h
1791@@ -0,0 +1,298 @@
1792+/*
1793+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
1794+ *
1795+ * SPDX-License-Identifier: BSD-3-Clause
1796+ */
1797+
1798+#ifndef PSA_IPC_CRYPTO_CALLER_KEY_DERIVATION_H
1799+#define PSA_IPC_CRYPTO_CALLER_KEY_DERIVATION_H
1800+
1801+#include <string.h>
1802+#include <stdlib.h>
1803+#include <psa/crypto.h>
1804+#include <psa/client.h>
1805+#include <psa/sid.h>
1806+#include <service/common/client/service_client.h>
1807+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
1808+#include <protocols/rpc/common/packed-c/status.h>
1809+#include <protocols/service/crypto/packed-c/opcodes.h>
1810+#include <protocols/service/crypto/packed-c/key_attributes.h>
1811+#include <protocols/service/crypto/packed-c/import_key.h>
1812+#include "crypto_caller_key_attributes.h"
1813+
1814+#ifdef __cplusplus
1815+extern "C" {
1816+#endif
1817+
1818+static inline psa_status_t crypto_caller_key_derivation_setup(
1819+ struct service_client *context,
1820+ uint32_t *op_handle,
1821+ psa_algorithm_t alg)
1822+{
1823+ struct service_client *ipc = context;
1824+ struct rpc_caller *caller = ipc->caller;
1825+ psa_status_t status;
1826+ struct psa_ipc_crypto_pack_iovec iov = {
1827+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
1828+ .alg = alg,
1829+ .op_handle = *op_handle,
1830+ };
1831+ struct psa_invec in_vec[] = {
1832+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1833+ };
1834+ struct psa_outvec out_vec[] = {
1835+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) }
1836+ };
1837+
1838+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1839+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1840+
1841+ return status;
1842+}
1843+
1844+static inline psa_status_t crypto_caller_key_derivation_get_capacity(
1845+ struct service_client *context,
1846+ const uint32_t op_handle,
1847+ size_t *capacity)
1848+{
1849+ struct service_client *ipc = context;
1850+ struct rpc_caller *caller = ipc->caller;
1851+ psa_status_t status;
1852+ struct psa_ipc_crypto_pack_iovec iov = {
1853+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
1854+ .op_handle = op_handle,
1855+ };
1856+ struct psa_invec in_vec[] = {
1857+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1858+ };
1859+ struct psa_outvec out_vec[] = {
1860+ { .base = psa_ptr_to_u32(capacity), .len = sizeof(uint32_t) }
1861+ };
1862+
1863+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1864+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1865+
1866+ return status;
1867+}
1868+
1869+static inline psa_status_t crypto_caller_key_derivation_set_capacity(
1870+ struct service_client *context,
1871+ uint32_t op_handle,
1872+ size_t capacity)
1873+{
1874+ struct service_client *ipc = context;
1875+ struct rpc_caller *caller = ipc->caller;
1876+ psa_status_t status;
1877+ struct psa_ipc_crypto_pack_iovec iov = {
1878+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
1879+ .capacity = capacity,
1880+ .op_handle = op_handle,
1881+ };
1882+ struct psa_invec in_vec[] = {
1883+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1884+ };
1885+
1886+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1887+ IOVEC_LEN(in_vec), NULL, 0);
1888+
1889+ return status;
1890+}
1891+
1892+static inline psa_status_t crypto_caller_key_derivation_input_bytes(
1893+ struct service_client *context,
1894+ uint32_t op_handle,
1895+ psa_key_derivation_step_t step,
1896+ const uint8_t *data,
1897+ size_t data_length)
1898+{
1899+ struct service_client *ipc = context;
1900+ struct rpc_caller *caller = ipc->caller;
1901+ psa_status_t status;
1902+ struct psa_ipc_crypto_pack_iovec iov = {
1903+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
1904+ .step = step,
1905+ .op_handle = op_handle,
1906+ };
1907+ struct psa_invec in_vec[] = {
1908+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1909+ { .base = psa_ptr_const_to_u32(data), .len = data_length },
1910+ };
1911+
1912+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1913+ IOVEC_LEN(in_vec), NULL, 0);
1914+
1915+ return status;
1916+}
1917+
1918+static inline psa_status_t crypto_caller_key_derivation_input_key(
1919+ struct service_client *context,
1920+ uint32_t op_handle,
1921+ psa_key_derivation_step_t step,
1922+ psa_key_id_t key)
1923+{
1924+ struct service_client *ipc = context;
1925+ struct rpc_caller *caller = ipc->caller;
1926+ psa_status_t status;
1927+ struct psa_ipc_crypto_pack_iovec iov = {
1928+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
1929+ .key_id = key,
1930+ .step = step,
1931+ .op_handle = op_handle,
1932+ };
1933+ struct psa_invec in_vec[] = {
1934+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1935+ };
1936+
1937+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1938+ IOVEC_LEN(in_vec), NULL, 0);
1939+
1940+ return status;
1941+}
1942+
1943+static inline psa_status_t crypto_caller_key_derivation_output_bytes(
1944+ struct service_client *context,
1945+ uint32_t op_handle,
1946+ uint8_t *output,
1947+ size_t output_length)
1948+{
1949+ struct service_client *ipc = context;
1950+ struct rpc_caller *caller = ipc->caller;
1951+ psa_status_t status;
1952+ struct psa_ipc_crypto_pack_iovec iov = {
1953+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
1954+ .op_handle = op_handle,
1955+ };
1956+ struct psa_invec in_vec[] = {
1957+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1958+ };
1959+ struct psa_outvec out_vec[] = {
1960+ { .base = psa_ptr_to_u32(output), .len = output_length },
1961+ };
1962+
1963+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1964+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1965+
1966+ return status;
1967+}
1968+
1969+static inline psa_status_t crypto_caller_key_derivation_output_key(
1970+ struct service_client *context,
1971+ const psa_key_attributes_t *attributes,
1972+ uint32_t op_handle,
1973+ psa_key_id_t *key)
1974+{
1975+ struct service_client *ipc = context;
1976+ struct rpc_caller *caller = ipc->caller;
1977+ psa_status_t status;
1978+ struct psa_ipc_crypto_pack_iovec iov = {
1979+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
1980+ .op_handle = op_handle,
1981+ };
1982+ struct psa_invec in_vec[] = {
1983+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
1984+ { .base = psa_ptr_const_to_u32(attributes),
1985+ .len = sizeof(psa_key_attributes_t) },
1986+ };
1987+ struct psa_outvec out_vec[] = {
1988+ { .base = psa_ptr_to_u32(key), .len = sizeof(psa_key_id_t)},
1989+ };
1990+
1991+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
1992+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
1993+
1994+ return status;
1995+}
1996+
1997+static inline psa_status_t crypto_caller_key_derivation_abort(
1998+ struct service_client *context,
1999+ uint32_t op_handle)
2000+{
2001+ struct service_client *ipc = context;
2002+ struct rpc_caller *caller = ipc->caller;
2003+ psa_status_t status;
2004+ struct psa_ipc_crypto_pack_iovec iov = {
2005+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
2006+ .op_handle = op_handle,
2007+ };
2008+ struct psa_invec in_vec[] = {
2009+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2010+ };
2011+ struct psa_outvec out_vec[] = {
2012+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
2013+ };
2014+
2015+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2016+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2017+
2018+ return status;
2019+}
2020+
2021+static inline psa_status_t crypto_caller_key_derivation_key_agreement(
2022+ struct service_client *context,
2023+ uint32_t op_handle,
2024+ psa_key_derivation_step_t step,
2025+ psa_key_id_t private_key,
2026+ const uint8_t *peer_key,
2027+ size_t peer_key_length)
2028+{
2029+ struct service_client *ipc = context;
2030+ struct rpc_caller *caller = ipc->caller;
2031+ psa_status_t status;
2032+ struct psa_ipc_crypto_pack_iovec iov = {
2033+ .sfn_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
2034+ .key_id = private_key,
2035+ .step = step,
2036+ .op_handle = op_handle,
2037+ };
2038+ struct psa_invec in_vec[] = {
2039+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2040+ { .base = psa_ptr_const_to_u32(peer_key),
2041+ .len = peer_key_length},
2042+ };
2043+
2044+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2045+ IOVEC_LEN(in_vec), NULL, 0);
2046+
2047+ return status;
2048+}
2049+
2050+static inline psa_status_t crypto_caller_raw_key_agreement(
2051+ struct service_client *context,
2052+ psa_algorithm_t alg,
2053+ psa_key_id_t private_key,
2054+ const uint8_t *peer_key,
2055+ size_t peer_key_length,
2056+ uint8_t *output,
2057+ size_t output_size,
2058+ size_t *output_length)
2059+{
2060+ struct service_client *ipc = context;
2061+ struct rpc_caller *caller = ipc->caller;
2062+ psa_status_t status;
2063+ struct psa_ipc_crypto_pack_iovec iov = {
2064+ .sfn_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
2065+ .alg = alg,
2066+ .key_id = private_key,
2067+ };
2068+ struct psa_invec in_vec[] = {
2069+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2070+ { .base = psa_ptr_const_to_u32(peer_key),
2071+ .len = peer_key_length},
2072+ };
2073+ struct psa_outvec out_vec[] = {
2074+ { .base = psa_ptr_to_u32(output), .len = output_size },
2075+ };
2076+
2077+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2078+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2079+
2080+ *output_length = out_vec[0].len;
2081+
2082+ return status;
2083+}
2084+
2085+#ifdef __cplusplus
2086+}
2087+#endif
2088+
2089+#endif /* PSA_IPC_CRYPTO_CALLER_KEY_DERIVATION_H */
2090diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
2091new file mode 100644
2092index 00000000..3a820192
2093--- /dev/null
2094+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_mac.h
2095@@ -0,0 +1,207 @@
2096+/*
2097+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
2098+ *
2099+ * SPDX-License-Identifier: BSD-3-Clause
2100+ */
2101+
2102+#ifndef PSA_IPC_CRYPTO_CALLER_MAC_H
2103+#define PSA_IPC_CRYPTO_CALLER_MAC_H
2104+
2105+#include <string.h>
2106+#include <stdlib.h>
2107+#include <psa/crypto.h>
2108+#include <psa/client.h>
2109+#include <psa/sid.h>
2110+#include <service/common/client/service_client.h>
2111+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
2112+#include <protocols/rpc/common/packed-c/status.h>
2113+#include <protocols/service/crypto/packed-c/opcodes.h>
2114+#include <protocols/service/crypto/packed-c/key_attributes.h>
2115+#include <protocols/service/crypto/packed-c/import_key.h>
2116+#include "crypto_caller_key_attributes.h"
2117+
2118+#ifdef __cplusplus
2119+extern "C" {
2120+#endif
2121+
2122+static inline psa_status_t crypto_caller_mac_sign_setup(
2123+ struct service_client *context,
2124+ uint32_t *op_handle,
2125+ psa_key_id_t key,
2126+ psa_algorithm_t alg)
2127+{
2128+ struct service_client *ipc = context;
2129+ struct rpc_caller *caller = ipc->caller;
2130+ psa_status_t status;
2131+ struct psa_ipc_crypto_pack_iovec iov = {
2132+ .sfn_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
2133+ .key_id = key,
2134+ .alg = alg,
2135+ .op_handle = *op_handle,
2136+ };
2137+ struct psa_invec in_vec[] = {
2138+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2139+ };
2140+ struct psa_outvec out_vec[] = {
2141+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) },
2142+ };
2143+
2144+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2145+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2146+
2147+ return status;
2148+}
2149+
2150+static inline psa_status_t crypto_caller_mac_verify_setup(
2151+ struct service_client *context,
2152+ uint32_t *op_handle,
2153+ psa_key_id_t key,
2154+ psa_algorithm_t alg)
2155+{
2156+ struct service_client *ipc = context;
2157+ struct rpc_caller *caller = ipc->caller;
2158+ psa_status_t status;
2159+ struct psa_ipc_crypto_pack_iovec iov = {
2160+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
2161+ .key_id = key,
2162+ .alg = alg,
2163+ .op_handle = *op_handle,
2164+ };
2165+ struct psa_invec in_vec[] = {
2166+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2167+ };
2168+ struct psa_outvec out_vec[] = {
2169+ { .base = psa_ptr_to_u32(op_handle), .len = sizeof(uint32_t) },
2170+ };
2171+
2172+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2173+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2174+
2175+ return status;
2176+}
2177+
2178+static inline psa_status_t crypto_caller_mac_update(
2179+ struct service_client *context,
2180+ uint32_t op_handle,
2181+ const uint8_t *input,
2182+ size_t input_length)
2183+{
2184+ struct service_client *ipc = context;
2185+ struct rpc_caller *caller = ipc->caller;
2186+ psa_status_t status;
2187+ struct psa_ipc_crypto_pack_iovec iov = {
2188+ .sfn_id = TFM_CRYPTO_MAC_UPDATE_SID,
2189+ .op_handle = op_handle,
2190+ };
2191+ struct psa_invec in_vec[] = {
2192+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2193+ { .base = psa_ptr_const_to_u32(input), .len = input_length },
2194+ };
2195+ struct psa_outvec out_vec[] = {
2196+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
2197+ };
2198+
2199+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2200+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2201+
2202+ return status;
2203+}
2204+
2205+static inline psa_status_t crypto_caller_mac_sign_finish(
2206+ struct service_client *context,
2207+ uint32_t op_handle,
2208+ uint8_t *mac,
2209+ size_t mac_size,
2210+ size_t *mac_length)
2211+{
2212+ struct service_client *ipc = context;
2213+ struct rpc_caller *caller = ipc->caller;
2214+ psa_status_t status;
2215+ struct psa_ipc_crypto_pack_iovec iov = {
2216+ .sfn_id = TFM_CRYPTO_MAC_SIGN_FINISH_SID,
2217+ .op_handle = op_handle,
2218+ };
2219+ struct psa_invec in_vec[] = {
2220+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2221+ };
2222+ struct psa_outvec out_vec[] = {
2223+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
2224+ { .base = psa_ptr_to_u32(mac), .len = mac_size },
2225+ };
2226+
2227+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2228+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2229+
2230+ *mac_length = out_vec[1].len;
2231+
2232+ return status;
2233+}
2234+
2235+static inline psa_status_t crypto_caller_mac_verify_finish(
2236+ struct service_client *context,
2237+ uint32_t op_handle,
2238+ const uint8_t *mac,
2239+ size_t mac_length)
2240+{
2241+ struct service_client *ipc = context;
2242+ struct rpc_caller *caller = ipc->caller;
2243+ psa_status_t status;
2244+ struct psa_ipc_crypto_pack_iovec iov = {
2245+ .sfn_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
2246+ .op_handle = op_handle,
2247+ };
2248+ struct psa_invec in_vec[] = {
2249+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2250+ { .base = psa_ptr_const_to_u32(mac), .len = mac_length },
2251+ };
2252+ struct psa_outvec out_vec[] = {
2253+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
2254+ };
2255+
2256+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2257+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2258+
2259+ return status;
2260+}
2261+
2262+static inline psa_status_t crypto_caller_mac_abort(
2263+ struct service_client *context,
2264+ uint32_t op_handle)
2265+{
2266+ struct service_client *ipc = context;
2267+ struct rpc_caller *caller = ipc->caller;
2268+ psa_status_t status;
2269+ struct psa_ipc_crypto_pack_iovec iov = {
2270+ .sfn_id = TFM_CRYPTO_MAC_ABORT_SID,
2271+ .op_handle = op_handle,
2272+ };
2273+ struct psa_invec in_vec[] = {
2274+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2275+ };
2276+ struct psa_outvec out_vec[] = {
2277+ { .base = psa_ptr_to_u32(&op_handle), .len = sizeof(uint32_t) },
2278+ };
2279+
2280+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2281+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2282+
2283+ return status;
2284+}
2285+
2286+static inline size_t crypto_caller_mac_max_update_size(const struct service_client *context)
2287+{
2288+ /* Returns the maximum number of bytes that may be
2289+ * carried as a parameter of the mac_update operation
2290+ * using the packed-c encoding.
2291+ */
2292+ size_t payload_space = context->service_info.max_payload;
2293+ size_t overhead = iov_size;
2294+
2295+ return (payload_space > overhead) ? payload_space - overhead : 0;
2296+}
2297+
2298+#ifdef __cplusplus
2299+}
2300+#endif
2301+
2302+#endif /* PSA_IPC_CRYPTO_CALLER_MAC_H */
2303diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
2304new file mode 100644
2305index 00000000..a3a796e2
2306--- /dev/null
2307+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_purge_key.h
2308@@ -0,0 +1,51 @@
2309+/*
2310+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
2311+ *
2312+ * SPDX-License-Identifier: BSD-3-Clause
2313+ */
2314+
2315+#ifndef PACKEDC_CRYPTO_CALLER_PURGE_KEY_H
2316+#define PACKEDC_CRYPTO_CALLER_PURGE_KEY_H
2317+
2318+#include <string.h>
2319+#include <stdlib.h>
2320+#include <psa/crypto.h>
2321+#include <psa/client.h>
2322+#include <psa/sid.h>
2323+#include <service/common/client/service_client.h>
2324+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
2325+#include <protocols/rpc/common/packed-c/status.h>
2326+#include <protocols/service/crypto/packed-c/opcodes.h>
2327+#include <protocols/service/crypto/packed-c/key_attributes.h>
2328+#include <protocols/service/crypto/packed-c/import_key.h>
2329+#include "crypto_caller_key_attributes.h"
2330+
2331+#ifdef __cplusplus
2332+extern "C" {
2333+#endif
2334+
2335+static inline psa_status_t crypto_caller_purge_key(struct service_client *context,
2336+ psa_key_id_t id)
2337+{
2338+ struct service_client *ipc = context;
2339+ struct rpc_caller *caller = ipc->caller;
2340+ psa_status_t status;
2341+ struct psa_ipc_crypto_pack_iovec iov = {
2342+ .sfn_id = TFM_CRYPTO_PURGE_KEY_SID,
2343+ .key_id = id,
2344+ };
2345+ struct psa_invec in_vec[] = {
2346+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
2347+ };
2348+
2349+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2350+ IOVEC_LEN(in_vec), NULL, 0);
2351+
2352+ return status;
2353+}
2354+
2355+#ifdef __cplusplus
2356+}
2357+#endif
2358+
2359+#endif /* PACKEDC_CRYPTO_CALLER_PURGE_KEY_H */
2360diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
2361new file mode 100644
2362index 00000000..71d88ced
2363--- /dev/null
2364+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_sign_hash.h
2365@@ -0,0 +1,64 @@
2366+/*
2367+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
2368+ *
2369+ * SPDX-License-Identifier: BSD-3-Clause
2370+ */
2371+
2372+#ifndef PSA_IPC_CRYPTO_CALLER_SIGN_HASH_H
2373+#define PSA_IPC_CRYPTO_CALLER_SIGN_HASH_H
2374+
2375+#include <string.h>
2376+#include <stdlib.h>
2377+#include <psa/crypto.h>
2378+#include <psa/client.h>
2379+#include <psa/sid.h>
2380+#include <service/common/client/service_client.h>
2381+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
2382+#include <protocols/rpc/common/packed-c/status.h>
2383+#include <protocols/service/crypto/packed-c/opcodes.h>
2384+#include <protocols/service/crypto/packed-c/key_attributes.h>
2385+#include <protocols/service/crypto/packed-c/import_key.h>
2386+#include "crypto_caller_key_attributes.h"
2387+
2388+#ifdef __cplusplus
2389+extern "C" {
2390+#endif
2391+
2392+static inline psa_status_t crypto_caller_sign_hash(struct service_client *context,
2393+ psa_key_id_t id,
2394+ psa_algorithm_t alg,
2395+ const uint8_t *hash,
2396+ size_t hash_length,
2397+ uint8_t *signature,
2398+ size_t signature_size,
2399+ size_t *signature_length)
2400+{
2401+ struct service_client *ipc = context;
2402+ struct rpc_caller *caller = ipc->caller;
2403+ psa_status_t status;
2404+ struct psa_ipc_crypto_pack_iovec iov = {
2405+ .sfn_id = TFM_CRYPTO_SIGN_HASH_SID,
2406+ .key_id = id,
2407+ .alg = alg,
2408+ };
2409+ struct psa_invec in_vec[] = {
2410+ { .base = psa_ptr_to_u32(&iov), .len = iov_size },
2411+ { .base = psa_ptr_const_to_u32(hash), .len = hash_length },
2412+ };
2413+ struct psa_outvec out_vec[] = {
2414+ { .base = psa_ptr_to_u32(signature), .len = signature_size },
2415+ };
2416+
2417+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2418+ IOVEC_LEN(in_vec), out_vec, IOVEC_LEN(out_vec));
2419+
2420+ *signature_length = out_vec[0].len;
2421+
2422+ return status;
2423+}
2424+
2425+#ifdef __cplusplus
2426+}
2427+#endif
2428+
2429+#endif /* PSA_IPC_CRYPTO_CALLER_SIGN_HASH_H */
2430diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
2431new file mode 100644
2432index 00000000..e16f6e54
2433--- /dev/null
2434+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_verify_hash.h
2435@@ -0,0 +1,59 @@
2436+/*
2437+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
2438+ *
2439+ * SPDX-License-Identifier: BSD-3-Clause
2440+ */
2441+
2442+#ifndef PSA_IPC_CRYPTO_CALLER_VERIFY_HASH_H
2443+#define PSA_IPC_CRYPTO_CALLER_VERIFY_HASH_H
2444+
2445+#include <string.h>
2446+#include <stdlib.h>
2447+#include <psa/crypto.h>
2448+#include <psa/client.h>
2449+#include <psa/sid.h>
2450+#include <service/common/client/service_client.h>
2451+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
2452+#include <protocols/rpc/common/packed-c/status.h>
2453+#include <protocols/service/crypto/packed-c/opcodes.h>
2454+#include <protocols/service/crypto/packed-c/key_attributes.h>
2455+#include <protocols/service/crypto/packed-c/import_key.h>
2456+#include "crypto_caller_key_attributes.h"
2457+
2458+#ifdef __cplusplus
2459+extern "C" {
2460+#endif
2461+
2462+static inline psa_status_t crypto_caller_verify_hash(struct service_client *context,
2463+ psa_key_id_t id,
2464+ psa_algorithm_t alg,
2465+ const uint8_t *hash,
2466+ size_t hash_length,
2467+ const uint8_t *signature,
2468+ size_t signature_length)
2469+{
2470+ struct service_client *ipc = context;
2471+ struct rpc_caller *caller = ipc->caller;
2472+ psa_status_t status;
2473+ struct psa_ipc_crypto_pack_iovec iov = {
2474+ .sfn_id = TFM_CRYPTO_VERIFY_HASH_SID,
2475+ .key_id = id,
2476+ .alg = alg,
2477+ };
2478+ struct psa_invec in_vec[] = {
2479+ { .base = psa_ptr_to_u32(&iov), .len = sizeof(struct psa_ipc_crypto_pack_iovec) },
2480+ { .base = psa_ptr_const_to_u32(hash), .len = hash_length },
2481+ { .base = psa_ptr_const_to_u32(signature), .len = signature_length},
2482+ };
2483+
2484+ status = psa_call(caller, TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec,
2485+ IOVEC_LEN(in_vec), NULL, 0);
2486+
2487+ return status;
2488+}
2489+
2490+#ifdef __cplusplus
2491+}
2492+#endif
2493+
2494+#endif /* PSA_IPC_CRYPTO_CALLER_VERIFY_HASH_H */
2495diff --git a/components/service/crypto/include/psa/crypto_client_struct.h b/components/service/crypto/include/psa/crypto_client_struct.h
2496index abd420c8..bf95c982 100644
2497--- a/components/service/crypto/include/psa/crypto_client_struct.h
2498+++ b/components/service/crypto/include/psa/crypto_client_struct.h
2499@@ -31,12 +31,12 @@ extern "C" {
2500 * data structure internally. */
2501 struct psa_client_key_attributes_s
2502 {
2503+ uint16_t type;
2504+ uint16_t bits;
2505 uint32_t lifetime;
2506- uint32_t id;
2507- uint32_t alg;
2508+ psa_key_id_t id;
2509 uint32_t usage;
2510- size_t bits;
2511- uint16_t type;
2512+ uint32_t alg;
2513 };
2514
2515 #define PSA_CLIENT_KEY_ATTRIBUTES_INIT {0, 0, 0, 0, 0, 0}
2516diff --git a/components/service/crypto/include/psa/crypto_sizes.h b/components/service/crypto/include/psa/crypto_sizes.h
2517index 7a0149bb..4d7bf6e9 100644
2518--- a/components/service/crypto/include/psa/crypto_sizes.h
2519+++ b/components/service/crypto/include/psa/crypto_sizes.h
2520@@ -81,7 +81,7 @@
2521 #define PSA_HASH_MAX_SIZE 64
2522 #define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128
2523 #else
2524-#define PSA_HASH_MAX_SIZE 32
2525+#define PSA_HASH_MAX_SIZE 64
2526 #define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64
2527 #endif
2528
2529diff --git a/deployments/se-proxy/opteesp/CMakeLists.txt b/deployments/se-proxy/opteesp/CMakeLists.txt
2530index af2225e7..21904283 100644
2531--- a/deployments/se-proxy/opteesp/CMakeLists.txt
2532+++ b/deployments/se-proxy/opteesp/CMakeLists.txt
2533@@ -85,7 +85,7 @@ add_components(TARGET "se-proxy"
2534 "components/rpc/dummy"
2535 "components/rpc/common/caller"
2536 "components/service/attestation/key_mngr/stub"
2537- "components/service/crypto/backend/stub"
2538+ "components/service/crypto/backend/psa_ipc"
2539 "components/service/crypto/client/psa"
2540 "components/service/secure_storage/backend/mock_store"
2541 )
2542diff --git a/deployments/se-proxy/opteesp/service_proxy_factory.c b/deployments/se-proxy/opteesp/service_proxy_factory.c
2543index 1110ac46..7edeef8b 100644
2544--- a/deployments/se-proxy/opteesp/service_proxy_factory.c
2545+++ b/deployments/se-proxy/opteesp/service_proxy_factory.c
2546@@ -15,7 +15,7 @@
2547 #include <trace.h>
2548
2549 /* Stub backends */
2550-#include <service/crypto/backend/stub/stub_crypto_backend.h>
2551+#include <service/crypto/backend/psa_ipc/crypto_ipc_backend.h>
2552 #include <service/secure_storage/backend/secure_storage_ipc/secure_storage_ipc.h>
2553 #include <service/secure_storage/backend/mock_store/mock_store.h>
2554
2555@@ -47,12 +47,17 @@ struct rpc_interface *crypto_proxy_create(void)
2556 {
2557 struct rpc_interface *crypto_iface = NULL;
2558 struct crypto_provider *crypto_provider;
2559+ struct rpc_caller *crypto_caller;
2560
2561- if (stub_crypto_backend_init() == PSA_SUCCESS) {
2562+ crypto_caller = openamp_caller_init(&openamp);
2563+ if (!crypto_caller)
2564+ return NULL;
2565+
2566+ if (crypto_ipc_backend_init(&openamp.rpc_caller) != PSA_SUCCESS)
2567+ return NULL;
2568
2569- crypto_provider = crypto_provider_factory_create();
2570- crypto_iface = service_provider_get_rpc_interface(&crypto_provider->base_provider);
2571- }
2572+ crypto_provider = crypto_provider_factory_create();
2573+ crypto_iface = service_provider_get_rpc_interface(&crypto_provider->base_provider);
2574
2575 return crypto_iface;
2576 }
2577diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
2578index bb778bb9..51e5faa3 100644
2579--- a/platform/providers/arm/corstone1000/platform.cmake
2580+++ b/platform/providers/arm/corstone1000/platform.cmake
2581@@ -8,3 +8,5 @@
2582
2583 # include MHU driver
2584 include(${TS_ROOT}/platform/drivers/arm/mhu_driver/component.cmake)
2585+
2586+add_compile_definitions(MBEDTLS_ECP_DP_SECP521R1_ENABLED)