blob: 38fda1b19c7400c8ef238e2b89b5d51cfeee3cc9 [file] [log] [blame]
Antonio de Angelis04debbd2019-10-14 12:12:52 +01001/*
Maulik Patel28659c42021-01-06 14:09:22 +00002 * Copyright (c) 2019-2021, 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
Antonio de Angelis04debbd2019-10-14 12:12:52 +010011#include "tfm_mbedcrypto_include.h"
12
Jamie Fox044bd8e2020-02-20 13:34:57 +000013/* Required for mbedtls_calloc in tfm_crypto_huk_derivation_input_bytes */
14#include "mbedtls/platform.h"
15
Antonio de Angelis04debbd2019-10-14 12:12:52 +010016#include "tfm_crypto_api.h"
17#include "tfm_crypto_defs.h"
Jamie Fox044bd8e2020-02-20 13:34:57 +000018#include "tfm_memory_utils.h"
19
Mingyang Sun8a19e7a2020-06-04 15:36:58 +080020#include "tfm_plat_crypto_keys.h"
Soby Mathewd8abdfd2020-10-14 10:28:01 +010021#include "tfm_crypto_private.h"
Jamie Fox044bd8e2020-02-20 13:34:57 +000022
Kevin Pengc6d74502020-03-04 16:55:37 +080023#ifdef TFM_PARTITION_TEST_PS
Jamie Fox044bd8e2020-02-20 13:34:57 +000024#include "psa_manifest/pid.h"
Kevin Pengc6d74502020-03-04 16:55:37 +080025#endif /* TFM_PARTITION_TEST_PS */
Jamie Fox044bd8e2020-02-20 13:34:57 +000026
27#ifndef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
28static psa_status_t tfm_crypto_huk_derivation_setup(
29 psa_key_derivation_operation_t *operation,
30 psa_algorithm_t alg)
31{
32 operation->alg = TFM_CRYPTO_ALG_HUK_DERIVATION;
33 return PSA_SUCCESS;
34}
35
36static psa_status_t tfm_crypto_huk_derivation_input_bytes(
37 psa_key_derivation_operation_t *operation,
38 psa_key_derivation_step_t step,
39 const uint8_t *data,
40 size_t data_length)
41{
42 psa_status_t status;
43 int32_t partition_id;
44
45 if (step != PSA_KEY_DERIVATION_INPUT_LABEL) {
46 return PSA_ERROR_INVALID_ARGUMENT;
47 }
48
49 /* Concatenate the caller's partition ID with the supplied label to prevent
50 * two different partitions from deriving the same key.
51 */
52 status = tfm_crypto_get_caller_id(&partition_id);
53 if (status != PSA_SUCCESS) {
54 return status;
55 }
56
Kevin Pengc6d74502020-03-04 16:55:37 +080057#ifdef TFM_PARTITION_TEST_PS
58 /* The PS tests run some operations under the wrong partition ID - this
Jamie Fox044bd8e2020-02-20 13:34:57 +000059 * causes the key derivation to change.
60 */
Kevin Pengc6d74502020-03-04 16:55:37 +080061 if (partition_id == TFM_SP_PS_TEST) {
62 partition_id = TFM_SP_PS;
Jamie Fox044bd8e2020-02-20 13:34:57 +000063 }
Kevin Pengc6d74502020-03-04 16:55:37 +080064#endif /* TFM_PARTITION_TEST_PS */
Jamie Fox044bd8e2020-02-20 13:34:57 +000065
66 /* Put the label in the tls12_prf ctx to make it available in the output key
67 * step.
68 */
69 operation->ctx.tls12_prf.label = mbedtls_calloc(1, sizeof(partition_id)
70 + data_length);
71 if (operation->ctx.tls12_prf.label == NULL) {
72 return PSA_ERROR_INSUFFICIENT_MEMORY;
73 }
74 (void)tfm_memcpy(operation->ctx.tls12_prf.label, &partition_id,
75 sizeof(partition_id));
76 (void)tfm_memcpy(operation->ctx.tls12_prf.label + sizeof(partition_id),
77 data, data_length);
78 operation->ctx.tls12_prf.label_length = sizeof(partition_id) + data_length;
79
80 return PSA_SUCCESS;
81}
82
83static psa_status_t tfm_crypto_huk_derivation_output_key(
84 const psa_key_attributes_t *attributes,
85 psa_key_derivation_operation_t *operation,
Maulik Patel28659c42021-01-06 14:09:22 +000086 mbedtls_svc_key_id_t *key_id)
Jamie Fox044bd8e2020-02-20 13:34:57 +000087{
88 enum tfm_plat_err_t err;
89 size_t bytes = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
90
91 if (sizeof(operation->ctx.tls12_prf.output_block) < bytes) {
92 return PSA_ERROR_INSUFFICIENT_MEMORY;
93 }
94
95 /* Derive key material from the HUK and output it to the operation buffer */
96 err = tfm_plat_get_huk_derived_key(operation->ctx.tls12_prf.label,
97 operation->ctx.tls12_prf.label_length,
98 NULL, 0,
99 operation->ctx.tls12_prf.output_block,
100 bytes);
101 if (err != TFM_PLAT_ERR_SUCCESS) {
102 return PSA_ERROR_HARDWARE_FAILURE;
103 }
104
105 return psa_import_key(attributes, operation->ctx.tls12_prf.output_block,
Maulik Patel28659c42021-01-06 14:09:22 +0000106 bytes, key_id);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000107}
108
109static psa_status_t tfm_crypto_huk_derivation_abort(
110 psa_key_derivation_operation_t *operation)
111{
112 if (operation->ctx.tls12_prf.label != NULL) {
113 (void)tfm_memset(operation->ctx.tls12_prf.label, 0,
114 operation->ctx.tls12_prf.label_length);
115 mbedtls_free(operation->ctx.tls12_prf.label);
116 }
117
118 (void)tfm_memset(operation, 0, sizeof(*operation));
119
120 return PSA_SUCCESS;
121}
122#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100123
124/*!
125 * \defgroup public_psa Public functions, PSA
126 *
127 */
128
129/*!@{*/
130psa_status_t tfm_crypto_key_derivation_setup(psa_invec in_vec[],
131 size_t in_len,
132 psa_outvec out_vec[],
133 size_t out_len)
134{
135#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
136 return PSA_ERROR_NOT_SUPPORTED;
137#else
138 psa_status_t status = PSA_SUCCESS;
139 psa_key_derivation_operation_t *operation = NULL;
140
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100141 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100142
143 if ((out_vec[0].len != sizeof(uint32_t)) ||
144 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100145 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100146 }
147 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
148 uint32_t handle = iov->op_handle;
149 uint32_t *handle_out = out_vec[0].base;
150 psa_algorithm_t alg = iov->alg;
151
152 /* Allocate the operation context in the secure world */
153 status = tfm_crypto_operation_alloc(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
154 &handle,
155 (void **)&operation);
156 if (status != PSA_SUCCESS) {
157 return status;
158 }
159
160 *handle_out = handle;
161
Jamie Fox044bd8e2020-02-20 13:34:57 +0000162 if (alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
163 status = tfm_crypto_huk_derivation_setup(operation, alg);
164 } else {
165 status = psa_key_derivation_setup(operation, alg);
166 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100167 if (status != PSA_SUCCESS) {
168 /* Release the operation context, ignore if the operation fails. */
169 (void)tfm_crypto_operation_release(handle_out);
170 return status;
171 }
172
173 return status;
174#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
175}
176
177psa_status_t tfm_crypto_key_derivation_get_capacity(psa_invec in_vec[],
178 size_t in_len,
179 psa_outvec out_vec[],
180 size_t out_len)
181{
182#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
183 return PSA_ERROR_NOT_SUPPORTED;
184#else
185 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100186
187 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100188
189 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
190 (out_vec[0].len != sizeof(size_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100191 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100192 }
193 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
194
195 uint32_t handle = iov->op_handle;
196 size_t *capacity = out_vec[0].base;
197 psa_key_derivation_operation_t *operation = NULL;
198
199 /* Look up the corresponding operation context */
200 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
201 handle,
202 (void **)&operation);
203 if (status != PSA_SUCCESS) {
204 *capacity = 0;
205 return status;
206 }
207
208 return psa_key_derivation_get_capacity(operation, capacity);
209#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
210}
211
212psa_status_t tfm_crypto_key_derivation_set_capacity(psa_invec in_vec[],
213 size_t in_len,
214 psa_outvec out_vec[],
215 size_t out_len)
216{
217#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
218 return PSA_ERROR_NOT_SUPPORTED;
219#else
220 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100221
222 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100223
224 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100225 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100226 }
227 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
228
229 uint32_t handle = iov->op_handle;
230 size_t capacity = iov->capacity;
231 psa_key_derivation_operation_t *operation = NULL;
232
233 /* Look up the corresponding operation context */
234 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
235 handle,
236 (void **)&operation);
237 if (status != PSA_SUCCESS) {
238 return status;
239 }
240
241 return psa_key_derivation_set_capacity(operation, capacity);
242#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
243}
244
245psa_status_t tfm_crypto_key_derivation_input_bytes(psa_invec in_vec[],
246 size_t in_len,
247 psa_outvec out_vec[],
248 size_t out_len)
249{
250#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
251 return PSA_ERROR_NOT_SUPPORTED;
252#else
253 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100254
255 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100256
257 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100258 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100259 }
260 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
261
262 uint32_t handle = iov->op_handle;
263 psa_key_derivation_step_t step = iov->step;
264 const uint8_t *data = in_vec[1].base;
265 size_t data_length = in_vec[1].len;
266 psa_key_derivation_operation_t *operation = NULL;
267
268 /* Look up the corresponding operation context */
269 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
270 handle,
271 (void **)&operation);
272 if (status != PSA_SUCCESS) {
273 return status;
274 }
275
Jamie Fox044bd8e2020-02-20 13:34:57 +0000276 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
277 return tfm_crypto_huk_derivation_input_bytes(operation, step, data,
278 data_length);
279 } else {
280 return psa_key_derivation_input_bytes(operation, step, data,
281 data_length);
282 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100283#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
284}
285
286psa_status_t tfm_crypto_key_derivation_output_bytes(psa_invec in_vec[],
287 size_t in_len,
288 psa_outvec out_vec[],
289 size_t out_len)
290{
291#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
292 return PSA_ERROR_NOT_SUPPORTED;
293#else
294 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100295
296 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100297
298 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100299 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100300 }
301 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
302
303 uint32_t handle = iov->op_handle;
304 uint8_t *output = out_vec[0].base;
305 size_t output_length = out_vec[0].len;
306 psa_key_derivation_operation_t *operation = NULL;
307
308 /* Look up the corresponding operation context */
309 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
310 handle,
311 (void **)&operation);
312 if (status != PSA_SUCCESS) {
313 return status;
314 }
315
316 return psa_key_derivation_output_bytes(operation, output, output_length);
317#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
318}
319
320psa_status_t tfm_crypto_key_derivation_input_key(psa_invec in_vec[],
321 size_t in_len,
322 psa_outvec out_vec[],
323 size_t out_len)
324{
325#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
326 return PSA_ERROR_NOT_SUPPORTED;
327#else
328 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100329
330 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100331
332 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100333 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100334 }
335 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100336 uint32_t handle = iov->op_handle;
Maulik Patel28659c42021-01-06 14:09:22 +0000337 psa_key_id_t key_id = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100338 psa_key_derivation_step_t step = iov->step;
339 psa_key_derivation_operation_t *operation = NULL;
Maulik Patel28659c42021-01-06 14:09:22 +0000340 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100341
David Hu105b4872021-05-19 16:43:19 +0800342 status = tfm_crypto_check_handle_owner(key_id);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100343 if (status != PSA_SUCCESS) {
344 return status;
345 }
346
347 /* Look up the corresponding operation context */
348 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
349 handle,
350 (void **)&operation);
351 if (status != PSA_SUCCESS) {
352 return status;
353 }
354
Maulik Patel28659c42021-01-06 14:09:22 +0000355 status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
356 if (status != PSA_SUCCESS) {
357 return status;
358 }
359
360 return psa_key_derivation_input_key(operation, step, encoded_key);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100361#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)) ||
Maulik Patel28659c42021-01-06 14:09:22 +0000378 (out_vec[0].len != sizeof(psa_key_id_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100379 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100380 }
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;
Maulik Patel28659c42021-01-06 14:09:22 +0000386 psa_key_id_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;
Maulik Patel28659c42021-01-06 14:09:22 +0000390 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100391
392 /* Look up the corresponding operation context */
393 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
394 handle,
395 (void **)&operation);
396 if (status != PSA_SUCCESS) {
397 return status;
398 }
Jamie Fox99360e82020-02-20 16:00:09 +0000399
400 status = tfm_crypto_check_key_storage(&index);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100401 if (status != PSA_SUCCESS) {
402 return status;
403 }
Jamie Fox99360e82020-02-20 16:00:09 +0000404
Jamie Fox98ab4412020-01-17 17:12:30 +0000405 status = tfm_crypto_get_caller_id(&partition_id);
406 if (status != PSA_SUCCESS) {
407 return status;
408 }
409
410 status = tfm_crypto_key_attributes_from_client(client_key_attr,
411 partition_id,
412 &key_attributes);
413 if (status != PSA_SUCCESS) {
414 return status;
415 }
416
Jamie Fox044bd8e2020-02-20 13:34:57 +0000417 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
Jamie Fox98ab4412020-01-17 17:12:30 +0000418 status = tfm_crypto_huk_derivation_output_key(&key_attributes,
Maulik Patel28659c42021-01-06 14:09:22 +0000419 operation, &encoded_key);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000420 } else {
Jamie Fox98ab4412020-01-17 17:12:30 +0000421 status = psa_key_derivation_output_key(&key_attributes, operation,
Maulik Patel28659c42021-01-06 14:09:22 +0000422 &encoded_key);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000423 }
David Hu105b4872021-05-19 16:43:19 +0800424#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
Maulik Patel28659c42021-01-06 14:09:22 +0000425 *key_handle = encoded_key.key_id;
David Hu105b4872021-05-19 16:43:19 +0800426#else
427 *key_handle = (psa_key_id_t)encoded_key;
428#endif
Maulik Patel28659c42021-01-06 14:09:22 +0000429
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100430 if (status == PSA_SUCCESS) {
Jamie Fox99360e82020-02-20 16:00:09 +0000431 status = tfm_crypto_set_key_storage(index, *key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100432 }
Jamie Fox99360e82020-02-20 16:00:09 +0000433
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100434 return status;
435#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
436}
437
438psa_status_t tfm_crypto_key_derivation_abort(psa_invec in_vec[],
439 size_t in_len,
440 psa_outvec out_vec[],
441 size_t out_len)
442{
443#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
444 return PSA_ERROR_NOT_SUPPORTED;
445#else
446 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100447
448 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100449
450 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
451 (out_vec[0].len != sizeof(uint32_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100452 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100453 }
454 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
455
456 uint32_t handle = iov->op_handle;
457 uint32_t *handle_out = out_vec[0].base;
458 psa_key_derivation_operation_t *operation = NULL;
459
460 /* Init the handle in the operation with the one passed from the iov */
461 *handle_out = iov->op_handle;
462
463 /* Look up the corresponding operation context */
464 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
465 handle,
466 (void **)&operation);
467 if (status != PSA_SUCCESS) {
468 /* Operation does not exist, so abort has no effect */
469 return PSA_SUCCESS;
470 }
471
472 *handle_out = handle;
473
Jamie Fox044bd8e2020-02-20 13:34:57 +0000474 if (operation->alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
475 status = tfm_crypto_huk_derivation_abort(operation);
476 } else {
477 status = psa_key_derivation_abort(operation);
478 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100479 if (status != PSA_SUCCESS) {
480 /* Release the operation context, ignore if the operation fails. */
481 (void)tfm_crypto_operation_release(handle_out);
482 return status;
483 }
484
485 status = tfm_crypto_operation_release(handle_out);
486
487 return status;
488#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
489}
490
491psa_status_t tfm_crypto_key_derivation_key_agreement(psa_invec in_vec[],
492 size_t in_len,
493 psa_outvec out_vec[],
494 size_t out_len)
495{
496#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
497 return PSA_ERROR_NOT_SUPPORTED;
498#else
499 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100500
501 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100502
503 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100504 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100505 }
506 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
507
508 uint32_t handle = iov->op_handle;
Maulik Patel28659c42021-01-06 14:09:22 +0000509 psa_key_id_t private_key = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100510 const uint8_t *peer_key = in_vec[1].base;
511 size_t peer_key_length = in_vec[1].len;
512 psa_key_derivation_operation_t *operation = NULL;
513 psa_key_derivation_step_t step = iov->step;
Maulik Patel28659c42021-01-06 14:09:22 +0000514 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100515
David Hu105b4872021-05-19 16:43:19 +0800516 status = tfm_crypto_check_handle_owner(private_key);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100517 if (status != PSA_SUCCESS) {
518 return status;
519 }
520
521 /* Look up the corresponding operation context */
522 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
523 handle,
524 (void **)&operation);
525 if (status != PSA_SUCCESS) {
526 return status;
527 }
528
Maulik Patel28659c42021-01-06 14:09:22 +0000529 status = tfm_crypto_encode_id_and_owner(private_key, &encoded_key);
530 if (status != PSA_SUCCESS) {
531 return status;
532 }
533
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100534 return psa_key_derivation_key_agreement(operation, step,
Maulik Patel28659c42021-01-06 14:09:22 +0000535 encoded_key,
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100536 peer_key,
537 peer_key_length);
538#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
539}
540
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100541psa_status_t tfm_crypto_raw_key_agreement(psa_invec in_vec[],
542 size_t in_len,
543 psa_outvec out_vec[],
544 size_t out_len)
545{
546#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
547 return PSA_ERROR_NOT_SUPPORTED;
548#else
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100549
550 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100551
552 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100553 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100554 }
555 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
556 uint8_t *output = out_vec[0].base;
557 size_t output_size = out_vec[0].len;
558 psa_algorithm_t alg = iov->alg;
Maulik Patel28659c42021-01-06 14:09:22 +0000559 psa_key_id_t private_key = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100560 const uint8_t *peer_key = in_vec[1].base;
561 size_t peer_key_length = in_vec[1].len;
Maulik Patel28659c42021-01-06 14:09:22 +0000562 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100563
David Hu105b4872021-05-19 16:43:19 +0800564 psa_status_t status = tfm_crypto_check_handle_owner(private_key);
Maulik Patel28659c42021-01-06 14:09:22 +0000565
566 if (status != PSA_SUCCESS) {
567 return status;
568 }
569
570 status = tfm_crypto_encode_id_and_owner(private_key, &encoded_key);
571 if (status != PSA_SUCCESS) {
572 return status;
573 }
574
575 return psa_raw_key_agreement(alg, encoded_key, peer_key, peer_key_length,
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100576 output, output_size, &out_vec[0].len);
577#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
578}
579/*!@}*/