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