blob: baeab1133064ca6fcb86d0d797fac3736e97f17a [file] [log] [blame]
Antonio de Angelis04debbd2019-10-14 12:12:52 +01001/*
Jamie Fox044bd8e2020-02-20 13:34:57 +00002 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
Antonio de Angelis04debbd2019-10-14 12:12:52 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stddef.h>
9#include <stdint.h>
10
11/* FixMe: Use PSA_ERROR_CONNECTION_REFUSED when performing parameter
12 * integrity checks but this will have to be revised
13 * when the full set of error codes mandated by PSA FF
14 * is available.
15 */
16#include "tfm_mbedcrypto_include.h"
17
Jamie Fox044bd8e2020-02-20 13:34:57 +000018/* Required for mbedtls_calloc in tfm_crypto_huk_derivation_input_bytes */
19#include "mbedtls/platform.h"
20
Antonio de Angelis04debbd2019-10-14 12:12:52 +010021#include "tfm_crypto_api.h"
22#include "tfm_crypto_defs.h"
Jamie Fox044bd8e2020-02-20 13:34:57 +000023#include "tfm_memory_utils.h"
24
Mingyang Sun8a19e7a2020-06-04 15:36:58 +080025#include "tfm_plat_crypto_keys.h"
Soby Mathewd8abdfd2020-10-14 10:28:01 +010026#include "tfm_crypto_private.h"
Jamie Fox044bd8e2020-02-20 13:34:57 +000027
Kevin Pengc6d74502020-03-04 16:55:37 +080028#ifdef TFM_PARTITION_TEST_PS
Jamie Fox044bd8e2020-02-20 13:34:57 +000029#include "psa_manifest/pid.h"
Kevin Pengc6d74502020-03-04 16:55:37 +080030#endif /* TFM_PARTITION_TEST_PS */
Jamie Fox044bd8e2020-02-20 13:34:57 +000031
32#ifndef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
33static psa_status_t tfm_crypto_huk_derivation_setup(
34 psa_key_derivation_operation_t *operation,
35 psa_algorithm_t alg)
36{
37 operation->alg = TFM_CRYPTO_ALG_HUK_DERIVATION;
38 return PSA_SUCCESS;
39}
40
41static psa_status_t tfm_crypto_huk_derivation_input_bytes(
42 psa_key_derivation_operation_t *operation,
43 psa_key_derivation_step_t step,
44 const uint8_t *data,
45 size_t data_length)
46{
47 psa_status_t status;
48 int32_t partition_id;
49
50 if (step != PSA_KEY_DERIVATION_INPUT_LABEL) {
51 return PSA_ERROR_INVALID_ARGUMENT;
52 }
53
54 /* Concatenate the caller's partition ID with the supplied label to prevent
55 * two different partitions from deriving the same key.
56 */
57 status = tfm_crypto_get_caller_id(&partition_id);
58 if (status != PSA_SUCCESS) {
59 return status;
60 }
61
Kevin Pengc6d74502020-03-04 16:55:37 +080062#ifdef TFM_PARTITION_TEST_PS
63 /* The PS tests run some operations under the wrong partition ID - this
Jamie Fox044bd8e2020-02-20 13:34:57 +000064 * causes the key derivation to change.
65 */
Kevin Pengc6d74502020-03-04 16:55:37 +080066 if (partition_id == TFM_SP_PS_TEST) {
67 partition_id = TFM_SP_PS;
Jamie Fox044bd8e2020-02-20 13:34:57 +000068 }
Kevin Pengc6d74502020-03-04 16:55:37 +080069#endif /* TFM_PARTITION_TEST_PS */
Jamie Fox044bd8e2020-02-20 13:34:57 +000070
71 /* Put the label in the tls12_prf ctx to make it available in the output key
72 * step.
73 */
74 operation->ctx.tls12_prf.label = mbedtls_calloc(1, sizeof(partition_id)
75 + data_length);
76 if (operation->ctx.tls12_prf.label == NULL) {
77 return PSA_ERROR_INSUFFICIENT_MEMORY;
78 }
79 (void)tfm_memcpy(operation->ctx.tls12_prf.label, &partition_id,
80 sizeof(partition_id));
81 (void)tfm_memcpy(operation->ctx.tls12_prf.label + sizeof(partition_id),
82 data, data_length);
83 operation->ctx.tls12_prf.label_length = sizeof(partition_id) + data_length;
84
85 return PSA_SUCCESS;
86}
87
88static psa_status_t tfm_crypto_huk_derivation_output_key(
89 const psa_key_attributes_t *attributes,
90 psa_key_derivation_operation_t *operation,
91 psa_key_handle_t *handle)
92{
93 enum tfm_plat_err_t err;
94 size_t bytes = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
95
96 if (sizeof(operation->ctx.tls12_prf.output_block) < bytes) {
97 return PSA_ERROR_INSUFFICIENT_MEMORY;
98 }
99
100 /* Derive key material from the HUK and output it to the operation buffer */
101 err = tfm_plat_get_huk_derived_key(operation->ctx.tls12_prf.label,
102 operation->ctx.tls12_prf.label_length,
103 NULL, 0,
104 operation->ctx.tls12_prf.output_block,
105 bytes);
106 if (err != TFM_PLAT_ERR_SUCCESS) {
107 return PSA_ERROR_HARDWARE_FAILURE;
108 }
109
110 return psa_import_key(attributes, operation->ctx.tls12_prf.output_block,
111 bytes, handle);
112}
113
114static psa_status_t tfm_crypto_huk_derivation_abort(
115 psa_key_derivation_operation_t *operation)
116{
117 if (operation->ctx.tls12_prf.label != NULL) {
118 (void)tfm_memset(operation->ctx.tls12_prf.label, 0,
119 operation->ctx.tls12_prf.label_length);
120 mbedtls_free(operation->ctx.tls12_prf.label);
121 }
122
123 (void)tfm_memset(operation, 0, sizeof(*operation));
124
125 return PSA_SUCCESS;
126}
127#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100128
129/*!
130 * \defgroup public_psa Public functions, PSA
131 *
132 */
133
134/*!@{*/
135psa_status_t tfm_crypto_key_derivation_setup(psa_invec in_vec[],
136 size_t in_len,
137 psa_outvec out_vec[],
138 size_t out_len)
139{
140#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
141 return PSA_ERROR_NOT_SUPPORTED;
142#else
143 psa_status_t status = PSA_SUCCESS;
144 psa_key_derivation_operation_t *operation = NULL;
145
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100146 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100147
148 if ((out_vec[0].len != sizeof(uint32_t)) ||
149 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
150 return PSA_ERROR_CONNECTION_REFUSED;
151 }
152 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
153 uint32_t handle = iov->op_handle;
154 uint32_t *handle_out = out_vec[0].base;
155 psa_algorithm_t alg = iov->alg;
156
157 /* Allocate the operation context in the secure world */
158 status = tfm_crypto_operation_alloc(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
159 &handle,
160 (void **)&operation);
161 if (status != PSA_SUCCESS) {
162 return status;
163 }
164
165 *handle_out = handle;
166
Jamie Fox044bd8e2020-02-20 13:34:57 +0000167 if (alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
168 status = tfm_crypto_huk_derivation_setup(operation, alg);
169 } else {
170 status = psa_key_derivation_setup(operation, alg);
171 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100172 if (status != PSA_SUCCESS) {
173 /* Release the operation context, ignore if the operation fails. */
174 (void)tfm_crypto_operation_release(handle_out);
175 return status;
176 }
177
178 return status;
179#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
180}
181
182psa_status_t tfm_crypto_key_derivation_get_capacity(psa_invec in_vec[],
183 size_t in_len,
184 psa_outvec out_vec[],
185 size_t out_len)
186{
187#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
188 return PSA_ERROR_NOT_SUPPORTED;
189#else
190 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100191
192 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100193
194 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
195 (out_vec[0].len != sizeof(size_t))) {
196 return PSA_ERROR_CONNECTION_REFUSED;
197 }
198 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
199
200 uint32_t handle = iov->op_handle;
201 size_t *capacity = out_vec[0].base;
202 psa_key_derivation_operation_t *operation = NULL;
203
204 /* Look up the corresponding operation context */
205 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
206 handle,
207 (void **)&operation);
208 if (status != PSA_SUCCESS) {
209 *capacity = 0;
210 return status;
211 }
212
213 return psa_key_derivation_get_capacity(operation, capacity);
214#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
215}
216
217psa_status_t tfm_crypto_key_derivation_set_capacity(psa_invec in_vec[],
218 size_t in_len,
219 psa_outvec out_vec[],
220 size_t out_len)
221{
222#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
223 return PSA_ERROR_NOT_SUPPORTED;
224#else
225 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100226
227 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100228
229 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
230 return PSA_ERROR_CONNECTION_REFUSED;
231 }
232 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
233
234 uint32_t handle = iov->op_handle;
235 size_t capacity = iov->capacity;
236 psa_key_derivation_operation_t *operation = NULL;
237
238 /* Look up the corresponding operation context */
239 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
240 handle,
241 (void **)&operation);
242 if (status != PSA_SUCCESS) {
243 return status;
244 }
245
246 return psa_key_derivation_set_capacity(operation, capacity);
247#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
248}
249
250psa_status_t tfm_crypto_key_derivation_input_bytes(psa_invec in_vec[],
251 size_t in_len,
252 psa_outvec out_vec[],
253 size_t out_len)
254{
255#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
256 return PSA_ERROR_NOT_SUPPORTED;
257#else
258 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100259
260 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100261
262 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
263 return PSA_ERROR_CONNECTION_REFUSED;
264 }
265 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
266
267 uint32_t handle = iov->op_handle;
268 psa_key_derivation_step_t step = iov->step;
269 const uint8_t *data = in_vec[1].base;
270 size_t data_length = in_vec[1].len;
271 psa_key_derivation_operation_t *operation = NULL;
272
273 /* Look up the corresponding operation context */
274 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
275 handle,
276 (void **)&operation);
277 if (status != PSA_SUCCESS) {
278 return status;
279 }
280
Jamie Fox044bd8e2020-02-20 13:34:57 +0000281 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
282 return tfm_crypto_huk_derivation_input_bytes(operation, step, data,
283 data_length);
284 } else {
285 return psa_key_derivation_input_bytes(operation, step, data,
286 data_length);
287 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100288#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
289}
290
291psa_status_t tfm_crypto_key_derivation_output_bytes(psa_invec in_vec[],
292 size_t in_len,
293 psa_outvec out_vec[],
294 size_t out_len)
295{
296#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
297 return PSA_ERROR_NOT_SUPPORTED;
298#else
299 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100300
301 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100302
303 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
304 return PSA_ERROR_CONNECTION_REFUSED;
305 }
306 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
307
308 uint32_t handle = iov->op_handle;
309 uint8_t *output = out_vec[0].base;
310 size_t output_length = out_vec[0].len;
311 psa_key_derivation_operation_t *operation = NULL;
312
313 /* Look up the corresponding operation context */
314 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
315 handle,
316 (void **)&operation);
317 if (status != PSA_SUCCESS) {
318 return status;
319 }
320
321 return psa_key_derivation_output_bytes(operation, output, output_length);
322#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
323}
324
325psa_status_t tfm_crypto_key_derivation_input_key(psa_invec in_vec[],
326 size_t in_len,
327 psa_outvec out_vec[],
328 size_t out_len)
329{
330#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
331 return PSA_ERROR_NOT_SUPPORTED;
332#else
333 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100334
335 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100336
337 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
338 return PSA_ERROR_CONNECTION_REFUSED;
339 }
340 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
341
342 uint32_t handle = iov->op_handle;
343 psa_key_handle_t key_handle = iov->key_handle;
344 psa_key_derivation_step_t step = iov->step;
345 psa_key_derivation_operation_t *operation = NULL;
346
347 status = tfm_crypto_check_handle_owner(key_handle, NULL);
348 if (status != PSA_SUCCESS) {
349 return status;
350 }
351
352 /* Look up the corresponding operation context */
353 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
354 handle,
355 (void **)&operation);
356 if (status != PSA_SUCCESS) {
357 return status;
358 }
359
360 return psa_key_derivation_input_key(operation, step, key_handle);
361#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
362}
363
364psa_status_t tfm_crypto_key_derivation_output_key(psa_invec in_vec[],
365 size_t in_len,
366 psa_outvec out_vec[],
367 size_t out_len)
368{
369#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
370 return PSA_ERROR_NOT_SUPPORTED;
371#else
372 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100373
374 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 2, 2, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100375
376 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Soby Mathewd7b79f22020-05-21 15:06:54 +0100377 (in_vec[1].len != sizeof(struct psa_client_key_attributes_s)) ||
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100378 (out_vec[0].len != sizeof(psa_key_handle_t))) {
379 return PSA_ERROR_CONNECTION_REFUSED;
380 }
381 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
382
383 uint32_t handle = iov->op_handle;
Soby Mathewd7b79f22020-05-21 15:06:54 +0100384 const struct psa_client_key_attributes_s *client_key_attr = in_vec[1].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100385 psa_key_derivation_operation_t *operation = NULL;
386 psa_key_handle_t *key_handle = out_vec[0].base;
Jamie Fox98ab4412020-01-17 17:12:30 +0000387 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
388 int32_t partition_id;
Jamie Fox99360e82020-02-20 16:00:09 +0000389 uint32_t index;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100390
391 /* Look up the corresponding operation context */
392 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
393 handle,
394 (void **)&operation);
395 if (status != PSA_SUCCESS) {
396 return status;
397 }
Jamie Fox99360e82020-02-20 16:00:09 +0000398
399 status = tfm_crypto_check_key_storage(&index);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100400 if (status != PSA_SUCCESS) {
401 return status;
402 }
Jamie Fox99360e82020-02-20 16:00:09 +0000403
Jamie Fox98ab4412020-01-17 17:12:30 +0000404 status = tfm_crypto_get_caller_id(&partition_id);
405 if (status != PSA_SUCCESS) {
406 return status;
407 }
408
409 status = tfm_crypto_key_attributes_from_client(client_key_attr,
410 partition_id,
411 &key_attributes);
412 if (status != PSA_SUCCESS) {
413 return status;
414 }
415
Jamie Fox044bd8e2020-02-20 13:34:57 +0000416 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
Jamie Fox98ab4412020-01-17 17:12:30 +0000417 status = tfm_crypto_huk_derivation_output_key(&key_attributes,
418 operation, key_handle);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000419 } else {
Jamie Fox98ab4412020-01-17 17:12:30 +0000420 status = psa_key_derivation_output_key(&key_attributes, operation,
Jamie Fox044bd8e2020-02-20 13:34:57 +0000421 key_handle);
422 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100423 if (status == PSA_SUCCESS) {
Jamie Fox99360e82020-02-20 16:00:09 +0000424 status = tfm_crypto_set_key_storage(index, *key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100425 }
Jamie Fox99360e82020-02-20 16:00:09 +0000426
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100427 return status;
428#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
429}
430
431psa_status_t tfm_crypto_key_derivation_abort(psa_invec in_vec[],
432 size_t in_len,
433 psa_outvec out_vec[],
434 size_t out_len)
435{
436#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
437 return PSA_ERROR_NOT_SUPPORTED;
438#else
439 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100440
441 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100442
443 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
444 (out_vec[0].len != sizeof(uint32_t))) {
445 return PSA_ERROR_CONNECTION_REFUSED;
446 }
447 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
448
449 uint32_t handle = iov->op_handle;
450 uint32_t *handle_out = out_vec[0].base;
451 psa_key_derivation_operation_t *operation = NULL;
452
453 /* Init the handle in the operation with the one passed from the iov */
454 *handle_out = iov->op_handle;
455
456 /* Look up the corresponding operation context */
457 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
458 handle,
459 (void **)&operation);
460 if (status != PSA_SUCCESS) {
461 /* Operation does not exist, so abort has no effect */
462 return PSA_SUCCESS;
463 }
464
465 *handle_out = handle;
466
Jamie Fox044bd8e2020-02-20 13:34:57 +0000467 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
468 status = tfm_crypto_huk_derivation_abort(operation);
469 } else {
470 status = psa_key_derivation_abort(operation);
471 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100472 if (status != PSA_SUCCESS) {
473 /* Release the operation context, ignore if the operation fails. */
474 (void)tfm_crypto_operation_release(handle_out);
475 return status;
476 }
477
478 status = tfm_crypto_operation_release(handle_out);
479
480 return status;
481#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
482}
483
484psa_status_t tfm_crypto_key_derivation_key_agreement(psa_invec in_vec[],
485 size_t in_len,
486 psa_outvec out_vec[],
487 size_t out_len)
488{
489#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
490 return PSA_ERROR_NOT_SUPPORTED;
491#else
492 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100493
494 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100495
496 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
497 return PSA_ERROR_CONNECTION_REFUSED;
498 }
499 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
500
501 uint32_t handle = iov->op_handle;
502 psa_key_handle_t private_key = iov->key_handle;
503 const uint8_t *peer_key = in_vec[1].base;
504 size_t peer_key_length = in_vec[1].len;
505 psa_key_derivation_operation_t *operation = NULL;
506 psa_key_derivation_step_t step = iov->step;
507
508 status = tfm_crypto_check_handle_owner(private_key, NULL);
509 if (status != PSA_SUCCESS) {
510 return status;
511 }
512
513 /* Look up the corresponding operation context */
514 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
515 handle,
516 (void **)&operation);
517 if (status != PSA_SUCCESS) {
518 return status;
519 }
520
521 return psa_key_derivation_key_agreement(operation, step,
522 private_key,
523 peer_key,
524 peer_key_length);
525#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
526}
527
528psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
529 size_t in_len,
530 psa_outvec out_vec[],
531 size_t out_len)
532{
533#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
534 return PSA_ERROR_NOT_SUPPORTED;
535#else
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100536
537 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100538
539 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
540 return PSA_ERROR_CONNECTION_REFUSED;
541 }
542 uint8_t *output = out_vec[0].base;
543 size_t output_size = out_vec[0].len;
544
545 return psa_generate_random(output, output_size);
546#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
547}
548
549psa_status_t tfm_crypto_raw_key_agreement(psa_invec in_vec[],
550 size_t in_len,
551 psa_outvec out_vec[],
552 size_t out_len)
553{
554#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
555 return PSA_ERROR_NOT_SUPPORTED;
556#else
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100557
558 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100559
560 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
561 return PSA_ERROR_CONNECTION_REFUSED;
562 }
563 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
564 uint8_t *output = out_vec[0].base;
565 size_t output_size = out_vec[0].len;
566 psa_algorithm_t alg = iov->alg;
567 psa_key_handle_t private_key = iov->key_handle;
568 const uint8_t *peer_key = in_vec[1].base;
569 size_t peer_key_length = in_vec[1].len;
570
571 return psa_raw_key_agreement(alg, private_key, peer_key, peer_key_length,
572 output, output_size, &out_vec[0].len);
573#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
574}
575/*!@}*/