blob: 16b6bc1fbfd491aac3e92cff75e865db4c385fa0 [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
Antonio de Angelis7740b382019-07-16 10:59:25 +010031#if (TFM_CRYPTO_KEY_MODULE_DISABLED == 0)
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 */
47static psa_status_t tfm_crypto_open_huk(psa_key_lifetime_t lifetime,
48 psa_key_handle_t *key_handle)
49{
50 psa_status_t status;
51 int32_t partition_id;
52 uint32_t i;
53 psa_key_policy_t huk_policy = PSA_KEY_POLICY_INIT;
54
55 /* The HUK has a persistent lifetime */
56 if (lifetime != PSA_KEY_LIFETIME_PERSISTENT) {
57 return PSA_ERROR_INVALID_ARGUMENT;
58 }
59
60 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
61 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
62 break;
63 }
64 }
65
66 if (i == TFM_CRYPTO_MAX_KEY_HANDLES) {
67 return PSA_ERROR_INSUFFICIENT_MEMORY;
68 }
69
70 status = tfm_crypto_get_caller_id(&partition_id);
71 if (status != PSA_SUCCESS) {
72 return status;
73 }
74
75 /* Allocate a transient key to get a valid key handle */
76 status = psa_allocate_key(key_handle);
77 if (status != PSA_SUCCESS) {
78 return status;
79 }
80
81 /* The HUK can only be used to derive other keys */
82 huk_policy.usage = PSA_KEY_USAGE_DERIVE;
83 huk_policy.alg = TFM_CRYPTO_ALG_HUK_DERIVATION;
84 status = psa_set_key_policy(*key_handle, &huk_policy);
85 if (status != PSA_SUCCESS) {
86 return status;
87 }
88
89 /* Import zero data to the HUK handle to prevent further modification */
90 status = psa_import_key(*key_handle, PSA_KEY_TYPE_RAW_DATA, NULL, 0);
91
92 if (status == PSA_SUCCESS) {
93 handle_owner[i].owner = partition_id;
94 handle_owner[i].handle = *key_handle;
95 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
96 }
97
98 return status;
99}
100
Antonio de Angelis8908f472018-08-31 15:44:25 +0100101/*!
102 * \defgroup public Public functions
103 *
104 */
105
106/*!@{*/
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100107psa_status_t tfm_crypto_check_handle_owner(psa_key_handle_t handle,
108 uint32_t *index)
109{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100110#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
111 return PSA_ERROR_NOT_SUPPORTED;
112#else
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100113 int32_t partition_id = 0;
114 uint32_t i = 0;
115 psa_status_t status;
116
117 status = tfm_crypto_get_caller_id(&partition_id);
118 if (status != PSA_SUCCESS) {
119 return status;
120 }
121
122 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
123 if (handle_owner[i].in_use && handle_owner[i].handle == handle) {
124 if (handle_owner[i].owner == partition_id) {
125 if (index != NULL) {
126 *index = i;
127 }
128 return PSA_SUCCESS;
129 } else {
130 return PSA_ERROR_NOT_PERMITTED;
131 }
132 }
133 }
134
135 return PSA_ERROR_INVALID_HANDLE;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100136#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100137}
138
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100139psa_status_t tfm_crypto_allocate_key(psa_invec in_vec[],
140 size_t in_len,
141 psa_outvec out_vec[],
142 size_t out_len)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100143{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100144#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
145 return PSA_ERROR_NOT_SUPPORTED;
146#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100147 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800148 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000149 }
150
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100151 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
152 (out_vec[0].len != sizeof(psa_key_handle_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800153 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000154 }
155
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100156 psa_key_handle_t *key_handle = out_vec[0].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100157 uint32_t i = 0;
158 int32_t partition_id = 0;
159 bool empty_found = false;
160 psa_status_t status;
Jamie Foxefd82732018-11-26 10:34:32 +0000161
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100162 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
163 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
164 empty_found = true;
165 break;
166 }
167 }
168
169 if (!empty_found) {
170 return PSA_ERROR_INSUFFICIENT_MEMORY;
171 }
172
173 status = tfm_crypto_get_caller_id(&partition_id);
174 if (status != PSA_SUCCESS) {
175 return status;
176 }
177
178 status = psa_allocate_key(key_handle);
179
180 if (status == PSA_SUCCESS) {
181 handle_owner[i].owner = partition_id;
182 handle_owner[i].handle = *key_handle;
183 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
184 }
185
186 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100187#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000188}
189
Jamie Foxdadb4e82019-09-03 17:59:41 +0100190psa_status_t tfm_crypto_open_key(psa_invec in_vec[],
191 size_t in_len,
192 psa_outvec out_vec[],
193 size_t out_len)
194{
195#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
196 return PSA_ERROR_NOT_SUPPORTED;
197#else
198 if ((in_len != 2) || (out_len != 1)) {
199 return PSA_ERROR_CONNECTION_REFUSED;
200 }
201
202 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
203 (in_vec[1].len != sizeof(psa_key_id_t)) ||
204 (out_vec[0].len != sizeof(psa_key_handle_t))) {
205 return PSA_ERROR_CONNECTION_REFUSED;
206 }
207
208 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
209 psa_key_lifetime_t lifetime = iov->lifetime;
210 psa_key_id_t id = *((psa_key_id_t *)in_vec[1].base);
211 psa_key_handle_t *key_handle = out_vec[0].base;
212
213 /* FIXME: Persistent key APIs are not supported in general, so use a
214 * specific implementation to open a handle to the HUK.
215 */
216 if (id == TFM_CRYPTO_KEY_ID_HUK) {
217 return tfm_crypto_open_huk(lifetime, key_handle);
218 } else {
219 return PSA_ERROR_NOT_SUPPORTED;
220 }
221#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
222}
223
224psa_status_t tfm_crypto_close_key(psa_invec in_vec[],
225 size_t in_len,
226 psa_outvec out_vec[],
227 size_t out_len)
228{
229#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
230 return PSA_ERROR_NOT_SUPPORTED;
231#else
232 (void)out_vec;
233
234 if ((in_len != 1) || (out_len != 0)) {
235 return PSA_ERROR_CONNECTION_REFUSED;
236 }
237
238 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
239 return PSA_ERROR_CONNECTION_REFUSED;
240 }
241 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
242
243 psa_key_handle_t key = iov->key_handle;
244 uint32_t index;
245 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
246
247 if (status != PSA_SUCCESS) {
248 return status;
249 }
250
251 status = psa_close_key(key);
252
253 if (status == PSA_SUCCESS) {
254 handle_owner[index].owner = 0;
255 handle_owner[index].handle = 0;
256 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
257 }
258
259 return status;
260#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
261}
262
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000263psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
264 size_t in_len,
265 psa_outvec out_vec[],
266 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100267{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100268#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
269 return PSA_ERROR_NOT_SUPPORTED;
270#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100271 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100272
Antonio de Angelis4743e672019-04-11 11:38:48 +0100273 if ((in_len != 2) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800274 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000275 }
276
Antonio de Angelis4743e672019-04-11 11:38:48 +0100277 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800278 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000279 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100280 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000281
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100282 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100283 psa_key_type_t type = iov->type;
284 const uint8_t *data = in_vec[1].base;
285 size_t data_length = in_vec[1].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100286 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
287
288 if (status != PSA_SUCCESS) {
289 return status;
290 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000291
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100292 return psa_import_key(key, type, data, data_length);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100293#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100294}
295
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000296psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
297 size_t in_len,
298 psa_outvec out_vec[],
299 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100300{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100301#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
302 return PSA_ERROR_NOT_SUPPORTED;
303#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100304 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100305
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000306 if ((in_len != 1) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800307 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000308 }
309
Antonio de Angelis4743e672019-04-11 11:38:48 +0100310 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800311 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000312 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100313 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000314
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100315 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100316 uint32_t index;
317 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000318
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100319 if (status != PSA_SUCCESS) {
320 return status;
321 }
322
323 status = psa_destroy_key(key);
324
325 if (status == PSA_SUCCESS) {
326 handle_owner[index].owner = 0;
327 handle_owner[index].handle = 0;
328 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
329 }
330
331 return status;
Antonio de Angelis7740b382019-07-16 10:59:25 +0100332#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100333}
334
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000335psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
336 size_t in_len,
337 psa_outvec out_vec[],
338 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100339{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100340#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
341 return PSA_ERROR_NOT_SUPPORTED;
342#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000343 if ((in_len != 1) || (out_len != 2)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800344 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000345 }
346
Antonio de Angelis4743e672019-04-11 11:38:48 +0100347 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000348 (out_vec[0].len != sizeof(psa_key_type_t)) ||
349 (out_vec[1].len != sizeof(size_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800350 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000351 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100352 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Foxefd82732018-11-26 10:34:32 +0000353
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100354 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000355 psa_key_type_t *type = out_vec[0].base;
356 size_t *bits = out_vec[1].base;
357
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100358 return psa_get_key_information(key, type, bits);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100359#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100360}
361
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000362psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
363 size_t in_len,
364 psa_outvec out_vec[],
365 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100366{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100367#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
368 return PSA_ERROR_NOT_SUPPORTED;
369#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000370 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800371 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100372 }
373
Antonio de Angelis4743e672019-04-11 11:38:48 +0100374 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800375 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100376 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100377 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100378
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100379 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000380 uint8_t *data = out_vec[0].base;
381 size_t data_size = out_vec[0].len;
382
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100383 return psa_export_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100384#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100385}
386
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000387psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
388 size_t in_len,
389 psa_outvec out_vec[],
390 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100391{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100392#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
393 return PSA_ERROR_NOT_SUPPORTED;
394#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100395 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800396 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100397 }
Hugues de Valon8b442442019-02-19 14:30:52 +0000398
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100399 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800400 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100401 }
402 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
403
404 psa_key_handle_t key = iov->key_handle;
405 uint8_t *data = out_vec[0].base;
406 size_t data_size = out_vec[0].len;
407
408 return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis7740b382019-07-16 10:59:25 +0100409#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100410}
411
412psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
413 size_t in_len,
414 psa_outvec out_vec[],
415 size_t out_len)
416{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100417#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
418 return PSA_ERROR_NOT_SUPPORTED;
419#else
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100420 (void)out_vec;
421
422 if ((in_len != 3) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800423 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100424 }
425
426 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
427 (in_vec[1].len != sizeof(psa_key_handle_t)) ||
428 (in_vec[2].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800429 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100430 }
431 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
432
433 psa_key_handle_t source_handle = iov->key_handle;
434 psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
435 const psa_key_policy_t *policy = in_vec[2].base;
436
437 return psa_copy_key(source_handle, target_handle, policy);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100438#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100439}
Jamie Foxefd82732018-11-26 10:34:32 +0000440
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000441psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
442 size_t in_len,
443 psa_outvec out_vec[],
444 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000445{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100446#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
447 return PSA_ERROR_NOT_SUPPORTED;
448#else
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100449 (void)out_vec;
Jamie Foxefd82732018-11-26 10:34:32 +0000450
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000451 if ((in_len != 2) || (out_len != 0)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800452 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000453 }
454
Antonio de Angelis4743e672019-04-11 11:38:48 +0100455 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000456 (in_vec[1].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800457 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000458 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100459 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000460
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100461 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000462 const psa_key_policy_t *policy = in_vec[1].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100463 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000464
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100465 if (status == PSA_SUCCESS) {
466 return psa_set_key_policy(key, policy);
467 } else {
468 return status;
469 }
Antonio de Angelis7740b382019-07-16 10:59:25 +0100470#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000471}
472
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000473psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
474 size_t in_len,
475 psa_outvec out_vec[],
476 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000477{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100478#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
479 return PSA_ERROR_NOT_SUPPORTED;
480#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000481 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800482 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000483 }
484
Antonio de Angelis4743e672019-04-11 11:38:48 +0100485 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000486 (out_vec[0].len != sizeof(psa_key_policy_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800487 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000488 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100489 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000490
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100491 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000492 psa_key_policy_t *policy = out_vec[0].base;
493
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100494 return psa_get_key_policy(key, policy);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100495#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000496}
497
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000498psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
499 size_t in_len,
500 psa_outvec out_vec[],
501 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000502{
Antonio de Angelis7740b382019-07-16 10:59:25 +0100503#if (TFM_CRYPTO_KEY_MODULE_DISABLED != 0)
504 return PSA_ERROR_NOT_SUPPORTED;
505#else
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000506 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800507 return PSA_ERROR_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000508 }
509
Antonio de Angelis4743e672019-04-11 11:38:48 +0100510 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000511 (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800512 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000513 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100514 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000515
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100516 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000517 psa_key_lifetime_t *lifetime = out_vec[0].base;
518
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100519 return psa_get_key_lifetime(key, lifetime);
Antonio de Angelis7740b382019-07-16 10:59:25 +0100520#endif /* TFM_CRYPTO_KEY_MODULE_DISABLED */
Jamie Foxefd82732018-11-26 10:34:32 +0000521}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100522/*!@}*/