blob: 33996834c2d0c17881fe29454c1fd67bd3e794b2 [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{
Summer Qin359167d2021-07-05 18:11:50 +080032 operation->MBEDTLS_PRIVATE(alg) = TFM_CRYPTO_ALG_HUK_DERIVATION;
Jamie Fox044bd8e2020-02-20 13:34:57 +000033 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;
Summer Qin359167d2021-07-05 18:11:50 +080044 psa_tls12_prf_key_derivation_t *tls12_prf;
Jamie Fox044bd8e2020-02-20 13:34:57 +000045
46 if (step != PSA_KEY_DERIVATION_INPUT_LABEL) {
47 return PSA_ERROR_INVALID_ARGUMENT;
48 }
49
50 /* Concatenate the caller's partition ID with the supplied label to prevent
51 * two different partitions from deriving the same key.
52 */
53 status = tfm_crypto_get_caller_id(&partition_id);
54 if (status != PSA_SUCCESS) {
55 return status;
56 }
57
Kevin Pengc6d74502020-03-04 16:55:37 +080058#ifdef TFM_PARTITION_TEST_PS
59 /* The PS tests run some operations under the wrong partition ID - this
Jamie Fox044bd8e2020-02-20 13:34:57 +000060 * causes the key derivation to change.
61 */
Kevin Pengc6d74502020-03-04 16:55:37 +080062 if (partition_id == TFM_SP_PS_TEST) {
63 partition_id = TFM_SP_PS;
Jamie Fox044bd8e2020-02-20 13:34:57 +000064 }
Kevin Pengc6d74502020-03-04 16:55:37 +080065#endif /* TFM_PARTITION_TEST_PS */
Jamie Fox044bd8e2020-02-20 13:34:57 +000066
67 /* Put the label in the tls12_prf ctx to make it available in the output key
68 * step.
69 */
Summer Qin359167d2021-07-05 18:11:50 +080070 tls12_prf = &(operation->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(tls12_prf));
71 tls12_prf->MBEDTLS_PRIVATE(label) =
72 mbedtls_calloc(1, sizeof(partition_id) + data_length);
73 if (tls12_prf->MBEDTLS_PRIVATE(label) == NULL) {
Jamie Fox044bd8e2020-02-20 13:34:57 +000074 return PSA_ERROR_INSUFFICIENT_MEMORY;
75 }
Summer Qin359167d2021-07-05 18:11:50 +080076 (void)tfm_memcpy(tls12_prf->MBEDTLS_PRIVATE(label), &partition_id,
Jamie Fox044bd8e2020-02-20 13:34:57 +000077 sizeof(partition_id));
Summer Qin359167d2021-07-05 18:11:50 +080078 (void)tfm_memcpy(tls12_prf->MBEDTLS_PRIVATE(label) + sizeof(partition_id),
Jamie Fox044bd8e2020-02-20 13:34:57 +000079 data, data_length);
Summer Qin359167d2021-07-05 18:11:50 +080080 tls12_prf->MBEDTLS_PRIVATE(label_length) = sizeof(partition_id) +
81 data_length;
Jamie Fox044bd8e2020-02-20 13:34:57 +000082
83 return PSA_SUCCESS;
84}
85
86static psa_status_t tfm_crypto_huk_derivation_output_key(
87 const psa_key_attributes_t *attributes,
88 psa_key_derivation_operation_t *operation,
Maulik Patel28659c42021-01-06 14:09:22 +000089 mbedtls_svc_key_id_t *key_id)
Jamie Fox044bd8e2020-02-20 13:34:57 +000090{
91 enum tfm_plat_err_t err;
92 size_t bytes = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
Summer Qin359167d2021-07-05 18:11:50 +080093 psa_tls12_prf_key_derivation_t *tls12_prf =
94 &(operation->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(tls12_prf));
Jamie Fox044bd8e2020-02-20 13:34:57 +000095
Summer Qin359167d2021-07-05 18:11:50 +080096 if (sizeof(tls12_prf->MBEDTLS_PRIVATE(output_block)) < bytes) {
Jamie Fox044bd8e2020-02-20 13:34:57 +000097 return PSA_ERROR_INSUFFICIENT_MEMORY;
98 }
99
100 /* Derive key material from the HUK and output it to the operation buffer */
Summer Qin359167d2021-07-05 18:11:50 +0800101 err = tfm_plat_get_huk_derived_key(tls12_prf->MBEDTLS_PRIVATE(label),
102 tls12_prf->MBEDTLS_PRIVATE(label_length),
Jamie Fox044bd8e2020-02-20 13:34:57 +0000103 NULL, 0,
Summer Qin359167d2021-07-05 18:11:50 +0800104 tls12_prf->MBEDTLS_PRIVATE(output_block),
Jamie Fox044bd8e2020-02-20 13:34:57 +0000105 bytes);
106 if (err != TFM_PLAT_ERR_SUCCESS) {
107 return PSA_ERROR_HARDWARE_FAILURE;
108 }
109
Summer Qin359167d2021-07-05 18:11:50 +0800110 return psa_import_key(attributes, tls12_prf->MBEDTLS_PRIVATE(output_block),
Maulik Patel28659c42021-01-06 14:09:22 +0000111 bytes, key_id);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000112}
113
114static psa_status_t tfm_crypto_huk_derivation_abort(
115 psa_key_derivation_operation_t *operation)
116{
Summer Qin359167d2021-07-05 18:11:50 +0800117 psa_tls12_prf_key_derivation_t *tls12_prf =
118 &(operation->MBEDTLS_PRIVATE(ctx).MBEDTLS_PRIVATE(tls12_prf));
119
120 if (tls12_prf->MBEDTLS_PRIVATE(label) != NULL) {
121 (void)tfm_memset(tls12_prf->MBEDTLS_PRIVATE(label), 0,
122 tls12_prf->MBEDTLS_PRIVATE(label_length));
123 mbedtls_free(tls12_prf->MBEDTLS_PRIVATE(label));
Jamie Fox044bd8e2020-02-20 13:34:57 +0000124 }
125
126 (void)tfm_memset(operation, 0, sizeof(*operation));
127
128 return PSA_SUCCESS;
129}
130#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100131
132/*!
133 * \defgroup public_psa Public functions, PSA
134 *
135 */
136
137/*!@{*/
138psa_status_t tfm_crypto_key_derivation_setup(psa_invec in_vec[],
139 size_t in_len,
140 psa_outvec out_vec[],
141 size_t out_len)
142{
143#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
144 return PSA_ERROR_NOT_SUPPORTED;
145#else
146 psa_status_t status = PSA_SUCCESS;
147 psa_key_derivation_operation_t *operation = NULL;
148
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100149 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100150
151 if ((out_vec[0].len != sizeof(uint32_t)) ||
152 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100153 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100154 }
155 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
156 uint32_t handle = iov->op_handle;
157 uint32_t *handle_out = out_vec[0].base;
158 psa_algorithm_t alg = iov->alg;
159
160 /* Allocate the operation context in the secure world */
161 status = tfm_crypto_operation_alloc(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
162 &handle,
163 (void **)&operation);
164 if (status != PSA_SUCCESS) {
165 return status;
166 }
167
168 *handle_out = handle;
169
Jamie Fox044bd8e2020-02-20 13:34:57 +0000170 if (alg == TFM_CRYPTO_ALG_HUK_DERIVATION) {
171 status = tfm_crypto_huk_derivation_setup(operation, alg);
172 } else {
173 status = psa_key_derivation_setup(operation, alg);
174 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100175 if (status != PSA_SUCCESS) {
176 /* Release the operation context, ignore if the operation fails. */
177 (void)tfm_crypto_operation_release(handle_out);
178 return status;
179 }
180
181 return status;
182#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
183}
184
185psa_status_t tfm_crypto_key_derivation_get_capacity(psa_invec in_vec[],
186 size_t in_len,
187 psa_outvec out_vec[],
188 size_t out_len)
189{
190#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
191 return PSA_ERROR_NOT_SUPPORTED;
192#else
193 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100194
195 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100196
197 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
198 (out_vec[0].len != sizeof(size_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100199 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100200 }
201 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
202
203 uint32_t handle = iov->op_handle;
204 size_t *capacity = out_vec[0].base;
205 psa_key_derivation_operation_t *operation = NULL;
206
207 /* Look up the corresponding operation context */
208 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
209 handle,
210 (void **)&operation);
211 if (status != PSA_SUCCESS) {
212 *capacity = 0;
213 return status;
214 }
215
216 return psa_key_derivation_get_capacity(operation, capacity);
217#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
218}
219
220psa_status_t tfm_crypto_key_derivation_set_capacity(psa_invec in_vec[],
221 size_t in_len,
222 psa_outvec out_vec[],
223 size_t out_len)
224{
225#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
226 return PSA_ERROR_NOT_SUPPORTED;
227#else
228 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100229
230 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100231
232 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100233 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100234 }
235 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
236
237 uint32_t handle = iov->op_handle;
238 size_t capacity = iov->capacity;
239 psa_key_derivation_operation_t *operation = NULL;
240
241 /* Look up the corresponding operation context */
242 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
243 handle,
244 (void **)&operation);
245 if (status != PSA_SUCCESS) {
246 return status;
247 }
248
249 return psa_key_derivation_set_capacity(operation, capacity);
250#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
251}
252
253psa_status_t tfm_crypto_key_derivation_input_bytes(psa_invec in_vec[],
254 size_t in_len,
255 psa_outvec out_vec[],
256 size_t out_len)
257{
258#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
259 return PSA_ERROR_NOT_SUPPORTED;
260#else
261 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100262
263 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100264
265 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100266 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100267 }
268 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
269
270 uint32_t handle = iov->op_handle;
271 psa_key_derivation_step_t step = iov->step;
272 const uint8_t *data = in_vec[1].base;
273 size_t data_length = in_vec[1].len;
274 psa_key_derivation_operation_t *operation = NULL;
275
276 /* Look up the corresponding operation context */
277 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
278 handle,
279 (void **)&operation);
280 if (status != PSA_SUCCESS) {
281 return status;
282 }
283
Summer Qin359167d2021-07-05 18:11:50 +0800284 if (operation->MBEDTLS_PRIVATE(alg) == TFM_CRYPTO_ALG_HUK_DERIVATION) {
Jamie Fox044bd8e2020-02-20 13:34:57 +0000285 return tfm_crypto_huk_derivation_input_bytes(operation, step, data,
286 data_length);
287 } else {
288 return psa_key_derivation_input_bytes(operation, step, data,
289 data_length);
290 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100291#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
292}
293
294psa_status_t tfm_crypto_key_derivation_output_bytes(psa_invec in_vec[],
295 size_t in_len,
296 psa_outvec out_vec[],
297 size_t out_len)
298{
299#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
300 return PSA_ERROR_NOT_SUPPORTED;
301#else
302 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100303
304 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100305
306 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100307 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100308 }
309 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
310
311 uint32_t handle = iov->op_handle;
312 uint8_t *output = out_vec[0].base;
313 size_t output_length = out_vec[0].len;
314 psa_key_derivation_operation_t *operation = NULL;
315
316 /* Look up the corresponding operation context */
317 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
318 handle,
319 (void **)&operation);
320 if (status != PSA_SUCCESS) {
321 return status;
322 }
323
324 return psa_key_derivation_output_bytes(operation, output, output_length);
325#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
326}
327
328psa_status_t tfm_crypto_key_derivation_input_key(psa_invec in_vec[],
329 size_t in_len,
330 psa_outvec out_vec[],
331 size_t out_len)
332{
333#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
334 return PSA_ERROR_NOT_SUPPORTED;
335#else
336 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100337
338 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100339
340 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100341 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100342 }
343 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100344 uint32_t handle = iov->op_handle;
Maulik Patel28659c42021-01-06 14:09:22 +0000345 psa_key_id_t key_id = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100346 psa_key_derivation_step_t step = iov->step;
347 psa_key_derivation_operation_t *operation = NULL;
Maulik Patel28659c42021-01-06 14:09:22 +0000348 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100349
David Hu105b4872021-05-19 16:43:19 +0800350 status = tfm_crypto_check_handle_owner(key_id);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100351 if (status != PSA_SUCCESS) {
352 return status;
353 }
354
355 /* Look up the corresponding operation context */
356 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
357 handle,
358 (void **)&operation);
359 if (status != PSA_SUCCESS) {
360 return status;
361 }
362
Maulik Patel28659c42021-01-06 14:09:22 +0000363 status = tfm_crypto_encode_id_and_owner(key_id, &encoded_key);
364 if (status != PSA_SUCCESS) {
365 return status;
366 }
367
368 return psa_key_derivation_input_key(operation, step, encoded_key);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100369#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
370}
371
372psa_status_t tfm_crypto_key_derivation_output_key(psa_invec in_vec[],
373 size_t in_len,
374 psa_outvec out_vec[],
375 size_t out_len)
376{
377#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
378 return PSA_ERROR_NOT_SUPPORTED;
379#else
380 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100381
382 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 2, 2, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100383
384 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Soby Mathewd7b79f22020-05-21 15:06:54 +0100385 (in_vec[1].len != sizeof(struct psa_client_key_attributes_s)) ||
Maulik Patel28659c42021-01-06 14:09:22 +0000386 (out_vec[0].len != sizeof(psa_key_id_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100387 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100388 }
389 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
390
391 uint32_t handle = iov->op_handle;
Soby Mathewd7b79f22020-05-21 15:06:54 +0100392 const struct psa_client_key_attributes_s *client_key_attr = in_vec[1].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100393 psa_key_derivation_operation_t *operation = NULL;
Maulik Patel28659c42021-01-06 14:09:22 +0000394 psa_key_id_t *key_handle = out_vec[0].base;
Jamie Fox98ab4412020-01-17 17:12:30 +0000395 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
396 int32_t partition_id;
Jamie Fox99360e82020-02-20 16:00:09 +0000397 uint32_t index;
Maulik Patel28659c42021-01-06 14:09:22 +0000398 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100399
400 /* Look up the corresponding operation context */
401 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
402 handle,
403 (void **)&operation);
404 if (status != PSA_SUCCESS) {
405 return status;
406 }
Jamie Fox99360e82020-02-20 16:00:09 +0000407
408 status = tfm_crypto_check_key_storage(&index);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100409 if (status != PSA_SUCCESS) {
410 return status;
411 }
Jamie Fox99360e82020-02-20 16:00:09 +0000412
Jamie Fox98ab4412020-01-17 17:12:30 +0000413 status = tfm_crypto_get_caller_id(&partition_id);
414 if (status != PSA_SUCCESS) {
415 return status;
416 }
417
418 status = tfm_crypto_key_attributes_from_client(client_key_attr,
419 partition_id,
420 &key_attributes);
421 if (status != PSA_SUCCESS) {
422 return status;
423 }
424
Summer Qin359167d2021-07-05 18:11:50 +0800425 if (operation->MBEDTLS_PRIVATE(alg) == TFM_CRYPTO_ALG_HUK_DERIVATION) {
Jamie Fox98ab4412020-01-17 17:12:30 +0000426 status = tfm_crypto_huk_derivation_output_key(&key_attributes,
Maulik Patel28659c42021-01-06 14:09:22 +0000427 operation, &encoded_key);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000428 } else {
Jamie Fox98ab4412020-01-17 17:12:30 +0000429 status = psa_key_derivation_output_key(&key_attributes, operation,
Maulik Patel28659c42021-01-06 14:09:22 +0000430 &encoded_key);
Jamie Fox044bd8e2020-02-20 13:34:57 +0000431 }
David Hu105b4872021-05-19 16:43:19 +0800432#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
Summer Qin359167d2021-07-05 18:11:50 +0800433 *key_handle = encoded_key.MBEDTLS_PRIVATE(key_id);
David Hu105b4872021-05-19 16:43:19 +0800434#else
435 *key_handle = (psa_key_id_t)encoded_key;
436#endif
Maulik Patel28659c42021-01-06 14:09:22 +0000437
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100438 if (status == PSA_SUCCESS) {
Jamie Fox99360e82020-02-20 16:00:09 +0000439 status = tfm_crypto_set_key_storage(index, *key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100440 }
Jamie Fox99360e82020-02-20 16:00:09 +0000441
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100442 return status;
443#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
444}
445
446psa_status_t tfm_crypto_key_derivation_abort(psa_invec in_vec[],
447 size_t in_len,
448 psa_outvec out_vec[],
449 size_t out_len)
450{
451#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
452 return PSA_ERROR_NOT_SUPPORTED;
453#else
454 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100455
456 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100457
458 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
459 (out_vec[0].len != sizeof(uint32_t))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100460 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100461 }
462 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
463
464 uint32_t handle = iov->op_handle;
465 uint32_t *handle_out = out_vec[0].base;
466 psa_key_derivation_operation_t *operation = NULL;
467
468 /* Init the handle in the operation with the one passed from the iov */
469 *handle_out = iov->op_handle;
470
471 /* Look up the corresponding operation context */
472 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
473 handle,
474 (void **)&operation);
475 if (status != PSA_SUCCESS) {
476 /* Operation does not exist, so abort has no effect */
477 return PSA_SUCCESS;
478 }
479
480 *handle_out = handle;
481
Summer Qin359167d2021-07-05 18:11:50 +0800482 if (operation->MBEDTLS_PRIVATE(alg) == TFM_CRYPTO_ALG_HUK_DERIVATION) {
Jamie Fox044bd8e2020-02-20 13:34:57 +0000483 status = tfm_crypto_huk_derivation_abort(operation);
484 } else {
485 status = psa_key_derivation_abort(operation);
486 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100487 if (status != PSA_SUCCESS) {
488 /* Release the operation context, ignore if the operation fails. */
489 (void)tfm_crypto_operation_release(handle_out);
490 return status;
491 }
492
493 status = tfm_crypto_operation_release(handle_out);
494
495 return status;
496#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
497}
498
499psa_status_t tfm_crypto_key_derivation_key_agreement(psa_invec in_vec[],
500 size_t in_len,
501 psa_outvec out_vec[],
502 size_t out_len)
503{
504#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
505 return PSA_ERROR_NOT_SUPPORTED;
506#else
507 psa_status_t status;
Soby Mathewd8abdfd2020-10-14 10:28:01 +0100508
509 CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 0, 0);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100510
511 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100512 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100513 }
514 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
515
516 uint32_t handle = iov->op_handle;
Maulik Patel28659c42021-01-06 14:09:22 +0000517 psa_key_id_t private_key = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100518 const uint8_t *peer_key = in_vec[1].base;
519 size_t peer_key_length = in_vec[1].len;
520 psa_key_derivation_operation_t *operation = NULL;
521 psa_key_derivation_step_t step = iov->step;
Maulik Patel28659c42021-01-06 14:09:22 +0000522 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100523
David Hu105b4872021-05-19 16:43:19 +0800524 status = tfm_crypto_check_handle_owner(private_key);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100525 if (status != PSA_SUCCESS) {
526 return status;
527 }
528
529 /* Look up the corresponding operation context */
530 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
531 handle,
532 (void **)&operation);
533 if (status != PSA_SUCCESS) {
534 return status;
535 }
536
Maulik Patel28659c42021-01-06 14:09:22 +0000537 status = tfm_crypto_encode_id_and_owner(private_key, &encoded_key);
538 if (status != PSA_SUCCESS) {
539 return status;
540 }
541
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100542 return psa_key_derivation_key_agreement(operation, step,
Maulik Patel28659c42021-01-06 14:09:22 +0000543 encoded_key,
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100544 peer_key,
545 peer_key_length);
546#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
547}
548
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100549psa_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)) {
Soby Mathewc6e89362020-10-19 16:55:16 +0100561 return PSA_ERROR_PROGRAMMER_ERROR;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100562 }
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;
Maulik Patel28659c42021-01-06 14:09:22 +0000567 psa_key_id_t private_key = iov->key_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100568 const uint8_t *peer_key = in_vec[1].base;
569 size_t peer_key_length = in_vec[1].len;
Maulik Patel28659c42021-01-06 14:09:22 +0000570 mbedtls_svc_key_id_t encoded_key;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100571
David Hu105b4872021-05-19 16:43:19 +0800572 psa_status_t status = tfm_crypto_check_handle_owner(private_key);
Maulik Patel28659c42021-01-06 14:09:22 +0000573
574 if (status != PSA_SUCCESS) {
575 return status;
576 }
577
578 status = tfm_crypto_encode_id_and_owner(private_key, &encoded_key);
579 if (status != PSA_SUCCESS) {
580 return status;
581 }
582
583 return psa_raw_key_agreement(alg, encoded_key, peer_key, peer_key_length,
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100584 output, output_size, &out_vec[0].len);
585#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
586}
587/*!@}*/