1 /*
2  * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "tfm_crypto_defs.h"
13 
14 #include "psa/client.h"
15 #include "psa_manifest/sid.h"
16 
17 #define API_DISPATCH(in_vec, out_vec)          \
18     psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,  \
19              in_vec, IOVEC_LEN(in_vec),        \
20              out_vec, IOVEC_LEN(out_vec))
21 #define API_DISPATCH_NO_OUTVEC(in_vec)         \
22     psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,  \
23              in_vec, IOVEC_LEN(in_vec),        \
24              (psa_outvec *)NULL, 0)
25 
26 /*!
27  * \def CONFIG_TFM_CRYPTO_API_RENAME
28  *
29  * \brief By setting this to 1, system integrators can rename the symbols of the
30  *        PSA Crypto APIs available in the TF-M interface. It allows flexibility
31  *        for some integration setups where multiple providers of the PSA Crypto
32  *        APIs are available at link time. Normally this configuration option
33  *        should not be enabled when building the Secure interface because the
34  *        secure partitions will just use the standard function names. By default
35  *        it prepends the "tfm_crypto__" prefix.
36  *
37  * \note  This config option is not available through the TF-M configuration as
38  *        it's for NS applications and system integrators to enable.
39  */
40 
41 /*!
42  * \def TFM_CRYPTO_API(ret, fun)
43  *
44  * \brief Define the function signature of a TF-M Crypto API with return
45  *        type \a ret and PSA Crypto API function name \a fun
46  *
47  * \param ret return type associated to the API
48  * \param fun API name (e.g. a PSA Crypto API function name)
49  *
50  * \returns Function signature
51  */
52 
53 #if CONFIG_TFM_CRYPTO_API_RENAME == 1
54 #define TFM_CRYPTO_API(ret, fun) ret tfm_crypto__##fun
55 #else
56 #define TFM_CRYPTO_API(ret, fun) ret fun
57 #endif /* CONFIG_TFM_CRYPTO_API_RENAME */
58 
TFM_CRYPTO_API(psa_status_t,psa_crypto_init)59 TFM_CRYPTO_API(psa_status_t, psa_crypto_init)(void)
60 {
61     /* Service init is performed during TFM boot up,
62      * so application level initialisation is empty
63      */
64     return PSA_SUCCESS;
65 }
66 
TFM_CRYPTO_API(int,psa_can_do_hash)67 TFM_CRYPTO_API(int, psa_can_do_hash)(psa_algorithm_t hash_alg)
68 {
69     psa_status_t status;
70     int can_do_hash;
71     const struct tfm_crypto_pack_iovec iov = {
72         .function_id = TFM_CRYPTO_CAN_DO_HASH_SID,
73         .alg = hash_alg,
74     };
75     psa_invec in_vec[] = {
76         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
77     };
78     psa_outvec out_vec[] = {
79         {.base = &can_do_hash, .len = sizeof(int)},
80     };
81 
82     status = API_DISPATCH(in_vec, out_vec);
83 
84     return (status != PSA_SUCCESS) ? 0 : can_do_hash;
85 }
86 
TFM_CRYPTO_API(int,psa_can_do_cipher)87 TFM_CRYPTO_API(int, psa_can_do_cipher)(psa_key_type_t key_type, psa_algorithm_t cipher_alg)
88 {
89     psa_status_t status;
90     int can_do_cipher;
91     const struct tfm_crypto_pack_iovec iov = {
92         .function_id = TFM_CRYPTO_CAN_DO_CIPHER_SID,
93         .alg = cipher_alg,
94     };
95     psa_invec in_vec[] = {
96         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
97         {.base = &key_type, .len = sizeof(psa_key_type_t)},
98     };
99     psa_outvec out_vec[] = {
100         {.base = &can_do_cipher, .len = sizeof(int)},
101     };
102 
103     status = API_DISPATCH(in_vec, out_vec);
104 
105     return (status != PSA_SUCCESS) ? 0 : can_do_cipher;
106 }
107 
TFM_CRYPTO_API(psa_status_t,psa_open_key)108 TFM_CRYPTO_API(psa_status_t, psa_open_key)(psa_key_id_t id,
109                                            psa_key_id_t *key)
110 {
111     const struct tfm_crypto_pack_iovec iov = {
112         .function_id = TFM_CRYPTO_OPEN_KEY_SID,
113         .key_id = id,
114     };
115     psa_invec in_vec[] = {
116         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
117     };
118     psa_outvec out_vec[] = {
119         {.base = key, .len = sizeof(psa_key_id_t)},
120     };
121 
122     return API_DISPATCH(in_vec, out_vec);
123 }
124 
TFM_CRYPTO_API(psa_status_t,psa_close_key)125 TFM_CRYPTO_API(psa_status_t, psa_close_key)(psa_key_id_t key)
126 {
127     const struct tfm_crypto_pack_iovec iov = {
128         .function_id = TFM_CRYPTO_CLOSE_KEY_SID,
129         .key_id = key,
130     };
131     psa_invec in_vec[] = {
132         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
133     };
134 
135     return API_DISPATCH_NO_OUTVEC(in_vec);
136 }
137 
TFM_CRYPTO_API(psa_status_t,psa_import_key)138 TFM_CRYPTO_API(psa_status_t, psa_import_key)(const psa_key_attributes_t *attributes,
139                                              const uint8_t *data,
140                                              size_t data_length,
141                                              psa_key_id_t *key)
142 {
143     struct tfm_crypto_pack_iovec iov = {
144         .function_id = TFM_CRYPTO_IMPORT_KEY_SID,
145     };
146     psa_invec in_vec[] = {
147         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
148         {.base = attributes, .len = sizeof(psa_key_attributes_t)},
149         {.base = data, .len = data_length}
150     };
151     psa_outvec out_vec[] = {
152         {.base = key, .len = sizeof(psa_key_id_t)}
153     };
154 
155     return API_DISPATCH(in_vec, out_vec);
156 }
157 
TFM_CRYPTO_API(psa_status_t,psa_destroy_key)158 TFM_CRYPTO_API(psa_status_t, psa_destroy_key)(psa_key_id_t key)
159 {
160     struct tfm_crypto_pack_iovec iov = {
161         .function_id = TFM_CRYPTO_DESTROY_KEY_SID,
162         .key_id = key,
163     };
164     psa_invec in_vec[] = {
165         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
166     };
167 
168     return API_DISPATCH_NO_OUTVEC(in_vec);
169 }
170 
TFM_CRYPTO_API(psa_status_t,psa_get_key_attributes)171 TFM_CRYPTO_API(psa_status_t, psa_get_key_attributes)(psa_key_id_t key,
172                                                      psa_key_attributes_t *attributes)
173 {
174     struct tfm_crypto_pack_iovec iov = {
175         .function_id = TFM_CRYPTO_GET_KEY_ATTRIBUTES_SID,
176         .key_id = key,
177     };
178     psa_invec in_vec[] = {
179         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
180     };
181     psa_outvec out_vec[] = {
182         {.base = attributes, .len = sizeof(psa_key_attributes_t)},
183     };
184 
185     return API_DISPATCH(in_vec, out_vec);
186 }
187 
TFM_CRYPTO_API(psa_status_t,psa_export_key)188 TFM_CRYPTO_API(psa_status_t, psa_export_key)(psa_key_id_t key,
189                                              uint8_t *data,
190                                              size_t data_size,
191                                              size_t *data_length)
192 {
193     psa_status_t status;
194     struct tfm_crypto_pack_iovec iov = {
195         .function_id = TFM_CRYPTO_EXPORT_KEY_SID,
196         .key_id = key,
197     };
198     psa_invec in_vec[] = {
199         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
200     };
201     psa_outvec out_vec[] = {
202         {.base = data, .len = data_size}
203     };
204 
205     status = API_DISPATCH(in_vec, out_vec);
206 
207     *data_length = out_vec[0].len;
208 
209     return status;
210 }
211 
TFM_CRYPTO_API(psa_status_t,psa_export_public_key)212 TFM_CRYPTO_API(psa_status_t, psa_export_public_key)(psa_key_id_t key,
213                                                     uint8_t *data,
214                                                     size_t data_size,
215                                                     size_t *data_length)
216 {
217     psa_status_t status;
218     struct tfm_crypto_pack_iovec iov = {
219         .function_id = TFM_CRYPTO_EXPORT_PUBLIC_KEY_SID,
220         .key_id = key,
221     };
222 
223     psa_invec in_vec[] = {
224         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
225     };
226     psa_outvec out_vec[] = {
227         {.base = data, .len = data_size}
228     };
229 
230     status = API_DISPATCH(in_vec, out_vec);
231 
232     *data_length = out_vec[0].len;
233 
234     return status;
235 }
236 
TFM_CRYPTO_API(psa_status_t,psa_purge_key)237 TFM_CRYPTO_API(psa_status_t, psa_purge_key)(psa_key_id_t key)
238 {
239     struct tfm_crypto_pack_iovec iov = {
240         .function_id = TFM_CRYPTO_PURGE_KEY_SID,
241         .key_id = key,
242     };
243     psa_invec in_vec[] = {
244         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
245     };
246 
247     return API_DISPATCH_NO_OUTVEC(in_vec);
248 }
249 
TFM_CRYPTO_API(psa_status_t,psa_copy_key)250 TFM_CRYPTO_API(psa_status_t, psa_copy_key)(psa_key_id_t source_key,
251                                            const psa_key_attributes_t *attributes,
252                                            psa_key_id_t *target_key)
253 {
254     struct tfm_crypto_pack_iovec iov = {
255         .function_id = TFM_CRYPTO_COPY_KEY_SID,
256         .key_id = source_key,
257     };
258 
259     psa_invec in_vec[] = {
260         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
261         {.base = attributes, .len = sizeof(psa_key_attributes_t)},
262     };
263 
264     psa_outvec out_vec[] = {
265         {.base = target_key, .len = sizeof(psa_key_id_t)},
266     };
267 
268     return API_DISPATCH(in_vec, out_vec);
269 }
270 
TFM_CRYPTO_API(psa_status_t,psa_cipher_generate_iv)271 TFM_CRYPTO_API(psa_status_t, psa_cipher_generate_iv)(psa_cipher_operation_t *operation,
272                                                      unsigned char *iv,
273                                                      size_t iv_size,
274                                                      size_t *iv_length)
275 {
276     psa_status_t status;
277     struct tfm_crypto_pack_iovec iov = {
278         .function_id = TFM_CRYPTO_CIPHER_GENERATE_IV_SID,
279         .op_handle = operation->handle,
280     };
281 
282     psa_invec in_vec[] = {
283         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
284     };
285     psa_outvec out_vec[] = {
286         {.base = iv, .len = iv_size},
287     };
288 
289     status = API_DISPATCH(in_vec, out_vec);
290 
291     *iv_length = out_vec[0].len;
292 
293     return status;
294 }
295 
TFM_CRYPTO_API(psa_status_t,psa_cipher_set_iv)296 TFM_CRYPTO_API(psa_status_t, psa_cipher_set_iv)(psa_cipher_operation_t *operation,
297                                                 const unsigned char *iv,
298                                                 size_t iv_length)
299 {
300     struct tfm_crypto_pack_iovec iov = {
301         .function_id = TFM_CRYPTO_CIPHER_SET_IV_SID,
302         .op_handle = operation->handle,
303     };
304 
305     psa_invec in_vec[] = {
306         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
307         {.base = iv, .len = iv_length},
308     };
309 
310     return API_DISPATCH_NO_OUTVEC(in_vec);
311 }
312 
TFM_CRYPTO_API(psa_status_t,psa_cipher_encrypt_setup)313 TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt_setup)(psa_cipher_operation_t *operation,
314                                                        psa_key_id_t key,
315                                                        psa_algorithm_t alg)
316 {
317     struct tfm_crypto_pack_iovec iov = {
318         .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SETUP_SID,
319         .key_id = key,
320         .alg = alg,
321         .op_handle = operation->handle,
322     };
323 
324     psa_invec in_vec[] = {
325         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
326     };
327     psa_outvec out_vec[] = {
328         {.base = &(operation->handle), .len = sizeof(uint32_t)},
329     };
330 
331     return API_DISPATCH(in_vec, out_vec);
332 }
333 
TFM_CRYPTO_API(psa_status_t,psa_cipher_decrypt_setup)334 TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt_setup)(psa_cipher_operation_t *operation,
335                                                        psa_key_id_t key,
336                                                        psa_algorithm_t alg)
337 {
338     struct tfm_crypto_pack_iovec iov = {
339         .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SETUP_SID,
340         .key_id = key,
341         .alg = alg,
342         .op_handle = operation->handle,
343     };
344 
345     psa_invec in_vec[] = {
346         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
347     };
348     psa_outvec out_vec[] = {
349         {.base = &(operation->handle), .len = sizeof(uint32_t)},
350     };
351 
352     return API_DISPATCH(in_vec, out_vec);
353 }
354 
TFM_CRYPTO_API(psa_status_t,psa_cipher_update)355 TFM_CRYPTO_API(psa_status_t, psa_cipher_update)(psa_cipher_operation_t *operation,
356                                                 const uint8_t *input,
357                                                 size_t input_length,
358                                                 unsigned char *output,
359                                                 size_t output_size,
360                                                 size_t *output_length)
361 {
362     psa_status_t status;
363     struct tfm_crypto_pack_iovec iov = {
364         .function_id = TFM_CRYPTO_CIPHER_UPDATE_SID,
365         .op_handle = operation->handle,
366     };
367 
368     psa_invec in_vec[] = {
369         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
370         {.base = input, .len = input_length},
371     };
372     psa_outvec out_vec[] = {
373         {.base = output, .len = output_size}
374     };
375 
376     status = API_DISPATCH(in_vec, out_vec);
377 
378     *output_length = out_vec[0].len;
379 
380     return status;
381 }
382 
TFM_CRYPTO_API(psa_status_t,psa_cipher_abort)383 TFM_CRYPTO_API(psa_status_t, psa_cipher_abort)(psa_cipher_operation_t *operation)
384 {
385     struct tfm_crypto_pack_iovec iov = {
386         .function_id = TFM_CRYPTO_CIPHER_ABORT_SID,
387         .op_handle = operation->handle,
388     };
389 
390     psa_invec in_vec[] = {
391         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
392     };
393     psa_outvec out_vec[] = {
394         {.base = &(operation->handle), .len = sizeof(uint32_t)},
395     };
396 
397     return API_DISPATCH(in_vec, out_vec);
398 }
399 
TFM_CRYPTO_API(psa_status_t,psa_cipher_finish)400 TFM_CRYPTO_API(psa_status_t, psa_cipher_finish)(psa_cipher_operation_t *operation,
401                                                 uint8_t *output,
402                                                 size_t output_size,
403                                                 size_t *output_length)
404 {
405     psa_status_t status;
406     struct tfm_crypto_pack_iovec iov = {
407         .function_id = TFM_CRYPTO_CIPHER_FINISH_SID,
408         .op_handle = operation->handle,
409     };
410 
411     psa_invec in_vec[] = {
412         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
413     };
414     psa_outvec out_vec[] = {
415         {.base = &(operation->handle), .len = sizeof(uint32_t)},
416         {.base = output, .len = output_size},
417     };
418 
419     status = API_DISPATCH(in_vec, out_vec);
420 
421     *output_length = out_vec[1].len;
422 
423     return status;
424 }
425 
TFM_CRYPTO_API(psa_status_t,psa_hash_setup)426 TFM_CRYPTO_API(psa_status_t, psa_hash_setup)(psa_hash_operation_t *operation,
427                                              psa_algorithm_t alg)
428 {
429     struct tfm_crypto_pack_iovec iov = {
430         .function_id = TFM_CRYPTO_HASH_SETUP_SID,
431         .alg = alg,
432         .op_handle = operation->handle,
433     };
434 
435     psa_invec in_vec[] = {
436         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
437     };
438     psa_outvec out_vec[] = {
439         {.base = &(operation->handle), .len = sizeof(uint32_t)},
440     };
441 
442     return API_DISPATCH(in_vec, out_vec);
443 }
444 
TFM_CRYPTO_API(psa_status_t,psa_hash_update)445 TFM_CRYPTO_API(psa_status_t, psa_hash_update)(psa_hash_operation_t *operation,
446                                               const uint8_t *input,
447                                               size_t input_length)
448 {
449     struct tfm_crypto_pack_iovec iov = {
450         .function_id = TFM_CRYPTO_HASH_UPDATE_SID,
451         .op_handle = operation->handle,
452     };
453 
454     psa_invec in_vec[] = {
455         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
456         {.base = input, .len = input_length},
457     };
458 
459     return API_DISPATCH_NO_OUTVEC(in_vec);
460 }
461 
TFM_CRYPTO_API(psa_status_t,psa_hash_finish)462 TFM_CRYPTO_API(psa_status_t, psa_hash_finish)(psa_hash_operation_t *operation,
463                                               uint8_t *hash,
464                                               size_t hash_size,
465                                               size_t *hash_length)
466 {
467     psa_status_t status;
468     struct tfm_crypto_pack_iovec iov = {
469         .function_id = TFM_CRYPTO_HASH_FINISH_SID,
470         .op_handle = operation->handle,
471     };
472 
473     psa_invec in_vec[] = {
474         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
475     };
476     psa_outvec out_vec[] = {
477         {.base = &(operation->handle), .len = sizeof(uint32_t)},
478         {.base = hash, .len = hash_size},
479     };
480 
481     status = API_DISPATCH(in_vec, out_vec);
482 
483     *hash_length = out_vec[1].len;
484 
485     return status;
486 }
487 
TFM_CRYPTO_API(psa_status_t,psa_hash_verify)488 TFM_CRYPTO_API(psa_status_t, psa_hash_verify)(psa_hash_operation_t *operation,
489                                               const uint8_t *hash,
490                                               size_t hash_length)
491 {
492     struct tfm_crypto_pack_iovec iov = {
493         .function_id = TFM_CRYPTO_HASH_VERIFY_SID,
494         .op_handle = operation->handle,
495     };
496 
497     psa_invec in_vec[] = {
498         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
499         {.base = hash, .len = hash_length},
500     };
501     psa_outvec out_vec[] = {
502         {.base = &(operation->handle), .len = sizeof(uint32_t)},
503     };
504 
505     return API_DISPATCH(in_vec, out_vec);
506 }
507 
TFM_CRYPTO_API(psa_status_t,psa_hash_abort)508 TFM_CRYPTO_API(psa_status_t, psa_hash_abort)(psa_hash_operation_t *operation)
509 {
510     struct tfm_crypto_pack_iovec iov = {
511         .function_id = TFM_CRYPTO_HASH_ABORT_SID,
512         .op_handle = operation->handle,
513     };
514 
515     psa_invec in_vec[] = {
516         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
517     };
518     psa_outvec out_vec[] = {
519         {.base = &(operation->handle), .len = sizeof(uint32_t)},
520     };
521 
522     return API_DISPATCH(in_vec, out_vec);
523 }
524 
TFM_CRYPTO_API(psa_status_t,psa_hash_clone)525 TFM_CRYPTO_API(psa_status_t, psa_hash_clone)(const psa_hash_operation_t *source_operation,
526                                              psa_hash_operation_t *target_operation)
527 {
528     struct tfm_crypto_pack_iovec iov = {
529         .function_id = TFM_CRYPTO_HASH_CLONE_SID,
530         .op_handle = source_operation->handle,
531     };
532 
533     if (target_operation && (target_operation->handle != 0)) {
534         return PSA_ERROR_BAD_STATE;
535     }
536 
537     psa_invec in_vec[] = {
538         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
539         {.base = &(target_operation->handle),
540          .len = sizeof(target_operation->handle)},
541     };
542     psa_outvec out_vec[] = {
543         {.base = &(target_operation->handle),
544          .len = sizeof(target_operation->handle)},
545     };
546 
547     return API_DISPATCH(in_vec, out_vec);
548 }
549 
TFM_CRYPTO_API(psa_status_t,psa_hash_compute)550 TFM_CRYPTO_API(psa_status_t, psa_hash_compute)(psa_algorithm_t alg,
551                                                const uint8_t *input,
552                                                size_t input_length,
553                                                uint8_t *hash,
554                                                size_t hash_size,
555                                                size_t *hash_length)
556 {
557     psa_status_t status;
558     struct tfm_crypto_pack_iovec iov = {
559         .function_id = TFM_CRYPTO_HASH_COMPUTE_SID,
560         .alg = alg,
561     };
562 
563     psa_invec in_vec[] = {
564         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
565         {.base = input, .len = input_length},
566     };
567 
568     psa_outvec out_vec[] = {
569         {.base = hash, .len = hash_size}
570     };
571 
572     status = API_DISPATCH(in_vec, out_vec);
573 
574     *hash_length = out_vec[0].len;
575 
576     return status;
577 }
578 
TFM_CRYPTO_API(psa_status_t,psa_hash_compare)579 TFM_CRYPTO_API(psa_status_t, psa_hash_compare)(psa_algorithm_t alg,
580                                                const uint8_t *input,
581                                                size_t input_length,
582                                                const uint8_t *hash,
583                                                size_t hash_length)
584 {
585     struct tfm_crypto_pack_iovec iov = {
586         .function_id = TFM_CRYPTO_HASH_COMPARE_SID,
587         .alg = alg,
588     };
589 
590     psa_invec in_vec[] = {
591         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
592         {.base = input, .len = input_length},
593         {.base = hash, .len = hash_length},
594     };
595 
596     return API_DISPATCH_NO_OUTVEC(in_vec);
597 }
598 
TFM_CRYPTO_API(psa_status_t,psa_mac_sign_setup)599 TFM_CRYPTO_API(psa_status_t, psa_mac_sign_setup)(psa_mac_operation_t *operation,
600                                                  psa_key_id_t key,
601                                                  psa_algorithm_t alg)
602 {
603     struct tfm_crypto_pack_iovec iov = {
604         .function_id = TFM_CRYPTO_MAC_SIGN_SETUP_SID,
605         .key_id = key,
606         .alg = alg,
607         .op_handle = operation->handle,
608     };
609 
610     psa_invec in_vec[] = {
611         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
612     };
613     psa_outvec out_vec[] = {
614         {.base = &(operation->handle), .len = sizeof(uint32_t)},
615     };
616 
617     return API_DISPATCH(in_vec, out_vec);
618 }
619 
TFM_CRYPTO_API(psa_status_t,psa_mac_verify_setup)620 TFM_CRYPTO_API(psa_status_t, psa_mac_verify_setup)(psa_mac_operation_t *operation,
621                                                    psa_key_id_t key,
622                                                    psa_algorithm_t alg)
623 {
624     struct tfm_crypto_pack_iovec iov = {
625         .function_id = TFM_CRYPTO_MAC_VERIFY_SETUP_SID,
626         .key_id = key,
627         .alg = alg,
628         .op_handle = operation->handle,
629     };
630 
631     psa_invec in_vec[] = {
632         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
633     };
634     psa_outvec out_vec[] = {
635         {.base = &(operation->handle), .len = sizeof(uint32_t)},
636     };
637 
638     return API_DISPATCH(in_vec, out_vec);
639 }
640 
TFM_CRYPTO_API(psa_status_t,psa_mac_update)641 TFM_CRYPTO_API(psa_status_t, psa_mac_update)(psa_mac_operation_t *operation,
642                                              const uint8_t *input,
643                                              size_t input_length)
644 {
645     struct tfm_crypto_pack_iovec iov = {
646         .function_id = TFM_CRYPTO_MAC_UPDATE_SID,
647         .op_handle = operation->handle,
648     };
649 
650     psa_invec in_vec[] = {
651         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
652         {.base = input, .len = input_length},
653     };
654 
655     return API_DISPATCH_NO_OUTVEC(in_vec);
656 }
657 
TFM_CRYPTO_API(psa_status_t,psa_mac_sign_finish)658 TFM_CRYPTO_API(psa_status_t, psa_mac_sign_finish)(psa_mac_operation_t *operation,
659                                                   uint8_t *mac,
660                                                   size_t mac_size,
661                                                   size_t *mac_length)
662 {
663     psa_status_t status;
664     struct tfm_crypto_pack_iovec iov = {
665         .function_id = TFM_CRYPTO_MAC_SIGN_FINISH_SID,
666         .op_handle = operation->handle,
667     };
668 
669     psa_invec in_vec[] = {
670         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
671     };
672     psa_outvec out_vec[] = {
673         {.base = &(operation->handle), .len = sizeof(uint32_t)},
674         {.base = mac, .len = mac_size},
675     };
676 
677     status = API_DISPATCH(in_vec, out_vec);
678 
679     *mac_length = out_vec[1].len;
680 
681     return status;
682 }
683 
TFM_CRYPTO_API(psa_status_t,psa_mac_verify_finish)684 TFM_CRYPTO_API(psa_status_t, psa_mac_verify_finish)(psa_mac_operation_t *operation,
685                                                     const uint8_t *mac,
686                                                     size_t mac_length)
687 {
688     struct tfm_crypto_pack_iovec iov = {
689         .function_id = TFM_CRYPTO_MAC_VERIFY_FINISH_SID,
690         .op_handle = operation->handle,
691     };
692 
693     psa_invec in_vec[] = {
694         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
695         {.base = mac, .len = mac_length},
696     };
697     psa_outvec out_vec[] = {
698         {.base = &(operation->handle), .len = sizeof(uint32_t)},
699     };
700 
701     return API_DISPATCH(in_vec, out_vec);
702 }
703 
TFM_CRYPTO_API(psa_status_t,psa_mac_abort)704 TFM_CRYPTO_API(psa_status_t, psa_mac_abort)(psa_mac_operation_t *operation)
705 {
706     struct tfm_crypto_pack_iovec iov = {
707         .function_id = TFM_CRYPTO_MAC_ABORT_SID,
708         .op_handle = operation->handle,
709     };
710 
711     psa_invec in_vec[] = {
712         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
713     };
714     psa_outvec out_vec[] = {
715         {.base = &(operation->handle), .len = sizeof(uint32_t)},
716     };
717 
718     return API_DISPATCH(in_vec, out_vec);
719 }
720 
TFM_CRYPTO_API(psa_status_t,psa_aead_encrypt)721 TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt)(psa_key_id_t key,
722                                                psa_algorithm_t alg,
723                                                const uint8_t *nonce,
724                                                size_t nonce_length,
725                                                const uint8_t *additional_data,
726                                                size_t additional_data_length,
727                                                const uint8_t *plaintext,
728                                                size_t plaintext_length,
729                                                uint8_t *ciphertext,
730                                                size_t ciphertext_size,
731                                                size_t *ciphertext_length)
732 {
733     psa_status_t status;
734     struct tfm_crypto_pack_iovec iov = {
735         .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SID,
736         .key_id = key,
737         .alg = alg,
738         .aead_in = {.nonce = {0}, .nonce_length = 0}
739     };
740 
741     /* Sanitize the optional input */
742     if ((additional_data == NULL) && (additional_data_length != 0)) {
743         return PSA_ERROR_INVALID_ARGUMENT;
744     }
745 
746     psa_invec in_vec[] = {
747         {.base = NULL, .len = 0},
748         {.base = plaintext, .len = plaintext_length},
749         {.base = additional_data, .len = additional_data_length},
750     };
751     psa_outvec out_vec[] = {
752         {.base = ciphertext, .len = ciphertext_size},
753     };
754 
755     if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
756         return PSA_ERROR_INVALID_ARGUMENT;
757     }
758 
759     if (nonce != NULL) {
760         for (size_t idx = 0; idx < nonce_length; idx++) {
761             iov.aead_in.nonce[idx] = nonce[idx];
762         }
763         iov.aead_in.nonce_length = nonce_length;
764     }
765 
766     in_vec[0].base = &iov;
767     in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
768 
769     size_t in_len = IOVEC_LEN(in_vec);
770 
771     if (additional_data == NULL) {
772         in_len--;
773     }
774     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
775                       out_vec, IOVEC_LEN(out_vec));
776 
777     *ciphertext_length = out_vec[0].len;
778 
779     return status;
780 }
781 
TFM_CRYPTO_API(psa_status_t,psa_aead_decrypt)782 TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt)(psa_key_id_t key,
783                                                psa_algorithm_t alg,
784                                                const uint8_t *nonce,
785                                                size_t nonce_length,
786                                                const uint8_t *additional_data,
787                                                size_t additional_data_length,
788                                                const uint8_t *ciphertext,
789                                                size_t ciphertext_length,
790                                                uint8_t *plaintext,
791                                                size_t plaintext_size,
792                                                size_t *plaintext_length)
793 {
794     psa_status_t status;
795     struct tfm_crypto_pack_iovec iov = {
796         .function_id = TFM_CRYPTO_AEAD_DECRYPT_SID,
797         .key_id = key,
798         .alg = alg,
799         .aead_in = {.nonce = {0}, .nonce_length = 0}
800     };
801 
802     /* Sanitize the optional input */
803     if ((additional_data == NULL) && (additional_data_length != 0)) {
804         return PSA_ERROR_INVALID_ARGUMENT;
805     }
806 
807     psa_invec in_vec[] = {
808         {.base = NULL, .len = 0},
809         {.base = ciphertext, .len = ciphertext_length},
810         {.base = additional_data, .len = additional_data_length},
811     };
812     psa_outvec out_vec[] = {
813         {.base = plaintext, .len = plaintext_size},
814     };
815 
816     if (nonce_length > TFM_CRYPTO_MAX_NONCE_LENGTH) {
817         return PSA_ERROR_INVALID_ARGUMENT;
818     }
819 
820     if (nonce != NULL) {
821         for (size_t idx = 0; idx < nonce_length; idx++) {
822             iov.aead_in.nonce[idx] = nonce[idx];
823         }
824         iov.aead_in.nonce_length = nonce_length;
825     }
826 
827     in_vec[0].base = &iov;
828     in_vec[0].len = sizeof(struct tfm_crypto_pack_iovec);
829 
830     size_t in_len = IOVEC_LEN(in_vec);
831 
832     if (additional_data == NULL) {
833         in_len--;
834     }
835     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
836                       out_vec, IOVEC_LEN(out_vec));
837 
838     *plaintext_length = out_vec[0].len;
839 
840     return status;
841 }
842 
TFM_CRYPTO_API(psa_status_t,psa_aead_encrypt_setup)843 TFM_CRYPTO_API(psa_status_t, psa_aead_encrypt_setup)(psa_aead_operation_t *operation,
844                                                      psa_key_id_t key,
845                                                      psa_algorithm_t alg)
846 {
847     psa_status_t status;
848     struct tfm_crypto_pack_iovec iov = {
849         .function_id = TFM_CRYPTO_AEAD_ENCRYPT_SETUP_SID,
850         .key_id = key,
851         .alg = alg,
852         .op_handle = operation->handle,
853     };
854 
855     psa_invec in_vec[] = {
856         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
857     };
858     psa_outvec out_vec[] = {
859         {.base = &(operation->handle), .len = sizeof(uint32_t)}
860     };
861 
862     status = API_DISPATCH(in_vec, out_vec);
863     return status;
864 }
865 
TFM_CRYPTO_API(psa_status_t,psa_aead_decrypt_setup)866 TFM_CRYPTO_API(psa_status_t, psa_aead_decrypt_setup)(psa_aead_operation_t *operation,
867                                                      psa_key_id_t key,
868                                                      psa_algorithm_t alg)
869 {
870     psa_status_t status;
871     struct tfm_crypto_pack_iovec iov = {
872         .function_id = TFM_CRYPTO_AEAD_DECRYPT_SETUP_SID,
873         .key_id = key,
874         .alg = alg,
875         .op_handle = operation->handle,
876     };
877 
878     psa_invec in_vec[] = {
879         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)}
880     };
881     psa_outvec out_vec[] = {
882         {.base = &(operation->handle), .len = sizeof(uint32_t)}
883     };
884 
885     status = API_DISPATCH(in_vec, out_vec);
886     return status;
887 }
888 
TFM_CRYPTO_API(psa_status_t,psa_aead_generate_nonce)889 TFM_CRYPTO_API(psa_status_t, psa_aead_generate_nonce)(psa_aead_operation_t *operation,
890                                                       uint8_t *nonce,
891                                                       size_t nonce_size,
892                                                       size_t *nonce_length)
893 {
894     psa_status_t status;
895     struct tfm_crypto_pack_iovec iov = {
896         .function_id = TFM_CRYPTO_AEAD_GENERATE_NONCE_SID,
897         .op_handle = operation->handle,
898     };
899 
900     psa_invec in_vec[] = {
901         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
902     };
903     psa_outvec out_vec[] = {
904         {.base = nonce, .len = nonce_size}
905     };
906 
907     status = API_DISPATCH(in_vec, out_vec);
908 
909     *nonce_length = out_vec[0].len;
910     return status;
911 }
912 
TFM_CRYPTO_API(psa_status_t,psa_aead_set_nonce)913 TFM_CRYPTO_API(psa_status_t, psa_aead_set_nonce)(psa_aead_operation_t *operation,
914                                                  const uint8_t *nonce,
915                                                  size_t nonce_length)
916 {
917     psa_status_t status;
918     struct tfm_crypto_pack_iovec iov = {
919         .function_id = TFM_CRYPTO_AEAD_SET_NONCE_SID,
920         .op_handle = operation->handle,
921     };
922 
923     psa_invec in_vec[] = {
924         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
925         {.base = nonce, .len = nonce_length}
926     };
927 
928     status = API_DISPATCH_NO_OUTVEC(in_vec);
929     return status;
930 }
931 
TFM_CRYPTO_API(psa_status_t,psa_aead_set_lengths)932 TFM_CRYPTO_API(psa_status_t, psa_aead_set_lengths)(psa_aead_operation_t *operation,
933                                                    size_t ad_length,
934                                                    size_t plaintext_length)
935 {
936     psa_status_t status;
937     struct tfm_crypto_pack_iovec iov = {
938         .function_id = TFM_CRYPTO_AEAD_SET_LENGTHS_SID,
939         .ad_length = ad_length,
940         .plaintext_length = plaintext_length,
941         .op_handle = operation->handle,
942     };
943 
944     psa_invec in_vec[] = {
945         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
946     };
947 
948     status = API_DISPATCH_NO_OUTVEC(in_vec);
949     return status;
950 }
951 
TFM_CRYPTO_API(psa_status_t,psa_aead_update_ad)952 TFM_CRYPTO_API(psa_status_t, psa_aead_update_ad)(psa_aead_operation_t *operation,
953                                                  const uint8_t *input,
954                                                  size_t input_length)
955 {
956     psa_status_t status;
957     struct tfm_crypto_pack_iovec iov = {
958         .function_id = TFM_CRYPTO_AEAD_UPDATE_AD_SID,
959         .op_handle = operation->handle,
960     };
961 
962     /* Sanitize the optional input */
963     if ((input == NULL) && (input_length != 0)) {
964         return PSA_ERROR_INVALID_ARGUMENT;
965     }
966 
967     psa_invec in_vec[] = {
968         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
969         {.base = input, .len = input_length}
970     };
971 
972     size_t in_len = IOVEC_LEN(in_vec);
973 
974     if (input == NULL) {
975         in_len--;
976     }
977     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
978                       NULL, 0);
979     return status;
980 }
981 
TFM_CRYPTO_API(psa_status_t,psa_aead_update)982 TFM_CRYPTO_API(psa_status_t, psa_aead_update)(psa_aead_operation_t *operation,
983                                               const uint8_t *input,
984                                               size_t input_length,
985                                               uint8_t *output,
986                                               size_t output_size,
987                                               size_t *output_length)
988 {
989     psa_status_t status;
990     struct tfm_crypto_pack_iovec iov = {
991         .function_id = TFM_CRYPTO_AEAD_UPDATE_SID,
992         .op_handle = operation->handle,
993     };
994 
995     /* Sanitize the optional input */
996     if ((input == NULL) && (input_length != 0)) {
997         return PSA_ERROR_INVALID_ARGUMENT;
998     }
999 
1000     psa_invec in_vec[] = {
1001         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1002         {.base = input, .len = input_length}
1003     };
1004     psa_outvec out_vec[] = {
1005         {.base = output, .len = output_size},
1006     };
1007 
1008     size_t in_len = IOVEC_LEN(in_vec);
1009 
1010     if (input == NULL) {
1011         in_len--;
1012     }
1013     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
1014                       out_vec, IOVEC_LEN(out_vec));
1015 
1016     *output_length = out_vec[0].len;
1017     return status;
1018 }
1019 
TFM_CRYPTO_API(psa_status_t,psa_aead_finish)1020 TFM_CRYPTO_API(psa_status_t, psa_aead_finish)(psa_aead_operation_t *operation,
1021                                               uint8_t *ciphertext,
1022                                               size_t ciphertext_size,
1023                                               size_t *ciphertext_length,
1024                                               uint8_t *tag,
1025                                               size_t tag_size,
1026                                               size_t *tag_length)
1027 {
1028     psa_status_t status;
1029     struct tfm_crypto_pack_iovec iov = {
1030         .function_id = TFM_CRYPTO_AEAD_FINISH_SID,
1031         .op_handle = operation->handle,
1032     };
1033 
1034     /* Sanitize the optional output */
1035     if ((ciphertext == NULL) && (ciphertext_size != 0)) {
1036         return PSA_ERROR_INVALID_ARGUMENT;
1037     }
1038 
1039     psa_invec in_vec[] = {
1040         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1041     };
1042     psa_outvec out_vec[] = {
1043         {.base = &(operation->handle), .len = sizeof(uint32_t)},
1044         {.base = tag, .len = tag_size},
1045         {.base = ciphertext, .len = ciphertext_size}
1046     };
1047 
1048     size_t out_len = IOVEC_LEN(out_vec);
1049 
1050     if ((ciphertext == NULL) || (ciphertext_size == 0)) {
1051         out_len--;
1052     }
1053     if ((out_len == 3) && (ciphertext_length == NULL)) {
1054         return PSA_ERROR_INVALID_ARGUMENT;
1055     }
1056 
1057     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
1058                       in_vec, IOVEC_LEN(in_vec),
1059                       out_vec, out_len);
1060 
1061     if (out_len == 3) {
1062         *ciphertext_length = out_vec[2].len;
1063     } else {
1064         *ciphertext_length = 0;
1065     }
1066 
1067     *tag_length = out_vec[1].len;
1068 
1069     return status;
1070 }
1071 
TFM_CRYPTO_API(psa_status_t,psa_aead_verify)1072 TFM_CRYPTO_API(psa_status_t, psa_aead_verify)(psa_aead_operation_t *operation,
1073                                               uint8_t *plaintext,
1074                                               size_t plaintext_size,
1075                                               size_t *plaintext_length,
1076                                               const uint8_t *tag,
1077                                               size_t tag_length)
1078 {
1079     psa_status_t status;
1080     struct tfm_crypto_pack_iovec iov = {
1081         .function_id = TFM_CRYPTO_AEAD_VERIFY_SID,
1082         .op_handle = operation->handle,
1083     };
1084 
1085     /* Sanitize the optional output */
1086     if ((plaintext == NULL) && (plaintext_size != 0)) {
1087         return PSA_ERROR_INVALID_ARGUMENT;
1088     }
1089 
1090     psa_invec in_vec[] = {
1091         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1092         {.base = tag, .len = tag_length}
1093     };
1094     psa_outvec out_vec[] = {
1095         {.base = &(operation->handle), .len = sizeof(uint32_t)},
1096         {.base = plaintext, .len = plaintext_size}
1097     };
1098 
1099     size_t out_len = IOVEC_LEN(out_vec);
1100 
1101     if ((plaintext == NULL) || (plaintext_size == 0)) {
1102         out_len--;
1103     }
1104     if ((out_len == 2) && (plaintext_length == NULL)) {
1105         return PSA_ERROR_INVALID_ARGUMENT;
1106     }
1107 
1108     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL,
1109                       in_vec, IOVEC_LEN(in_vec),
1110                       out_vec, out_len);
1111 
1112     if (out_len == 2) {
1113         *plaintext_length = out_vec[1].len;
1114     } else {
1115         *plaintext_length = 0;
1116     }
1117     return status;
1118 }
1119 
TFM_CRYPTO_API(psa_status_t,psa_aead_abort)1120 TFM_CRYPTO_API(psa_status_t, psa_aead_abort)(psa_aead_operation_t *operation)
1121 {
1122     struct tfm_crypto_pack_iovec iov = {
1123         .function_id = TFM_CRYPTO_AEAD_ABORT_SID,
1124         .op_handle = operation->handle,
1125     };
1126 
1127     psa_invec in_vec[] = {
1128         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1129     };
1130     psa_outvec out_vec[] = {
1131         {.base = &(operation->handle), .len = sizeof(uint32_t)},
1132     };
1133 
1134     return API_DISPATCH(in_vec, out_vec);
1135 }
1136 
TFM_CRYPTO_API(psa_status_t,psa_sign_message)1137 TFM_CRYPTO_API(psa_status_t, psa_sign_message)(psa_key_id_t key,
1138                                                psa_algorithm_t alg,
1139                                                const uint8_t *input,
1140                                                size_t input_length,
1141                                                uint8_t *signature,
1142                                                size_t signature_size,
1143                                                size_t *signature_length)
1144 {
1145     psa_status_t status;
1146     struct tfm_crypto_pack_iovec iov = {
1147         .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_MESSAGE_SID,
1148         .key_id = key,
1149         .alg = alg,
1150     };
1151 
1152     psa_invec in_vec[] = {
1153         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1154         {.base = input, .len = input_length},
1155     };
1156     psa_outvec out_vec[] = {
1157         {.base = signature, .len = signature_size},
1158     };
1159 
1160     status = API_DISPATCH(in_vec, out_vec);
1161 
1162     *signature_length = out_vec[0].len;
1163     return status;
1164 }
1165 
TFM_CRYPTO_API(psa_status_t,psa_verify_message)1166 TFM_CRYPTO_API(psa_status_t, psa_verify_message)(psa_key_id_t key,
1167                                                  psa_algorithm_t alg,
1168                                                  const uint8_t *input,
1169                                                  size_t input_length,
1170                                                  const uint8_t *signature,
1171                                                  size_t signature_length)
1172 {
1173     struct tfm_crypto_pack_iovec iov = {
1174         .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_MESSAGE_SID,
1175         .key_id = key,
1176         .alg = alg
1177     };
1178 
1179     psa_invec in_vec[] = {
1180         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1181         {.base = input, .len = input_length},
1182         {.base = signature, .len = signature_length}
1183     };
1184 
1185     return API_DISPATCH_NO_OUTVEC(in_vec);
1186 }
1187 
TFM_CRYPTO_API(psa_status_t,psa_sign_hash)1188 TFM_CRYPTO_API(psa_status_t, psa_sign_hash)(psa_key_id_t key,
1189                                             psa_algorithm_t alg,
1190                                             const uint8_t *hash,
1191                                             size_t hash_length,
1192                                             uint8_t *signature,
1193                                             size_t signature_size,
1194                                             size_t *signature_length)
1195 {
1196     psa_status_t status;
1197     struct tfm_crypto_pack_iovec iov = {
1198         .function_id = TFM_CRYPTO_ASYMMETRIC_SIGN_HASH_SID,
1199         .key_id = key,
1200         .alg = alg,
1201     };
1202 
1203     psa_invec in_vec[] = {
1204         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1205         {.base = hash, .len = hash_length},
1206     };
1207     psa_outvec out_vec[] = {
1208         {.base = signature, .len = signature_size},
1209     };
1210 
1211     status = API_DISPATCH(in_vec, out_vec);
1212 
1213     *signature_length = out_vec[0].len;
1214 
1215     return status;
1216 }
1217 
TFM_CRYPTO_API(psa_status_t,psa_verify_hash)1218 TFM_CRYPTO_API(psa_status_t, psa_verify_hash)(psa_key_id_t key,
1219                                               psa_algorithm_t alg,
1220                                               const uint8_t *hash,
1221                                               size_t hash_length,
1222                                               const uint8_t *signature,
1223                                               size_t signature_length)
1224 {
1225     struct tfm_crypto_pack_iovec iov = {
1226         .function_id = TFM_CRYPTO_ASYMMETRIC_VERIFY_HASH_SID,
1227         .key_id = key,
1228         .alg = alg
1229     };
1230 
1231     psa_invec in_vec[] = {
1232         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1233         {.base = hash, .len = hash_length},
1234         {.base = signature, .len = signature_length}
1235     };
1236 
1237     return API_DISPATCH_NO_OUTVEC(in_vec);
1238 }
1239 
TFM_CRYPTO_API(psa_status_t,psa_asymmetric_encrypt)1240 TFM_CRYPTO_API(psa_status_t, psa_asymmetric_encrypt)(psa_key_id_t key,
1241                                                      psa_algorithm_t alg,
1242                                                      const uint8_t *input,
1243                                                      size_t input_length,
1244                                                      const uint8_t *salt,
1245                                                      size_t salt_length,
1246                                                      uint8_t *output,
1247                                                      size_t output_size,
1248                                                      size_t *output_length)
1249 {
1250     psa_status_t status;
1251     struct tfm_crypto_pack_iovec iov = {
1252         .function_id = TFM_CRYPTO_ASYMMETRIC_ENCRYPT_SID,
1253         .key_id = key,
1254         .alg = alg
1255     };
1256 
1257     /* Sanitize the optional input */
1258     if ((salt == NULL) && (salt_length != 0)) {
1259         return PSA_ERROR_INVALID_ARGUMENT;
1260     }
1261 
1262     psa_invec in_vec[] = {
1263         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1264         {.base = input, .len = input_length},
1265         {.base = salt, .len = salt_length}
1266     };
1267 
1268     psa_outvec out_vec[] = {
1269         {.base = output, .len = output_size},
1270     };
1271 
1272     size_t in_len = IOVEC_LEN(in_vec);
1273 
1274     if (salt == NULL) {
1275         in_len--;
1276     }
1277     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
1278                       out_vec, IOVEC_LEN(out_vec));
1279 
1280     *output_length = out_vec[0].len;
1281 
1282     return status;
1283 }
1284 
TFM_CRYPTO_API(psa_status_t,psa_asymmetric_decrypt)1285 TFM_CRYPTO_API(psa_status_t, psa_asymmetric_decrypt)(psa_key_id_t key,
1286                                                      psa_algorithm_t alg,
1287                                                      const uint8_t *input,
1288                                                      size_t input_length,
1289                                                      const uint8_t *salt,
1290                                                      size_t salt_length,
1291                                                      uint8_t *output,
1292                                                      size_t output_size,
1293                                                      size_t *output_length)
1294 {
1295     psa_status_t status;
1296     struct tfm_crypto_pack_iovec iov = {
1297         .function_id = TFM_CRYPTO_ASYMMETRIC_DECRYPT_SID,
1298         .key_id = key,
1299         .alg = alg
1300     };
1301 
1302     /* Sanitize the optional input */
1303     if ((salt == NULL) && (salt_length != 0)) {
1304         return PSA_ERROR_INVALID_ARGUMENT;
1305     }
1306 
1307     psa_invec in_vec[] = {
1308         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1309         {.base = input, .len = input_length},
1310         {.base = salt, .len = salt_length}
1311     };
1312 
1313     psa_outvec out_vec[] = {
1314         {.base = output, .len = output_size},
1315     };
1316 
1317     size_t in_len = IOVEC_LEN(in_vec);
1318 
1319     if (salt == NULL) {
1320         in_len--;
1321     }
1322     status = psa_call(TFM_CRYPTO_HANDLE, PSA_IPC_CALL, in_vec, in_len,
1323                       out_vec, IOVEC_LEN(out_vec));
1324 
1325     *output_length = out_vec[0].len;
1326 
1327     return status;
1328 }
1329 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_get_capacity)1330 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_get_capacity)(
1331                                 const psa_key_derivation_operation_t *operation,
1332                                 size_t *capacity)
1333 {
1334     struct tfm_crypto_pack_iovec iov = {
1335         .function_id = TFM_CRYPTO_KEY_DERIVATION_GET_CAPACITY_SID,
1336         .op_handle = operation->handle,
1337     };
1338 
1339     psa_invec in_vec[] = {
1340         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1341     };
1342 
1343     psa_outvec out_vec[] = {
1344         {.base = capacity, .len = sizeof(size_t)},
1345     };
1346 
1347     return API_DISPATCH(in_vec, out_vec);
1348 }
1349 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_output_bytes)1350 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_bytes)(
1351                                       psa_key_derivation_operation_t *operation,
1352                                       uint8_t *output,
1353                                       size_t output_length)
1354 {
1355     struct tfm_crypto_pack_iovec iov = {
1356         .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_BYTES_SID,
1357         .op_handle = operation->handle,
1358     };
1359 
1360     psa_invec in_vec[] = {
1361         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1362     };
1363 
1364     psa_outvec out_vec[] = {
1365         {.base = output, .len = output_length},
1366     };
1367 
1368     return API_DISPATCH(in_vec, out_vec);
1369 }
1370 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_input_key)1371 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_key)(
1372                                       psa_key_derivation_operation_t *operation,
1373                                       psa_key_derivation_step_t step,
1374                                       psa_key_id_t key)
1375 {
1376     struct tfm_crypto_pack_iovec iov = {
1377         .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_KEY_SID,
1378         .key_id = key,
1379         .step = step,
1380         .op_handle = operation->handle,
1381     };
1382 
1383     psa_invec in_vec[] = {
1384         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1385     };
1386 
1387     return API_DISPATCH_NO_OUTVEC(in_vec);
1388 }
1389 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_abort)1390 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_abort)(psa_key_derivation_operation_t *operation)
1391 {
1392     struct tfm_crypto_pack_iovec iov = {
1393         .function_id = TFM_CRYPTO_KEY_DERIVATION_ABORT_SID,
1394         .op_handle = operation->handle,
1395     };
1396 
1397     psa_invec in_vec[] = {
1398         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1399     };
1400 
1401     psa_outvec out_vec[] = {
1402         {.base = &(operation->handle), .len = sizeof(uint32_t)},
1403     };
1404 
1405     return API_DISPATCH(in_vec, out_vec);
1406 }
1407 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_key_agreement)1408 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_key_agreement)(
1409                                       psa_key_derivation_operation_t *operation,
1410                                       psa_key_derivation_step_t step,
1411                                       psa_key_id_t private_key,
1412                                       const uint8_t *peer_key,
1413                                       size_t peer_key_length)
1414 {
1415     struct tfm_crypto_pack_iovec iov = {
1416         .function_id = TFM_CRYPTO_KEY_DERIVATION_KEY_AGREEMENT_SID,
1417         .key_id = private_key,
1418         .step = step,
1419         .op_handle = operation->handle,
1420     };
1421 
1422     psa_invec in_vec[] = {
1423         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1424         {.base = peer_key, .len = peer_key_length},
1425     };
1426 
1427     return API_DISPATCH_NO_OUTVEC(in_vec);
1428 }
1429 
TFM_CRYPTO_API(psa_status_t,psa_generate_random)1430 TFM_CRYPTO_API(psa_status_t, psa_generate_random)(uint8_t *output,
1431                                                   size_t output_size)
1432 {
1433     struct tfm_crypto_pack_iovec iov = {
1434         .function_id = TFM_CRYPTO_GENERATE_RANDOM_SID,
1435     };
1436 
1437     psa_invec in_vec[] = {
1438         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1439     };
1440 
1441     psa_outvec out_vec[] = {
1442         {.base = output, .len = output_size},
1443     };
1444 
1445     if (output_size == 0) {
1446         return PSA_SUCCESS;
1447     }
1448 
1449     return API_DISPATCH(in_vec, out_vec);
1450 }
1451 
TFM_CRYPTO_API(psa_status_t,psa_generate_key)1452 TFM_CRYPTO_API(psa_status_t, psa_generate_key)(const psa_key_attributes_t *attributes,
1453                                                psa_key_id_t *key)
1454 {
1455     struct tfm_crypto_pack_iovec iov = {
1456         .function_id = TFM_CRYPTO_GENERATE_KEY_SID,
1457     };
1458 
1459     psa_invec in_vec[] = {
1460         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1461         {.base = attributes, .len = sizeof(psa_key_attributes_t)},
1462     };
1463 
1464     psa_outvec out_vec[] = {
1465         {.base = key, .len = sizeof(psa_key_id_t)},
1466     };
1467 
1468     return API_DISPATCH(in_vec, out_vec);
1469 }
1470 
TFM_CRYPTO_API(psa_status_t,psa_mac_compute)1471 TFM_CRYPTO_API(psa_status_t, psa_mac_compute)(psa_key_id_t key,
1472                                               psa_algorithm_t alg,
1473                                               const uint8_t *input,
1474                                               size_t input_length,
1475                                               uint8_t *mac,
1476                                               size_t mac_size,
1477                                               size_t *mac_length)
1478 {
1479     psa_status_t status;
1480     struct tfm_crypto_pack_iovec iov = {
1481         .function_id = TFM_CRYPTO_MAC_COMPUTE_SID,
1482         .key_id = key,
1483         .alg = alg,
1484     };
1485 
1486     psa_invec in_vec[] = {
1487         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1488         {.base = input, .len = input_length},
1489     };
1490     psa_outvec out_vec[] = {
1491         {.base = mac, .len = mac_size},
1492     };
1493 
1494     status = API_DISPATCH(in_vec, out_vec);
1495 
1496     *mac_length = out_vec[0].len;
1497     return status;
1498 }
1499 
TFM_CRYPTO_API(psa_status_t,psa_mac_verify)1500 TFM_CRYPTO_API(psa_status_t, psa_mac_verify)(psa_key_id_t key,
1501                                              psa_algorithm_t alg,
1502                                              const uint8_t *input,
1503                                              size_t input_length,
1504                                              const uint8_t *mac,
1505                                              const size_t mac_length)
1506 {
1507     struct tfm_crypto_pack_iovec iov = {
1508         .function_id = TFM_CRYPTO_MAC_VERIFY_SID,
1509         .key_id = key,
1510         .alg = alg,
1511     };
1512 
1513     psa_invec in_vec[] = {
1514         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1515         {.base = input, .len = input_length},
1516         {.base = mac, .len = mac_length},
1517     };
1518 
1519     return API_DISPATCH_NO_OUTVEC(in_vec);
1520 }
1521 
TFM_CRYPTO_API(psa_status_t,psa_cipher_encrypt)1522 TFM_CRYPTO_API(psa_status_t, psa_cipher_encrypt)(psa_key_id_t key,
1523                                                  psa_algorithm_t alg,
1524                                                  const uint8_t *input,
1525                                                  size_t input_length,
1526                                                  uint8_t *output,
1527                                                  size_t output_size,
1528                                                  size_t *output_length)
1529 {
1530     psa_status_t status;
1531     struct tfm_crypto_pack_iovec iov = {
1532         .function_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
1533         .key_id = key,
1534         .alg = alg,
1535     };
1536 
1537     psa_invec in_vec[] = {
1538         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1539         {.base = input, .len = input_length},
1540     };
1541     psa_outvec out_vec[] = {
1542         {.base = output, .len = output_size}
1543     };
1544 
1545     status = API_DISPATCH(in_vec, out_vec);
1546 
1547     *output_length = out_vec[0].len;
1548     return status;
1549 }
1550 
TFM_CRYPTO_API(psa_status_t,psa_cipher_decrypt)1551 TFM_CRYPTO_API(psa_status_t, psa_cipher_decrypt)(psa_key_id_t key,
1552                                                  psa_algorithm_t alg,
1553                                                  const uint8_t *input,
1554                                                  size_t input_length,
1555                                                  uint8_t *output,
1556                                                  size_t output_size,
1557                                                  size_t *output_length)
1558 {
1559     psa_status_t status;
1560     struct tfm_crypto_pack_iovec iov = {
1561         .function_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
1562         .key_id = key,
1563         .alg = alg,
1564     };
1565 
1566     psa_invec in_vec[] = {
1567         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1568         {.base = input, .len = input_length},
1569     };
1570     psa_outvec out_vec[] = {
1571         {.base = output, .len = output_size}
1572     };
1573 
1574     status = API_DISPATCH(in_vec, out_vec);
1575 
1576     *output_length = out_vec[0].len;
1577     return status;
1578 }
1579 
TFM_CRYPTO_API(psa_status_t,psa_raw_key_agreement)1580 TFM_CRYPTO_API(psa_status_t, psa_raw_key_agreement)(psa_algorithm_t alg,
1581                                                     psa_key_id_t private_key,
1582                                                     const uint8_t *peer_key,
1583                                                     size_t peer_key_length,
1584                                                     uint8_t *output,
1585                                                     size_t output_size,
1586                                                     size_t *output_length)
1587 {
1588     psa_status_t status;
1589     struct tfm_crypto_pack_iovec iov = {
1590         .function_id = TFM_CRYPTO_RAW_KEY_AGREEMENT_SID,
1591         .alg = alg,
1592         .key_id = private_key
1593     };
1594 
1595     psa_invec in_vec[] = {
1596         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1597         {.base = peer_key, .len = peer_key_length},
1598     };
1599 
1600     psa_outvec out_vec[] = {
1601         {.base = output, .len = output_size},
1602     };
1603 
1604     status = API_DISPATCH(in_vec, out_vec);
1605 
1606     *output_length = out_vec[0].len;
1607 
1608     return status;
1609 }
1610 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_setup)1611 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_setup)(psa_key_derivation_operation_t *operation,
1612                                                        psa_algorithm_t alg)
1613 {
1614     struct tfm_crypto_pack_iovec iov = {
1615         .function_id = TFM_CRYPTO_KEY_DERIVATION_SETUP_SID,
1616         .alg = alg,
1617         .op_handle = operation->handle,
1618     };
1619 
1620     psa_invec in_vec[] = {
1621         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1622     };
1623     psa_outvec out_vec[] = {
1624         {.base = &(operation->handle), .len = sizeof(uint32_t)},
1625     };
1626 
1627     return API_DISPATCH(in_vec, out_vec);
1628 }
1629 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_set_capacity)1630 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_set_capacity)(
1631                                       psa_key_derivation_operation_t *operation,
1632                                       size_t capacity)
1633 {
1634     struct tfm_crypto_pack_iovec iov = {
1635         .function_id = TFM_CRYPTO_KEY_DERIVATION_SET_CAPACITY_SID,
1636         .capacity = capacity,
1637         .op_handle = operation->handle,
1638     };
1639 
1640     psa_invec in_vec[] = {
1641         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1642     };
1643 
1644     return API_DISPATCH_NO_OUTVEC(in_vec);
1645 }
1646 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_input_bytes)1647 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_bytes)(
1648                                       psa_key_derivation_operation_t *operation,
1649                                       psa_key_derivation_step_t step,
1650                                       const uint8_t *data,
1651                                       size_t data_length)
1652 {
1653     struct tfm_crypto_pack_iovec iov = {
1654         .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_BYTES_SID,
1655         .step = step,
1656         .op_handle = operation->handle,
1657     };
1658 
1659     psa_invec in_vec[] = {
1660         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1661         {.base = data, .len = data_length},
1662     };
1663 
1664     return API_DISPATCH_NO_OUTVEC(in_vec);
1665 }
1666 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_output_key)1667 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_output_key)(
1668                                       const psa_key_attributes_t *attributes,
1669                                       psa_key_derivation_operation_t *operation,
1670                                       psa_key_id_t *key)
1671 {
1672     struct tfm_crypto_pack_iovec iov = {
1673         .function_id = TFM_CRYPTO_KEY_DERIVATION_OUTPUT_KEY_SID,
1674         .op_handle = operation->handle,
1675     };
1676 
1677     psa_invec in_vec[] = {
1678         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1679         {.base = attributes, .len = sizeof(psa_key_attributes_t)},
1680     };
1681 
1682     psa_outvec out_vec[] = {
1683         {.base = key, .len = sizeof(psa_key_id_t)}
1684     };
1685 
1686     return API_DISPATCH(in_vec, out_vec);
1687 }
1688 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_input_integer)1689 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_input_integer)(
1690                                       psa_key_derivation_operation_t *operation,
1691                                       psa_key_derivation_step_t step,
1692                                       uint64_t value)
1693 {
1694     struct tfm_crypto_pack_iovec iov = {
1695         .function_id = TFM_CRYPTO_KEY_DERIVATION_INPUT_INTEGER_SID,
1696         .step = step,
1697         .value = value,
1698         .op_handle = operation->handle,
1699     };
1700 
1701     psa_invec in_vec[] = {
1702         {.base = &iov, .len = sizeof(struct tfm_crypto_pack_iovec)},
1703     };
1704 
1705     return API_DISPATCH_NO_OUTVEC(in_vec);
1706 }
1707 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_verify_bytes)1708 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_bytes)(
1709                                       psa_key_derivation_operation_t *operation,
1710                                       const uint8_t *expected_output,
1711                                       size_t output_length)
1712 {
1713     (void)operation;
1714     (void)expected_output;
1715     (void)output_length;
1716     /* To be implemented when the PSA backend supports it */
1717     return PSA_ERROR_NOT_SUPPORTED;
1718 }
1719 
TFM_CRYPTO_API(psa_status_t,psa_key_derivation_verify_key)1720 TFM_CRYPTO_API(psa_status_t, psa_key_derivation_verify_key)(
1721                                       psa_key_derivation_operation_t *operation,
1722                                       psa_key_id_t expected)
1723 {
1724     (void)operation;
1725     (void)expected;
1726     /* To be implemented when the PSA backend supports it */
1727     return PSA_ERROR_NOT_SUPPORTED;
1728 }
1729 
1730 /* The implementation of the following helper function is marked
1731  * weak to allow for those integrations where this is directly
1732  * provided by the psa_crypto_client.c module of Mbed TLS
1733  */
1734 __attribute__((weak))
TFM_CRYPTO_API(void,psa_reset_key_attributes)1735 TFM_CRYPTO_API(void, psa_reset_key_attributes)(
1736                                       psa_key_attributes_t *attributes)
1737 {
1738     memset(attributes, 0, sizeof(*attributes));
1739 }
1740