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