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