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