blob: 2bef9ca0a65d98ec97a32ec160cf908a703498b1 [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 Fox82b87ca2018-12-11 16:41:11 +00008#include <stdbool.h>
Jamie Foxefd82732018-11-26 10:34:32 +00009#include <stddef.h>
Antonio de Angelis8908f472018-08-31 15:44:25 +010010
Jamie Foxefd82732018-11-26 10:34:32 +000011#include "tfm_crypto_api.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010012#include "psa_crypto.h"
Jamie Foxefd82732018-11-26 10:34:32 +000013#include "tfm_crypto_defs.h"
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000014#include "secure_fw/core/tfm_memory_utils.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010015
16/**
Jamie Fox82b87ca2018-12-11 16:41:11 +000017 * \brief This is the default value of maximum number of simultaneous
18 * key stores supported.
Antonio de Angelis8908f472018-08-31 15:44:25 +010019 */
Jamie Fox82b87ca2018-12-11 16:41:11 +000020#ifndef TFM_CRYPTO_KEY_STORAGE_NUM
Antonio de Angelis8908f472018-08-31 15:44:25 +010021#define TFM_CRYPTO_KEY_STORAGE_NUM (4)
Jamie Fox82b87ca2018-12-11 16:41:11 +000022#endif
23
24/**
25 * \brief This is the default value of the maximum supported key length
26 * in bytes.
27 */
28#ifndef TFM_CRYPTO_MAX_KEY_LENGTH
Tamas Ban28aeec32019-01-09 16:53:26 +000029#define TFM_CRYPTO_MAX_KEY_LENGTH (64)
Jamie Fox82b87ca2018-12-11 16:41:11 +000030#endif
Antonio de Angelis8908f472018-08-31 15:44:25 +010031
32struct tfm_crypto_key_storage_s {
33 uint8_t in_use; /*!< Indicates if the key store is in use */
34 psa_key_type_t type; /*!< Type of the key stored */
Jamie Foxefd82732018-11-26 10:34:32 +000035 psa_key_policy_t policy; /*!< Policy of the key stored */
36 psa_key_lifetime_t lifetime; /*!< Lifetime of the key stored */
Antonio de Angelis8908f472018-08-31 15:44:25 +010037 size_t data_length; /*!< Length of the key stored */
38 uint8_t data[TFM_CRYPTO_MAX_KEY_LENGTH]; /*!< Buffer containining the key */
39};
40
41static struct tfm_crypto_key_storage_s
42 key_storage[TFM_CRYPTO_KEY_STORAGE_NUM] = {{0}};
Jamie Fox82b87ca2018-12-11 16:41:11 +000043
44/**
45 * \brief Get a pointer to the key store for the provided key slot.
46 *
47 * \param[in] key Key slot
48 *
49 * \return Pointer to key store or NULL if key is not a valid key slot
50 */
51static struct tfm_crypto_key_storage_s *get_key_store(psa_key_slot_t key)
52{
53 if (key == 0 || key > TFM_CRYPTO_KEY_STORAGE_NUM) {
54 return NULL;
55 }
56
57 return &key_storage[key - 1];
58}
59
60/**
61 * \brief Check that the key type is supported and that key_length is a
62 * supported key length for that key type.
63 *
64 * \param[in] type Key type
65 * \param[in] key_length Key data length in bytes
66 *
67 * \return True if the key type is supported and key_length is a supported
68 * key length for that key type, false otherwise
69 */
70static bool key_type_is_supported(psa_key_type_t type, size_t key_length)
71{
72 if (key_length > TFM_CRYPTO_MAX_KEY_LENGTH) {
73 return false;
74 }
75
76 switch (type) {
77 case PSA_KEY_TYPE_RAW_DATA:
78 case PSA_KEY_TYPE_HMAC:
79 case PSA_KEY_TYPE_DERIVE:
80 return true; /* No further restictions on these key types */
81 case PSA_KEY_TYPE_AES:
82 case PSA_KEY_TYPE_CAMELLIA:
83 return (key_length == 16 || key_length == 24 || key_length == 32);
84 case PSA_KEY_TYPE_DES:
85 return (key_length == 8 || key_length == 16 || key_length == 24);
86 case PSA_KEY_TYPE_ARC4:
87 return key_length >= 1;
88 default:
89 return false; /* Other key types are not supported */
90 }
91}
92
Antonio de Angelis8908f472018-08-31 15:44:25 +010093/*!
94 * \defgroup public Public functions
95 *
96 */
97
98/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000099psa_status_t tfm_crypto_init_key(void)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100100{
101 /* Clear the contents of the local key_storage */
Hugues de Valon8b442442019-02-19 14:30:52 +0000102 (void)tfm_memset(key_storage, 0, sizeof(key_storage));
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000103 return PSA_SUCCESS;
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100104}
105
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000106psa_status_t tfm_crypto_get_key(psa_key_slot_t key,
107 psa_key_usage_t usage,
108 psa_algorithm_t alg,
109 uint8_t *data,
110 size_t data_size,
111 size_t *data_length)
Jamie Foxefd82732018-11-26 10:34:32 +0000112{
Jamie Fox82b87ca2018-12-11 16:41:11 +0000113 struct tfm_crypto_key_storage_s *key_store;
Jamie Foxefd82732018-11-26 10:34:32 +0000114 size_t i;
115
Jamie Fox82b87ca2018-12-11 16:41:11 +0000116 key_store = get_key_store(key);
117 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000118 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000119 }
120
Jamie Fox82b87ca2018-12-11 16:41:11 +0000121 if (key_store->in_use == TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000122 return PSA_ERROR_EMPTY_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000123 }
124
125 /* Check that usage is permitted for this key */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000126 if ((usage & key_store->policy.usage) != usage) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000127 return PSA_ERROR_NOT_PERMITTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000128 }
129
130 /* Check that alg is compatible with this key */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000131 if (alg != 0 && alg != key_store->policy.alg) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000132 return PSA_ERROR_NOT_PERMITTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000133 }
134
Jamie Fox82b87ca2018-12-11 16:41:11 +0000135 if (key_store->data_length > data_size) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000136 return PSA_ERROR_BUFFER_TOO_SMALL;
Jamie Foxefd82732018-11-26 10:34:32 +0000137 }
138
Jamie Fox82b87ca2018-12-11 16:41:11 +0000139 for (i = 0; i < key_store->data_length; i++) {
140 data[i] = key_store->data[i];
Jamie Foxefd82732018-11-26 10:34:32 +0000141 }
142
Jamie Fox82b87ca2018-12-11 16:41:11 +0000143 *data_length = key_store->data_length;
Jamie Foxefd82732018-11-26 10:34:32 +0000144
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000145 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000146}
147
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000148psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
149 size_t in_len,
150 psa_outvec out_vec[],
151 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100152{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000153 struct tfm_crypto_key_storage_s *key_store = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100154 size_t i;
155
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000156 if ((in_len != 3) || (out_len != 0)) {
157 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000158 }
159
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000160 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
161 (in_vec[1].len != sizeof(psa_key_type_t))) {
162 return PSA_CONNECTION_REFUSED;
163 }
164
165 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
166 psa_key_type_t type = *((psa_key_type_t *)in_vec[1].base);
167 const uint8_t *data = in_vec[2].base;
168 size_t data_length = in_vec[2].len;
169
Jamie Fox82b87ca2018-12-11 16:41:11 +0000170 key_store = get_key_store(key);
171 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000172 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100173 }
174
Jamie Fox82b87ca2018-12-11 16:41:11 +0000175 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000176 return PSA_ERROR_OCCUPIED_SLOT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100177 }
178
Jamie Fox82b87ca2018-12-11 16:41:11 +0000179 if (!key_type_is_supported(type, data_length)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000180 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100181 }
182
Jamie Fox82b87ca2018-12-11 16:41:11 +0000183 key_store->in_use = TFM_CRYPTO_IN_USE;
184 key_store->type = type;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100185
186 for (i=0; i<data_length; i++) {
Jamie Fox82b87ca2018-12-11 16:41:11 +0000187 key_store->data[i] = data[i];
Antonio de Angelis8908f472018-08-31 15:44:25 +0100188 }
189
Jamie Fox82b87ca2018-12-11 16:41:11 +0000190 key_store->data_length = data_length;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100191
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000192 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100193}
194
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000195psa_status_t tfm_crypto_destroy_key(psa_invec in_vec[],
196 size_t in_len,
197 psa_outvec out_vec[],
198 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100199{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000200 struct tfm_crypto_key_storage_s *key_store = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100201 uint32_t i;
202
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000203 if ((in_len != 1) || (out_len != 0)) {
204 return PSA_CONNECTION_REFUSED;
205 }
206
207 if (in_vec[0].len != sizeof(psa_key_slot_t)) {
208 return PSA_CONNECTION_REFUSED;
209 }
210
211 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
212
Jamie Fox82b87ca2018-12-11 16:41:11 +0000213 key_store = get_key_store(key);
214 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000215 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100216 }
217
Jamie Fox82b87ca2018-12-11 16:41:11 +0000218 volatile uint8_t *p_mem = (uint8_t *)key_store;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100219 uint32_t size_mem = sizeof(struct tfm_crypto_key_storage_s);
220
221 /* memset the key_storage */
222 for (i=0; i<size_mem; i++) {
223 p_mem[i] = 0;
224 }
225
226 /* Set default values */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000227 key_store->in_use = TFM_CRYPTO_NOT_IN_USE;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100228
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000229 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100230}
231
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000232psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
233 size_t in_len,
234 psa_outvec out_vec[],
235 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100236{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000237 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000238
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000239 if ((in_len != 1) || (out_len != 2)) {
240 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000241 }
242
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000243 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
244 (out_vec[0].len != sizeof(psa_key_type_t)) ||
245 (out_vec[1].len != sizeof(size_t))) {
246 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000247 }
248
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000249 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
250 psa_key_type_t *type = out_vec[0].base;
251 size_t *bits = out_vec[1].base;
252
Jamie Fox82b87ca2018-12-11 16:41:11 +0000253 /* Initialise output parameters contents to zero */
254 *type = (psa_key_type_t) 0;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000255 *bits = (size_t) 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000256
257 key_store = get_key_store(key);
258 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000259 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100260 }
261
Jamie Fox82b87ca2018-12-11 16:41:11 +0000262 if (key_store->in_use == TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000263 return PSA_ERROR_EMPTY_SLOT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100264 }
265
266 /* Get basic metadata */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000267 *type = key_store->type;
268 *bits = PSA_BYTES_TO_BITS(key_store->data_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100269
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000270 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100271}
272
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000273psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
274 size_t in_len,
275 psa_outvec out_vec[],
276 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100277{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000278 if ((in_len != 1) || (out_len != 1)) {
279 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100280 }
281
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000282 if (in_vec[0].len != sizeof(psa_key_slot_t)) {
283 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100284 }
285
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000286 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
287 uint8_t *data = out_vec[0].base;
288 size_t data_size = out_vec[0].len;
289
Jamie Foxefd82732018-11-26 10:34:32 +0000290 return tfm_crypto_get_key(key, PSA_KEY_USAGE_EXPORT, 0, data, data_size,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000291 &(out_vec[0].len));
Antonio de Angelis8908f472018-08-31 15:44:25 +0100292}
293
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000294psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
295 size_t in_len,
296 psa_outvec out_vec[],
297 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100298{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000299 (void)in_vec;
300 (void)in_len;
301 (void)out_vec;
302 (void)out_len;
Hugues de Valon8b442442019-02-19 14:30:52 +0000303
Antonio de Angelis8908f472018-08-31 15:44:25 +0100304 /* FIXME: This API is not supported yet */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000305 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100306}
Jamie Foxefd82732018-11-26 10:34:32 +0000307
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000308psa_status_t tfm_crypto_key_policy_init(psa_invec in_vec[],
309 size_t in_len,
310 psa_outvec out_vec[],
311 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000312{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000313 if ((in_len != 0) || (out_len != 1)) {
314 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000315 }
316
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000317 if (out_vec[0].len != sizeof(psa_key_policy_t)) {
318 return PSA_CONNECTION_REFUSED;
319 }
320
321 psa_key_policy_t *policy = out_vec[0].base;
322
Jamie Foxefd82732018-11-26 10:34:32 +0000323 policy->usage = 0;
324 policy->alg = 0;
325
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000326 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000327}
328
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000329psa_status_t tfm_crypto_key_policy_set_usage(psa_invec in_vec[],
330 size_t in_len,
331 psa_outvec out_vec[],
332 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000333{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000334 if ((in_len != 2) || (out_len != 1)) {
335 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000336 }
337
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000338 if ((out_vec[0].len != sizeof(psa_key_policy_t)) ||
339 (in_vec[0].len != sizeof(psa_key_usage_t)) ||
340 (in_vec[1].len != sizeof(psa_algorithm_t))) {
341 return PSA_CONNECTION_REFUSED;
342 }
343
344 psa_key_policy_t *policy = out_vec[0].base;
345 psa_key_usage_t usage = *((psa_key_usage_t *)in_vec[0].base);
346 psa_algorithm_t alg = *((psa_algorithm_t *)in_vec[1].base);
347
Jamie Foxefd82732018-11-26 10:34:32 +0000348 policy->usage = usage;
349 policy->alg = alg;
350
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000351 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000352}
353
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000354psa_status_t tfm_crypto_key_policy_get_usage(psa_invec in_vec[],
355 size_t in_len,
356 psa_outvec out_vec[],
357 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000358{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000359 if ((in_len != 1) || (out_len != 1)) {
360 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000361 }
362
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000363 if ((in_vec[0].len != sizeof(psa_key_policy_t)) ||
364 (out_vec[0].len != sizeof(psa_key_usage_t))) {
365 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000366 }
367
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000368 const psa_key_policy_t *policy = in_vec[0].base;
369 psa_key_usage_t *usage = out_vec[0].base;
370
Jamie Foxefd82732018-11-26 10:34:32 +0000371 *usage = policy->usage;
372
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000373 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000374}
375
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000376psa_status_t tfm_crypto_key_policy_get_algorithm(psa_invec in_vec[],
377 size_t in_len,
378 psa_outvec out_vec[],
379 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000380{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000381 if ((in_len != 1) || (out_len != 1)) {
382 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000383 }
384
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000385 if ((in_vec[0].len != sizeof(psa_key_policy_t)) ||
386 (out_vec[0].len != sizeof(psa_algorithm_t))) {
387 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000388 }
389
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000390 const psa_key_policy_t *policy = in_vec[0].base;
391 psa_algorithm_t *alg = out_vec[0].base;
392
Jamie Foxefd82732018-11-26 10:34:32 +0000393 *alg = policy->alg;
394
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000395 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000396}
397
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000398psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
399 size_t in_len,
400 psa_outvec out_vec[],
401 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000402{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000403 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000404
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000405 if ((in_len != 2) || (out_len != 0)) {
406 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000407 }
408
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000409 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
410 (in_vec[1].len != sizeof(psa_key_policy_t))) {
411 return PSA_CONNECTION_REFUSED;
412 }
413
414 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
415 const psa_key_policy_t *policy = in_vec[1].base;
416
Jamie Foxefd82732018-11-26 10:34:32 +0000417 /* Check that the policy is valid */
418 if (policy->usage & ~(PSA_KEY_USAGE_EXPORT
419 | PSA_KEY_USAGE_ENCRYPT
420 | PSA_KEY_USAGE_DECRYPT
421 | PSA_KEY_USAGE_SIGN
422 | PSA_KEY_USAGE_VERIFY
423 | PSA_KEY_USAGE_DERIVE)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000424 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000425 }
426
Jamie Fox82b87ca2018-12-11 16:41:11 +0000427 key_store = get_key_store(key);
428 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000429 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000430 }
431
Jamie Foxefd82732018-11-26 10:34:32 +0000432 /* Changing the policy of an occupied slot is not permitted as
433 * this is a requirement of the PSA Crypto API
434 */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000435 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000436 return PSA_ERROR_OCCUPIED_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000437 }
438
Jamie Fox82b87ca2018-12-11 16:41:11 +0000439 key_store->policy = *policy;
Jamie Foxefd82732018-11-26 10:34:32 +0000440
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000441 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000442}
443
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000444psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
445 size_t in_len,
446 psa_outvec out_vec[],
447 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000448{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000449 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000450
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000451 if ((in_len != 1) || (out_len != 1)) {
452 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000453 }
454
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000455 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
456 (out_vec[0].len != sizeof(psa_key_policy_t))) {
457 return PSA_CONNECTION_REFUSED;
458 }
459
460 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
461 psa_key_policy_t *policy = out_vec[0].base;
462
Jamie Fox82b87ca2018-12-11 16:41:11 +0000463 key_store = get_key_store(key);
464 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000465 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000466 }
467
Jamie Fox82b87ca2018-12-11 16:41:11 +0000468 *policy = key_store->policy;
Jamie Foxefd82732018-11-26 10:34:32 +0000469
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000470 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000471}
472
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000473psa_status_t tfm_crypto_set_key_lifetime(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 Angelisab85ccd2019-03-25 15:14:29 +0000478 struct tfm_crypto_key_storage_s *key_store = NULL;
479
480 if ((in_len != 2) || (out_len != 0)) {
481 return PSA_CONNECTION_REFUSED;
482 }
483
484 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
485 (in_vec[1].len != sizeof(psa_key_lifetime_t))) {
486 return PSA_CONNECTION_REFUSED;
487 }
488
489 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
490 psa_key_lifetime_t lifetime = *((psa_key_lifetime_t *)in_vec[1].base);
Jamie Foxefd82732018-11-26 10:34:32 +0000491
492 /* Check that the lifetime is valid */
493 if (lifetime != PSA_KEY_LIFETIME_VOLATILE
494 && lifetime != PSA_KEY_LIFETIME_PERSISTENT
495 && lifetime != PSA_KEY_LIFETIME_WRITE_ONCE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000496 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000497 }
498
Jamie Fox82b87ca2018-12-11 16:41:11 +0000499 key_store = get_key_store(key);
500 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000501 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000502 }
503
Jamie Foxefd82732018-11-26 10:34:32 +0000504 /* TF-M Crypto service does not support changing the lifetime of an occupied
505 * slot.
506 */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000507 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000508 return PSA_ERROR_OCCUPIED_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000509 }
510
511 /* Only volatile keys are currently supported */
512 if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000513 return PSA_ERROR_NOT_SUPPORTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000514 }
515
Jamie Fox82b87ca2018-12-11 16:41:11 +0000516 key_store->lifetime = lifetime;
Jamie Foxefd82732018-11-26 10:34:32 +0000517
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000518 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000519}
520
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000521psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
522 size_t in_len,
523 psa_outvec out_vec[],
524 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000525{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000526 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000527
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000528 if ((in_len != 1) || (out_len != 1)) {
529 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000530 }
531
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000532 if ((in_vec[0].len != sizeof(psa_key_slot_t)) ||
533 (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
534 return PSA_CONNECTION_REFUSED;
535 }
536
537 psa_key_slot_t key = *((psa_key_slot_t *)in_vec[0].base);
538 psa_key_lifetime_t *lifetime = out_vec[0].base;
539
Jamie Fox82b87ca2018-12-11 16:41:11 +0000540 key_store = get_key_store(key);
541 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000542 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000543 }
544
Jamie Fox82b87ca2018-12-11 16:41:11 +0000545 *lifetime = key_store->lifetime;
Jamie Foxefd82732018-11-26 10:34:32 +0000546
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000547 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000548}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100549/*!@}*/