blob: e88040d097ebf77b3b2c935ba3ed4e476e81b91d [file] [log] [blame]
Antonio de Angelis8908f472018-08-31 15:44:25 +01001/*
Antonio de Angelis04debbd2019-10-14 12:12:52 +01002 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
Antonio de Angelis8908f472018-08-31 15:44:25 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Jamie Foxefd82732018-11-26 10:34:32 +00008#include <stddef.h>
Jamie Fox0e54ebc2019-04-09 14:21:04 +01009#include <stdint.h>
Antonio de Angelis8908f472018-08-31 15:44:25 +010010
Summer Qin4b1d03b2019-07-02 14:56:08 +080011/* FixMe: Use PSA_ERROR_CONNECTION_REFUSED when performing parameter
Antonio de Angelis4743e672019-04-11 11:38:48 +010012 * 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 */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010016#include "tfm_mbedcrypto_include.h"
Antonio de Angelis4743e672019-04-11 11:38:48 +010017
Jamie Fox0e54ebc2019-04-09 14:21:04 +010018#include "tfm_crypto_api.h"
19#include "tfm_crypto_defs.h"
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010020#include <stdbool.h>
Jamie Fox82b87ca2018-12-11 16:41:11 +000021
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010022#ifndef TFM_CRYPTO_MAX_KEY_HANDLES
23#define TFM_CRYPTO_MAX_KEY_HANDLES (16)
24#endif
25struct tfm_crypto_handle_owner_s {
26 int32_t owner; /*!< Owner of the allocated handle */
27 psa_key_handle_t handle; /*!< Allocated handle */
28 uint8_t in_use; /*!< Flag to indicate if this in use */
29};
30
Kevin Peng96f802e2019-12-26 16:10:25 +080031#ifndef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010032static struct tfm_crypto_handle_owner_s
33 handle_owner[TFM_CRYPTO_MAX_KEY_HANDLES] = {0};
Antonio de Angelis7740b382019-07-16 10:59:25 +010034#endif
Jamie Foxdadb4e82019-09-03 17:59:41 +010035
Antonio de Angelis8908f472018-08-31 15:44:25 +010036/*!
37 * \defgroup public Public functions
38 *
39 */
40
41/*!@{*/
Jamie Fox98ab4412020-01-17 17:12:30 +000042psa_status_t tfm_crypto_key_attributes_from_client(
43 const psa_client_key_attributes_t *client_key_attr,
44 int32_t client_id,
45 psa_key_attributes_t *key_attributes)
46{
47 if (client_key_attr == NULL || key_attributes == NULL) {
48 return PSA_ERROR_PROGRAMMER_ERROR;
49 }
50
51 /* Domain parameters are not supported, ignore any passed by the client */
52 key_attributes->domain_parameters = NULL;
53 key_attributes->domain_parameters_size = 0;
54
55 /* Copy core key attributes from the client core key attributes */
56 key_attributes->core.type = client_key_attr->core.type;
57 key_attributes->core.lifetime = client_key_attr->core.lifetime;
58 key_attributes->core.policy = client_key_attr->core.policy;
59 key_attributes->core.bits = client_key_attr->core.bits;
60 key_attributes->core.flags = client_key_attr->core.flags;
61
62 /* Use the client key id as the key_id and its partition id as the owner */
63 key_attributes->core.id.key_id = client_key_attr->core.id;
64 key_attributes->core.id.owner = client_id;
65
66 return PSA_SUCCESS;
67}
68
69psa_status_t tfm_crypto_key_attributes_to_client(
70 const psa_key_attributes_t *key_attributes,
71 psa_client_key_attributes_t *client_key_attr)
72{
73 if (client_key_attr == NULL || key_attributes == NULL) {
74 return PSA_ERROR_PROGRAMMER_ERROR;
75 }
76
77 /* Domain parameters are not supported, avoid passing any to the client */
78 client_key_attr->domain_parameters = NULL;
79 client_key_attr->domain_parameters_size = 0;
80
81 /* Copy core key attributes to the client core key attributes */
82 client_key_attr->core.type = key_attributes->core.type;
83 client_key_attr->core.lifetime = key_attributes->core.lifetime;
84 client_key_attr->core.policy = key_attributes->core.policy;
85 client_key_attr->core.bits = key_attributes->core.bits;
86 client_key_attr->core.flags = key_attributes->core.flags;
87
88 /* Return the key_id as the client key id, do not return the owner */
89 client_key_attr->core.id = key_attributes->core.id.key_id;
90
91 return PSA_SUCCESS;
92}
93
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010094psa_status_t tfm_crypto_check_handle_owner(psa_key_handle_t handle,
95 uint32_t *index)
96{
Kevin Peng96f802e2019-12-26 16:10:25 +080097#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +010098 return PSA_ERROR_NOT_SUPPORTED;
99#else
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100100 int32_t partition_id = 0;
101 uint32_t i = 0;
102 psa_status_t status;
103
104 status = tfm_crypto_get_caller_id(&partition_id);
105 if (status != PSA_SUCCESS) {
106 return status;
107 }
108
109 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
110 if (handle_owner[i].in_use && handle_owner[i].handle == handle) {
111 if (handle_owner[i].owner == partition_id) {
112 if (index != NULL) {
113 *index = i;
114 }
115 return PSA_SUCCESS;
116 } else {
117 return PSA_ERROR_NOT_PERMITTED;
118 }
119 }
120 }
121
122 return PSA_ERROR_INVALID_HANDLE;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100123#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100124}
125
Jamie Fox99360e82020-02-20 16:00:09 +0000126psa_status_t tfm_crypto_check_key_storage(uint32_t *index)
127{
128#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
129 return PSA_ERROR_NOT_SUPPORTED;
130#else
131 uint32_t i;
132
133 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
134 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
135 *index = i;
136 return PSA_SUCCESS;
137 }
138 }
139
140 return PSA_ERROR_INSUFFICIENT_MEMORY;
141#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
142}
143
144psa_status_t tfm_crypto_set_key_storage(uint32_t index,
145 psa_key_handle_t key_handle)
146{
147#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
148 return PSA_ERROR_NOT_SUPPORTED;
149#else
150 psa_status_t status;
151 int32_t partition_id;
152
153 status = tfm_crypto_get_caller_id(&partition_id);
154 if (status != PSA_SUCCESS) {
155 return status;
156 }
157
158 handle_owner[index].owner = partition_id;
159 handle_owner[index].handle = key_handle;
160 handle_owner[index].in_use = TFM_CRYPTO_IN_USE;
161
162 return PSA_SUCCESS;
163#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
164}
165
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100166psa_status_t tfm_crypto_set_key_domain_parameters(psa_invec in_vec[],
167 size_t in_len,
168 psa_outvec out_vec[],
169 size_t out_len)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100170{
Kevin Peng96f802e2019-12-26 16:10:25 +0800171#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100172 return PSA_ERROR_NOT_SUPPORTED;
173#else
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100174 /* FixMe: To be implemented */
175 return PSA_ERROR_NOT_SUPPORTED;
176#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
177}
178
179psa_status_t tfm_crypto_get_key_domain_parameters(psa_invec in_vec[],
180 size_t in_len,
181 psa_outvec out_vec[],
182 size_t out_len)
183{
184#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
185 return PSA_ERROR_NOT_SUPPORTED;
186#else
187 /* FixMe: To be implemented */
188 return PSA_ERROR_NOT_SUPPORTED;
189#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
190}
191
192psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
193 size_t in_len,
194 psa_outvec out_vec[],
195 size_t out_len)
196{
197#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
198 return PSA_ERROR_NOT_SUPPORTED;
199#else
200
201 if ((in_len != 3) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800202 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000203 }
204
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100205 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000206 (in_vec[1].len != sizeof(psa_client_key_attributes_t)) ||
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100207 (out_vec[0].len != sizeof(psa_key_handle_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800208 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000209 }
Jamie Fox98ab4412020-01-17 17:12:30 +0000210 const psa_client_key_attributes_t *client_key_attr = in_vec[1].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100211 const uint8_t *data = in_vec[2].base;
212 size_t data_length = in_vec[2].len;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100213 psa_key_handle_t *key_handle = out_vec[0].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100214 psa_status_t status;
Jamie Fox98ab4412020-01-17 17:12:30 +0000215 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100216 uint32_t i = 0;
217 int32_t partition_id = 0;
218 bool empty_found = false;
Jamie Foxefd82732018-11-26 10:34:32 +0000219
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100220 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
221 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
222 empty_found = true;
223 break;
224 }
225 }
226
227 if (!empty_found) {
228 return PSA_ERROR_INSUFFICIENT_MEMORY;
229 }
230
231 status = tfm_crypto_get_caller_id(&partition_id);
232 if (status != PSA_SUCCESS) {
233 return status;
234 }
235
Jamie Fox98ab4412020-01-17 17:12:30 +0000236 status = tfm_crypto_key_attributes_from_client(client_key_attr,
237 partition_id,
238 &key_attributes);
239 if (status != PSA_SUCCESS) {
240 return status;
241 }
242
243 status = psa_import_key(&key_attributes, data, data_length, key_handle);
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100244
245 if (status == PSA_SUCCESS) {
246 handle_owner[i].owner = partition_id;
247 handle_owner[i].handle = *key_handle;
248 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
249 }
250
251 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100252#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000253}
254
Jamie Foxdadb4e82019-09-03 17:59:41 +0100255psa_status_t tfm_crypto_open_key(psa_invec in_vec[],
256 size_t in_len,
257 psa_outvec out_vec[],
258 size_t out_len)
259{
Kevin Peng96f802e2019-12-26 16:10:25 +0800260#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Jamie Foxdadb4e82019-09-03 17:59:41 +0100261 return PSA_ERROR_NOT_SUPPORTED;
262#else
263 if ((in_len != 2) || (out_len != 1)) {
264 return PSA_ERROR_CONNECTION_REFUSED;
265 }
266
267 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000268 (in_vec[1].len != sizeof(psa_app_key_id_t)) ||
Jamie Foxdadb4e82019-09-03 17:59:41 +0100269 (out_vec[0].len != sizeof(psa_key_handle_t))) {
270 return PSA_ERROR_CONNECTION_REFUSED;
271 }
272
Jamie Fox98ab4412020-01-17 17:12:30 +0000273 psa_app_key_id_t client_key_id = *((psa_app_key_id_t *)in_vec[1].base);
274 psa_key_handle_t *key_handle = out_vec[0].base;
275 psa_status_t status;
276 psa_key_id_t id;
277 int32_t partition_id;
278 uint32_t i;
279
280 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
281 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
282 break;
283 }
284 }
285
286 if (i == TFM_CRYPTO_MAX_KEY_HANDLES) {
287 return PSA_ERROR_INSUFFICIENT_MEMORY;
288 }
289
290 status = tfm_crypto_get_caller_id(&partition_id);
291 if (status != PSA_SUCCESS) {
292 return status;
293 }
294
295 /* Use the client key id as the key_id and its partition id as the owner */
296 id = (psa_key_id_t){ .key_id = client_key_id, .owner = partition_id };
297
298 status = psa_open_key(id, key_handle);
299
300 if (status == PSA_SUCCESS) {
301 handle_owner[i].owner = partition_id;
302 handle_owner[i].handle = *key_handle;
303 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
304 }
305
306 return status;
Jamie Foxdadb4e82019-09-03 17:59:41 +0100307#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
308}
309
310psa_status_t tfm_crypto_close_key(psa_invec in_vec[],
311 size_t in_len,
312 psa_outvec out_vec[],
313 size_t out_len)
314{
Kevin Peng96f802e2019-12-26 16:10:25 +0800315#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Jamie Foxdadb4e82019-09-03 17:59:41 +0100316 return PSA_ERROR_NOT_SUPPORTED;
317#else
318 (void)out_vec;
319
320 if ((in_len != 1) || (out_len != 0)) {
321 return PSA_ERROR_CONNECTION_REFUSED;
322 }
323
324 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
325 return PSA_ERROR_CONNECTION_REFUSED;
326 }
327 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
328
329 psa_key_handle_t key = iov->key_handle;
330 uint32_t index;
331 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
332
333 if (status != PSA_SUCCESS) {
334 return status;
335 }
336
337 status = psa_close_key(key);
338
339 if (status == PSA_SUCCESS) {
340 handle_owner[index].owner = 0;
341 handle_owner[index].handle = 0;
342 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
343 }
344
345 return status;
346#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
347}
348
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000349psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
350 size_t in_len,
351 psa_outvec out_vec[],
352 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100353{
Kevin Peng96f802e2019-12-26 16:10:25 +0800354#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100355 return PSA_ERROR_NOT_SUPPORTED;
356#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100357 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100358
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000359 if ((in_len != 1) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800360 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000361 }
362
Antonio de Angelis4743e672019-04-11 11:38:48 +0100363 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800364 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000365 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100366 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000367
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100368 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100369 uint32_t index;
370 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000371
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100372 if (status != PSA_SUCCESS) {
373 return status;
374 }
375
376 status = psa_destroy_key(key);
377
378 if (status == PSA_SUCCESS) {
379 handle_owner[index].owner = 0;
380 handle_owner[index].handle = 0;
381 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
382 }
383
384 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100385#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100386}
387
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100388psa_status_t tfm_crypto_get_key_attributes(psa_invec in_vec[],
389 size_t in_len,
390 psa_outvec out_vec[],
391 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100392{
Kevin Peng96f802e2019-12-26 16:10:25 +0800393#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100394 return PSA_ERROR_NOT_SUPPORTED;
395#else
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100396 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800397 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000398 }
399
Antonio de Angelis4743e672019-04-11 11:38:48 +0100400 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000401 (out_vec[0].len != sizeof(psa_client_key_attributes_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800402 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000403 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100404 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Foxefd82732018-11-26 10:34:32 +0000405
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100406 psa_key_handle_t key = iov->key_handle;
Jamie Fox98ab4412020-01-17 17:12:30 +0000407 psa_client_key_attributes_t *client_key_attr = out_vec[0].base;
408 psa_status_t status;
409 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000410
Jamie Fox98ab4412020-01-17 17:12:30 +0000411 status = tfm_crypto_check_handle_owner(key, NULL);
412 if (status != PSA_SUCCESS) {
413 return status;
414 }
415
416 status = psa_get_key_attributes(key, &key_attributes);
417
418 if (status == PSA_SUCCESS) {
419 status = tfm_crypto_key_attributes_to_client(&key_attributes,
420 client_key_attr);
421 }
422
423 return status;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100424#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
425}
426
427psa_status_t tfm_crypto_reset_key_attributes(psa_invec in_vec[],
428 size_t in_len,
429 psa_outvec out_vec[],
430 size_t out_len)
431{
432#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
433 return PSA_ERROR_NOT_SUPPORTED;
434#else
435 if ((in_len != 1) || (out_len != 1)) {
436 return PSA_ERROR_CONNECTION_REFUSED;
437 }
438
439 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000440 (out_vec[0].len != sizeof(psa_client_key_attributes_t))) {
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100441 return PSA_ERROR_CONNECTION_REFUSED;
442 }
443
Jamie Fox98ab4412020-01-17 17:12:30 +0000444 psa_client_key_attributes_t *client_key_attr = out_vec[0].base;
445 psa_status_t status;
446 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
447 int32_t partition_id;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100448
Jamie Fox98ab4412020-01-17 17:12:30 +0000449 status = tfm_crypto_get_caller_id(&partition_id);
450 if (status != PSA_SUCCESS) {
451 return status;
452 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100453
Jamie Fox98ab4412020-01-17 17:12:30 +0000454 status = tfm_crypto_key_attributes_from_client(client_key_attr,
455 partition_id,
456 &key_attributes);
457 if (status != PSA_SUCCESS) {
458 return status;
459 }
460
461 psa_reset_key_attributes(&key_attributes);
462
463 return tfm_crypto_key_attributes_to_client(&key_attributes,
464 client_key_attr);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100465#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100466}
467
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000468psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
469 size_t in_len,
470 psa_outvec out_vec[],
471 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100472{
Kevin Peng96f802e2019-12-26 16:10:25 +0800473#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100474 return PSA_ERROR_NOT_SUPPORTED;
475#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000476 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800477 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100478 }
479
Antonio de Angelis4743e672019-04-11 11:38:48 +0100480 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800481 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100482 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100483 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100484
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100485 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000486 uint8_t *data = out_vec[0].base;
487 size_t data_size = out_vec[0].len;
488
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100489 return psa_export_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100490#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100491}
492
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000493psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
494 size_t in_len,
495 psa_outvec out_vec[],
496 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100497{
Kevin Peng96f802e2019-12-26 16:10:25 +0800498#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100499 return PSA_ERROR_NOT_SUPPORTED;
500#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100501 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800502 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100503 }
Hugues de Valon8b442442019-02-19 14:30:52 +0000504
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100505 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800506 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100507 }
508 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
509
510 psa_key_handle_t key = iov->key_handle;
511 uint8_t *data = out_vec[0].base;
512 size_t data_size = out_vec[0].len;
513
514 return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100515#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100516}
517
518psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
519 size_t in_len,
520 psa_outvec out_vec[],
521 size_t out_len)
522{
Kevin Peng96f802e2019-12-26 16:10:25 +0800523#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100524 return PSA_ERROR_NOT_SUPPORTED;
525#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100526
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100527 if ((in_len != 2) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800528 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100529 }
530
531 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100532 (out_vec[0].len != sizeof(psa_key_handle_t)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000533 (in_vec[1].len != sizeof(psa_client_key_attributes_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800534 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100535 }
536 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
537
538 psa_key_handle_t source_handle = iov->key_handle;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100539 psa_key_handle_t *target_handle = out_vec[0].base;
Jamie Fox98ab4412020-01-17 17:12:30 +0000540 const psa_client_key_attributes_t *client_key_attr = in_vec[1].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100541 psa_status_t status;
Jamie Fox98ab4412020-01-17 17:12:30 +0000542 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100543 uint32_t i = 0;
544 int32_t partition_id = 0;
545 bool empty_found = false;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100546
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100547 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
548 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
549 empty_found = true;
550 break;
551 }
Jamie Foxefd82732018-11-26 10:34:32 +0000552 }
553
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100554 if (!empty_found) {
555 return PSA_ERROR_INSUFFICIENT_MEMORY;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000556 }
557
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100558 status = tfm_crypto_get_caller_id(&partition_id);
559 if (status != PSA_SUCCESS) {
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100560 return status;
561 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100562
Jamie Fox98ab4412020-01-17 17:12:30 +0000563 status = tfm_crypto_key_attributes_from_client(client_key_attr,
564 partition_id,
565 &key_attributes);
566 if (status != PSA_SUCCESS) {
567 return status;
568 }
569
570 status = psa_copy_key(source_handle, &key_attributes, target_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100571
572 if (status == PSA_SUCCESS) {
573 handle_owner[i].owner = partition_id;
574 handle_owner[i].handle = *target_handle;
575 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
576 }
577
578 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100579#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100580 return PSA_ERROR_NOT_SUPPORTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000581}
582
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100583psa_status_t tfm_crypto_generate_key(psa_invec in_vec[],
584 size_t in_len,
585 psa_outvec out_vec[],
586 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000587{
Kevin Peng96f802e2019-12-26 16:10:25 +0800588#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100589 return PSA_ERROR_NOT_SUPPORTED;
590#else
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100591 if ((in_len != 2) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800592 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000593 }
594
Antonio de Angelis4743e672019-04-11 11:38:48 +0100595 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox98ab4412020-01-17 17:12:30 +0000596 (in_vec[1].len != sizeof(psa_client_key_attributes_t)) ||
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100597 (out_vec[0].len != sizeof(psa_key_handle_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800598 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000599 }
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100600 psa_key_handle_t *key_handle = out_vec[0].base;
Jamie Fox98ab4412020-01-17 17:12:30 +0000601 const psa_client_key_attributes_t *client_key_attr = in_vec[1].base;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100602 psa_status_t status;
Jamie Fox98ab4412020-01-17 17:12:30 +0000603 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100604 uint32_t i = 0;
605 int32_t partition_id = 0;
606 bool empty_found = false;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000607
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100608 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
609 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
610 empty_found = true;
611 break;
612 }
Jamie Foxefd82732018-11-26 10:34:32 +0000613 }
614
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100615 if (!empty_found) {
616 return PSA_ERROR_INSUFFICIENT_MEMORY;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000617 }
618
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100619 status = tfm_crypto_get_caller_id(&partition_id);
620 if (status != PSA_SUCCESS) {
621 return status;
622 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000623
Jamie Fox98ab4412020-01-17 17:12:30 +0000624 status = tfm_crypto_key_attributes_from_client(client_key_attr,
625 partition_id,
626 &key_attributes);
627 if (status != PSA_SUCCESS) {
628 return status;
629 }
630
631 status = psa_generate_key(&key_attributes, key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100632
633 if (status == PSA_SUCCESS) {
634 handle_owner[i].owner = partition_id;
635 handle_owner[i].handle = *key_handle;
636 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
637 }
638
639 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100640#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000641}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100642/*!@}*/