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