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