blob: 00cf946eff966caece602781c4aa7af32041aa84 [file] [log] [blame]
Antonio de Angelis8908f472018-08-31 15:44:25 +01001/*
Antonio de Angelis377a1552018-11-22 17:02:40 +00002 * Copyright (c) 2018-2019, 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
36/**
37 * \brief Open a handle to the hardware unique key (HUK).
38 *
39 * \note As persistent keys are not yet supported by TF-M Crypto, this function
40 * allocates an empty volatile key to get a valid key handle.
41 *
42 * \param[in] lifetime The lifetime of the key
43 * \param[out] handle On success, a handle to the HUK
44 *
45 * \return Return values as described in \ref psa_status_t
46 */
Kevin Peng96f802e2019-12-26 16:10:25 +080047#ifndef TFM_CRYPTO_KEY_MODULE_DISABLED
Jamie Foxdadb4e82019-09-03 17:59:41 +010048static psa_status_t tfm_crypto_open_huk(psa_key_lifetime_t lifetime,
49 psa_key_handle_t *key_handle)
50{
51 psa_status_t status;
52 int32_t partition_id;
53 uint32_t i;
54 psa_key_policy_t huk_policy = PSA_KEY_POLICY_INIT;
55
56 /* The HUK has a persistent lifetime */
57 if (lifetime != PSA_KEY_LIFETIME_PERSISTENT) {
58 return PSA_ERROR_INVALID_ARGUMENT;
59 }
60
61 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
62 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
63 break;
64 }
65 }
66
67 if (i == TFM_CRYPTO_MAX_KEY_HANDLES) {
68 return PSA_ERROR_INSUFFICIENT_MEMORY;
69 }
70
71 status = tfm_crypto_get_caller_id(&partition_id);
72 if (status != PSA_SUCCESS) {
73 return status;
74 }
75
76 /* Allocate a transient key to get a valid key handle */
77 status = psa_allocate_key(key_handle);
78 if (status != PSA_SUCCESS) {
79 return status;
80 }
81
82 /* The HUK can only be used to derive other keys */
83 huk_policy.usage = PSA_KEY_USAGE_DERIVE;
84 huk_policy.alg = TFM_CRYPTO_ALG_HUK_DERIVATION;
85 status = psa_set_key_policy(*key_handle, &huk_policy);
86 if (status != PSA_SUCCESS) {
87 return status;
88 }
89
90 /* Import zero data to the HUK handle to prevent further modification */
91 status = psa_import_key(*key_handle, PSA_KEY_TYPE_RAW_DATA, NULL, 0);
92
93 if (status == PSA_SUCCESS) {
94 handle_owner[i].owner = partition_id;
95 handle_owner[i].handle = *key_handle;
96 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
97 }
98
99 return status;
100}
Kevin Peng8d11bd12019-12-25 17:41:22 +0800101#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxdadb4e82019-09-03 17:59:41 +0100102
Antonio de Angelis8908f472018-08-31 15:44:25 +0100103/*!
104 * \defgroup public Public functions
105 *
106 */
107
108/*!@{*/
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100109psa_status_t tfm_crypto_check_handle_owner(psa_key_handle_t handle,
110 uint32_t *index)
111{
Kevin Peng96f802e2019-12-26 16:10:25 +0800112#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100113 return PSA_ERROR_NOT_SUPPORTED;
114#else
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100115 int32_t partition_id = 0;
116 uint32_t i = 0;
117 psa_status_t status;
118
119 status = tfm_crypto_get_caller_id(&partition_id);
120 if (status != PSA_SUCCESS) {
121 return status;
122 }
123
124 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
125 if (handle_owner[i].in_use && handle_owner[i].handle == handle) {
126 if (handle_owner[i].owner == partition_id) {
127 if (index != NULL) {
128 *index = i;
129 }
130 return PSA_SUCCESS;
131 } else {
132 return PSA_ERROR_NOT_PERMITTED;
133 }
134 }
135 }
136
137 return PSA_ERROR_INVALID_HANDLE;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100138#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100139}
140
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100141psa_status_t tfm_crypto_allocate_key(psa_invec in_vec[],
142 size_t in_len,
143 psa_outvec out_vec[],
144 size_t out_len)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100145{
Kevin Peng96f802e2019-12-26 16:10:25 +0800146#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100147 return PSA_ERROR_NOT_SUPPORTED;
148#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100149 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800150 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000151 }
152
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100153 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
154 (out_vec[0].len != sizeof(psa_key_handle_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800155 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000156 }
157
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100158 psa_key_handle_t *key_handle = out_vec[0].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100159 uint32_t i = 0;
160 int32_t partition_id = 0;
161 bool empty_found = false;
162 psa_status_t status;
Jamie Foxefd82732018-11-26 10:34:32 +0000163
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100164 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
165 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
166 empty_found = true;
167 break;
168 }
169 }
170
171 if (!empty_found) {
172 return PSA_ERROR_INSUFFICIENT_MEMORY;
173 }
174
175 status = tfm_crypto_get_caller_id(&partition_id);
176 if (status != PSA_SUCCESS) {
177 return status;
178 }
179
180 status = psa_allocate_key(key_handle);
181
182 if (status == PSA_SUCCESS) {
183 handle_owner[i].owner = partition_id;
184 handle_owner[i].handle = *key_handle;
185 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
186 }
187
188 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100189#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000190}
191
Jamie Foxdadb4e82019-09-03 17:59:41 +0100192psa_status_t tfm_crypto_open_key(psa_invec in_vec[],
193 size_t in_len,
194 psa_outvec out_vec[],
195 size_t out_len)
196{
Kevin Peng96f802e2019-12-26 16:10:25 +0800197#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Jamie Foxdadb4e82019-09-03 17:59:41 +0100198 return PSA_ERROR_NOT_SUPPORTED;
199#else
200 if ((in_len != 2) || (out_len != 1)) {
201 return PSA_ERROR_CONNECTION_REFUSED;
202 }
203
204 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
205 (in_vec[1].len != sizeof(psa_key_id_t)) ||
206 (out_vec[0].len != sizeof(psa_key_handle_t))) {
207 return PSA_ERROR_CONNECTION_REFUSED;
208 }
209
210 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
211 psa_key_lifetime_t lifetime = iov->lifetime;
212 psa_key_id_t id = *((psa_key_id_t *)in_vec[1].base);
213 psa_key_handle_t *key_handle = out_vec[0].base;
214
215 /* FIXME: Persistent key APIs are not supported in general, so use a
216 * specific implementation to open a handle to the HUK.
217 */
218 if (id == TFM_CRYPTO_KEY_ID_HUK) {
219 return tfm_crypto_open_huk(lifetime, key_handle);
220 } else {
221 return PSA_ERROR_NOT_SUPPORTED;
222 }
223#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
224}
225
226psa_status_t tfm_crypto_close_key(psa_invec in_vec[],
227 size_t in_len,
228 psa_outvec out_vec[],
229 size_t out_len)
230{
Kevin Peng96f802e2019-12-26 16:10:25 +0800231#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Jamie Foxdadb4e82019-09-03 17:59:41 +0100232 return PSA_ERROR_NOT_SUPPORTED;
233#else
234 (void)out_vec;
235
236 if ((in_len != 1) || (out_len != 0)) {
237 return PSA_ERROR_CONNECTION_REFUSED;
238 }
239
240 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
241 return PSA_ERROR_CONNECTION_REFUSED;
242 }
243 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
244
245 psa_key_handle_t key = iov->key_handle;
246 uint32_t index;
247 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
248
249 if (status != PSA_SUCCESS) {
250 return status;
251 }
252
253 status = psa_close_key(key);
254
255 if (status == PSA_SUCCESS) {
256 handle_owner[index].owner = 0;
257 handle_owner[index].handle = 0;
258 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
259 }
260
261 return status;
262#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
263}
264
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000265psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
266 size_t in_len,
267 psa_outvec out_vec[],
268 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100269{
Kevin Peng96f802e2019-12-26 16:10:25 +0800270#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100271 return PSA_ERROR_NOT_SUPPORTED;
272#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100273 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100274
Antonio de Angelis4743e672019-04-11 11:38:48 +0100275 if ((in_len != 2) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800276 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000277 }
278
Antonio de Angelis4743e672019-04-11 11:38:48 +0100279 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800280 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000281 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100282 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000283
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100284 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100285 psa_key_type_t type = iov->type;
286 const uint8_t *data = in_vec[1].base;
287 size_t data_length = in_vec[1].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100288 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
289
290 if (status != PSA_SUCCESS) {
291 return status;
292 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000293
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100294 return psa_import_key(key, type, data, data_length);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100295#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100296}
297
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000298psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
299 size_t in_len,
300 psa_outvec out_vec[],
301 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100302{
Kevin Peng96f802e2019-12-26 16:10:25 +0800303#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100304 return PSA_ERROR_NOT_SUPPORTED;
305#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100306 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100307
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000308 if ((in_len != 1) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800309 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000310 }
311
Antonio de Angelis4743e672019-04-11 11:38:48 +0100312 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800313 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000314 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100315 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000316
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100317 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100318 uint32_t index;
319 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000320
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100321 if (status != PSA_SUCCESS) {
322 return status;
323 }
324
325 status = psa_destroy_key(key);
326
327 if (status == PSA_SUCCESS) {
328 handle_owner[index].owner = 0;
329 handle_owner[index].handle = 0;
330 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
331 }
332
333 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100334#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100335}
336
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000337psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
338 size_t in_len,
339 psa_outvec out_vec[],
340 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100341{
Kevin Peng96f802e2019-12-26 16:10:25 +0800342#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100343 return PSA_ERROR_NOT_SUPPORTED;
344#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000345 if ((in_len != 1) || (out_len != 2)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800346 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000347 }
348
Antonio de Angelis4743e672019-04-11 11:38:48 +0100349 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000350 (out_vec[0].len != sizeof(psa_key_type_t)) ||
351 (out_vec[1].len != sizeof(size_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800352 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000353 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100354 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Foxefd82732018-11-26 10:34:32 +0000355
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100356 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000357 psa_key_type_t *type = out_vec[0].base;
358 size_t *bits = out_vec[1].base;
359
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100360 return psa_get_key_information(key, type, bits);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100361#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100362}
363
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000364psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
365 size_t in_len,
366 psa_outvec out_vec[],
367 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100368{
Kevin Peng96f802e2019-12-26 16:10:25 +0800369#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100370 return PSA_ERROR_NOT_SUPPORTED;
371#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000372 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800373 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100374 }
375
Antonio de Angelis4743e672019-04-11 11:38:48 +0100376 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800377 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100378 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100379 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100380
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100381 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000382 uint8_t *data = out_vec[0].base;
383 size_t data_size = out_vec[0].len;
384
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100385 return psa_export_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100386#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100387}
388
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000389psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
390 size_t in_len,
391 psa_outvec out_vec[],
392 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100393{
Kevin Peng96f802e2019-12-26 16:10:25 +0800394#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100395 return PSA_ERROR_NOT_SUPPORTED;
396#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100397 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800398 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100399 }
Hugues de Valon8b442442019-02-19 14:30:52 +0000400
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100401 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800402 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100403 }
404 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
405
406 psa_key_handle_t key = iov->key_handle;
407 uint8_t *data = out_vec[0].base;
408 size_t data_size = out_vec[0].len;
409
410 return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100411#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100412}
413
414psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
415 size_t in_len,
416 psa_outvec out_vec[],
417 size_t out_len)
418{
Kevin Peng96f802e2019-12-26 16:10:25 +0800419#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100420 return PSA_ERROR_NOT_SUPPORTED;
421#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100422 (void)out_vec;
423
424 if ((in_len != 3) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800425 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100426 }
427
428 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
429 (in_vec[1].len != sizeof(psa_key_handle_t)) ||
430 (in_vec[2].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800431 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100432 }
433 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
434
435 psa_key_handle_t source_handle = iov->key_handle;
436 psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
437 const psa_key_policy_t *policy = in_vec[2].base;
438
439 return psa_copy_key(source_handle, target_handle, policy);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100440#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100441}
Jamie Foxefd82732018-11-26 10:34:32 +0000442
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000443psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
444 size_t in_len,
445 psa_outvec out_vec[],
446 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000447{
Kevin Peng96f802e2019-12-26 16:10:25 +0800448#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100449 return PSA_ERROR_NOT_SUPPORTED;
450#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100451 (void)out_vec;
Jamie Foxefd82732018-11-26 10:34:32 +0000452
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000453 if ((in_len != 2) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800454 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000455 }
456
Antonio de Angelis4743e672019-04-11 11:38:48 +0100457 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000458 (in_vec[1].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800459 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000460 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100461 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000462
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100463 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000464 const psa_key_policy_t *policy = in_vec[1].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100465 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000466
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100467 if (status == PSA_SUCCESS) {
468 return psa_set_key_policy(key, policy);
469 } else {
470 return status;
471 }
Antonio de Angelis7740b382019-07-16 10:59:25 +0100472#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000473}
474
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000475psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
476 size_t in_len,
477 psa_outvec out_vec[],
478 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000479{
Kevin Peng96f802e2019-12-26 16:10:25 +0800480#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100481 return PSA_ERROR_NOT_SUPPORTED;
482#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000483 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800484 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000485 }
486
Antonio de Angelis4743e672019-04-11 11:38:48 +0100487 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000488 (out_vec[0].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800489 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000490 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100491 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000492
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100493 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000494 psa_key_policy_t *policy = out_vec[0].base;
495
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100496 return psa_get_key_policy(key, policy);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100497#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000498}
499
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000500psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
501 size_t in_len,
502 psa_outvec out_vec[],
503 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000504{
Kevin Peng96f802e2019-12-26 16:10:25 +0800505#ifdef TFM_CRYPTO_KEY_MODULE_DISABLED
Antonio de Angelis7740b382019-07-16 10:59:25 +0100506 return PSA_ERROR_NOT_SUPPORTED;
507#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000508 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800509 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000510 }
511
Antonio de Angelis4743e672019-04-11 11:38:48 +0100512 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000513 (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800514 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000515 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100516 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000517
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100518 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000519 psa_key_lifetime_t *lifetime = out_vec[0].base;
520
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100521 return psa_get_key_lifetime(key, lifetime);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100522#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000523}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100524/*!@}*/