blob: 65a72b75149dc8bea182f0ffd92194bcf948f110 [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
Antonio de Angelis4743e672019-04-11 11:38:48 +010011/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
12 * 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
31static struct tfm_crypto_handle_owner_s
32 handle_owner[TFM_CRYPTO_MAX_KEY_HANDLES] = {0};
Antonio de Angelis8908f472018-08-31 15:44:25 +010033/*!
34 * \defgroup public Public functions
35 *
36 */
37
38/*!@{*/
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010039psa_status_t tfm_crypto_check_handle_owner(psa_key_handle_t handle,
40 uint32_t *index)
41{
42 int32_t partition_id = 0;
43 uint32_t i = 0;
44 psa_status_t status;
45
46 status = tfm_crypto_get_caller_id(&partition_id);
47 if (status != PSA_SUCCESS) {
48 return status;
49 }
50
51 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
52 if (handle_owner[i].in_use && handle_owner[i].handle == handle) {
53 if (handle_owner[i].owner == partition_id) {
54 if (index != NULL) {
55 *index = i;
56 }
57 return PSA_SUCCESS;
58 } else {
59 return PSA_ERROR_NOT_PERMITTED;
60 }
61 }
62 }
63
64 return PSA_ERROR_INVALID_HANDLE;
65}
66
Jamie Fox0e54ebc2019-04-09 14:21:04 +010067psa_status_t tfm_crypto_allocate_key(psa_invec in_vec[],
68 size_t in_len,
69 psa_outvec out_vec[],
70 size_t out_len)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010071{
Jamie Fox0e54ebc2019-04-09 14:21:04 +010072 if ((in_len != 1) || (out_len != 1)) {
73 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +000074 }
75
Jamie Fox0e54ebc2019-04-09 14:21:04 +010076 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
77 (out_vec[0].len != sizeof(psa_key_handle_t))) {
78 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +000079 }
80
Jamie Fox0e54ebc2019-04-09 14:21:04 +010081 psa_key_handle_t *key_handle = out_vec[0].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010082 uint32_t i = 0;
83 int32_t partition_id = 0;
84 bool empty_found = false;
85 psa_status_t status;
Jamie Foxefd82732018-11-26 10:34:32 +000086
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010087 for (i = 0; i < TFM_CRYPTO_MAX_KEY_HANDLES; i++) {
88 if (handle_owner[i].in_use == TFM_CRYPTO_NOT_IN_USE) {
89 empty_found = true;
90 break;
91 }
92 }
93
94 if (!empty_found) {
95 return PSA_ERROR_INSUFFICIENT_MEMORY;
96 }
97
98 status = tfm_crypto_get_caller_id(&partition_id);
99 if (status != PSA_SUCCESS) {
100 return status;
101 }
102
103 status = psa_allocate_key(key_handle);
104
105 if (status == PSA_SUCCESS) {
106 handle_owner[i].owner = partition_id;
107 handle_owner[i].handle = *key_handle;
108 handle_owner[i].in_use = TFM_CRYPTO_IN_USE;
109 }
110
111 return status;
Jamie Foxefd82732018-11-26 10:34:32 +0000112}
113
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000114psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
115 size_t in_len,
116 psa_outvec out_vec[],
117 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100118{
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100119 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100120
Antonio de Angelis4743e672019-04-11 11:38:48 +0100121 if ((in_len != 2) || (out_len != 0)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000122 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000123 }
124
Antonio de Angelis4743e672019-04-11 11:38:48 +0100125 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000126 return PSA_CONNECTION_REFUSED;
127 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100128 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000129
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100130 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100131 psa_key_type_t type = iov->type;
132 const uint8_t *data = in_vec[1].base;
133 size_t data_length = in_vec[1].len;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100134 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
135
136 if (status != PSA_SUCCESS) {
137 return status;
138 }
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000139
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100140 return psa_import_key(key, type, data, data_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100141}
142
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000143psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
144 size_t in_len,
145 psa_outvec out_vec[],
146 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100147{
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100148 (void)out_vec;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100149
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000150 if ((in_len != 1) || (out_len != 0)) {
151 return PSA_CONNECTION_REFUSED;
152 }
153
Antonio de Angelis4743e672019-04-11 11:38:48 +0100154 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000155 return PSA_CONNECTION_REFUSED;
156 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100157 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000158
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100159 psa_key_handle_t key = iov->key_handle;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100160 uint32_t index;
161 psa_status_t status = tfm_crypto_check_handle_owner(key, &index);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000162
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100163 if (status != PSA_SUCCESS) {
164 return status;
165 }
166
167 status = psa_destroy_key(key);
168
169 if (status == PSA_SUCCESS) {
170 handle_owner[index].owner = 0;
171 handle_owner[index].handle = 0;
172 handle_owner[index].in_use = TFM_CRYPTO_NOT_IN_USE;
173 }
174
175 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100176}
177
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000178psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
179 size_t in_len,
180 psa_outvec out_vec[],
181 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100182{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000183 if ((in_len != 1) || (out_len != 2)) {
184 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000185 }
186
Antonio de Angelis4743e672019-04-11 11:38:48 +0100187 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000188 (out_vec[0].len != sizeof(psa_key_type_t)) ||
189 (out_vec[1].len != sizeof(size_t))) {
190 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000191 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100192 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Foxefd82732018-11-26 10:34:32 +0000193
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100194 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000195 psa_key_type_t *type = out_vec[0].base;
196 size_t *bits = out_vec[1].base;
197
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100198 return psa_get_key_information(key, type, bits);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100199}
200
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000201psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
202 size_t in_len,
203 psa_outvec out_vec[],
204 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100205{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000206 if ((in_len != 1) || (out_len != 1)) {
207 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100208 }
209
Antonio de Angelis4743e672019-04-11 11:38:48 +0100210 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000211 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100212 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100213 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100214
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100215 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000216 uint8_t *data = out_vec[0].base;
217 size_t data_size = out_vec[0].len;
218
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100219 return psa_export_key(key, data, data_size, &(out_vec[0].len));
Antonio de Angelis8908f472018-08-31 15:44:25 +0100220}
221
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000222psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
223 size_t in_len,
224 psa_outvec out_vec[],
225 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100226{
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100227 if ((in_len != 1) || (out_len != 1)) {
228 return PSA_CONNECTION_REFUSED;
229 }
Hugues de Valon8b442442019-02-19 14:30:52 +0000230
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100231 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
232 return PSA_CONNECTION_REFUSED;
233 }
234 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
235
236 psa_key_handle_t key = iov->key_handle;
237 uint8_t *data = out_vec[0].base;
238 size_t data_size = out_vec[0].len;
239
240 return psa_export_public_key(key, data, data_size, &(out_vec[0].len));
241}
242
243psa_status_t tfm_crypto_copy_key(psa_invec in_vec[],
244 size_t in_len,
245 psa_outvec out_vec[],
246 size_t out_len)
247{
248 (void)out_vec;
249
250 if ((in_len != 3) || (out_len != 0)) {
251 return PSA_CONNECTION_REFUSED;
252 }
253
254 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
255 (in_vec[1].len != sizeof(psa_key_handle_t)) ||
256 (in_vec[2].len != sizeof(psa_key_policy_t))) {
257 return PSA_CONNECTION_REFUSED;
258 }
259 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
260
261 psa_key_handle_t source_handle = iov->key_handle;
262 psa_key_handle_t target_handle = *((psa_key_handle_t *)in_vec[1].base);
263 const psa_key_policy_t *policy = in_vec[2].base;
264
265 return psa_copy_key(source_handle, target_handle, policy);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100266}
Jamie Foxefd82732018-11-26 10:34:32 +0000267
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000268psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
269 size_t in_len,
270 psa_outvec out_vec[],
271 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000272{
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100273 (void)out_vec;
Jamie Foxefd82732018-11-26 10:34:32 +0000274
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000275 if ((in_len != 2) || (out_len != 0)) {
276 return PSA_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)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000280 (in_vec[1].len != sizeof(psa_key_policy_t))) {
281 return PSA_CONNECTION_REFUSED;
282 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100283 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000284
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100285 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000286 const psa_key_policy_t *policy = in_vec[1].base;
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100287 psa_status_t status = tfm_crypto_check_handle_owner(key, NULL);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000288
Antonio de Angelis60a6fe62019-06-18 15:27:34 +0100289 if (status == PSA_SUCCESS) {
290 return psa_set_key_policy(key, policy);
291 } else {
292 return status;
293 }
Jamie Foxefd82732018-11-26 10:34:32 +0000294}
295
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000296psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
297 size_t in_len,
298 psa_outvec out_vec[],
299 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000300{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000301 if ((in_len != 1) || (out_len != 1)) {
302 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000303 }
304
Antonio de Angelis4743e672019-04-11 11:38:48 +0100305 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000306 (out_vec[0].len != sizeof(psa_key_policy_t))) {
307 return PSA_CONNECTION_REFUSED;
308 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100309 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000310
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100311 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000312 psa_key_policy_t *policy = out_vec[0].base;
313
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100314 return psa_get_key_policy(key, policy);
Jamie Foxefd82732018-11-26 10:34:32 +0000315}
316
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000317psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
318 size_t in_len,
319 psa_outvec out_vec[],
320 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000321{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000322 if ((in_len != 1) || (out_len != 1)) {
323 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000324 }
325
Antonio de Angelis4743e672019-04-11 11:38:48 +0100326 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000327 (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
328 return PSA_CONNECTION_REFUSED;
329 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100330 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000331
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100332 psa_key_handle_t key = iov->key_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000333 psa_key_lifetime_t *lifetime = out_vec[0].base;
334
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100335 return psa_get_key_lifetime(key, lifetime);
Jamie Foxefd82732018-11-26 10:34:32 +0000336}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100337/*!@}*/