blob: dc55de62f6007a45c8833c98f7af82fc0197ff90 [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
Antonio de Angelis4743e672019-04-11 11:38:48 +010016/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
17 * integrity checks but this will have to be revised
18 * when the full set of error codes mandated by PSA FF
19 * is available.
20 */
21
Antonio de Angelis8908f472018-08-31 15:44:25 +010022/**
Jamie Fox82b87ca2018-12-11 16:41:11 +000023 * \brief This is the default value of maximum number of simultaneous
24 * key stores supported.
Antonio de Angelis8908f472018-08-31 15:44:25 +010025 */
Jamie Fox82b87ca2018-12-11 16:41:11 +000026#ifndef TFM_CRYPTO_KEY_STORAGE_NUM
Antonio de Angelis8908f472018-08-31 15:44:25 +010027#define TFM_CRYPTO_KEY_STORAGE_NUM (4)
Jamie Fox82b87ca2018-12-11 16:41:11 +000028#endif
29
30/**
31 * \brief This is the default value of the maximum supported key length
32 * in bytes.
33 */
34#ifndef TFM_CRYPTO_MAX_KEY_LENGTH
Tamas Ban28aeec32019-01-09 16:53:26 +000035#define TFM_CRYPTO_MAX_KEY_LENGTH (64)
Jamie Fox82b87ca2018-12-11 16:41:11 +000036#endif
Antonio de Angelis8908f472018-08-31 15:44:25 +010037
38struct tfm_crypto_key_storage_s {
39 uint8_t in_use; /*!< Indicates if the key store is in use */
40 psa_key_type_t type; /*!< Type of the key stored */
Jamie Foxefd82732018-11-26 10:34:32 +000041 psa_key_policy_t policy; /*!< Policy of the key stored */
42 psa_key_lifetime_t lifetime; /*!< Lifetime of the key stored */
Antonio de Angelis8908f472018-08-31 15:44:25 +010043 size_t data_length; /*!< Length of the key stored */
44 uint8_t data[TFM_CRYPTO_MAX_KEY_LENGTH]; /*!< Buffer containining the key */
45};
46
47static struct tfm_crypto_key_storage_s
48 key_storage[TFM_CRYPTO_KEY_STORAGE_NUM] = {{0}};
Jamie Fox82b87ca2018-12-11 16:41:11 +000049
50/**
51 * \brief Get a pointer to the key store for the provided key slot.
52 *
53 * \param[in] key Key slot
54 *
55 * \return Pointer to key store or NULL if key is not a valid key slot
56 */
57static struct tfm_crypto_key_storage_s *get_key_store(psa_key_slot_t key)
58{
59 if (key == 0 || key > TFM_CRYPTO_KEY_STORAGE_NUM) {
60 return NULL;
61 }
62
63 return &key_storage[key - 1];
64}
65
66/**
67 * \brief Check that the key type is supported and that key_length is a
68 * supported key length for that key type.
69 *
70 * \param[in] type Key type
71 * \param[in] key_length Key data length in bytes
72 *
73 * \return True if the key type is supported and key_length is a supported
74 * key length for that key type, false otherwise
75 */
76static bool key_type_is_supported(psa_key_type_t type, size_t key_length)
77{
78 if (key_length > TFM_CRYPTO_MAX_KEY_LENGTH) {
79 return false;
80 }
81
82 switch (type) {
83 case PSA_KEY_TYPE_RAW_DATA:
84 case PSA_KEY_TYPE_HMAC:
85 case PSA_KEY_TYPE_DERIVE:
86 return true; /* No further restictions on these key types */
87 case PSA_KEY_TYPE_AES:
88 case PSA_KEY_TYPE_CAMELLIA:
89 return (key_length == 16 || key_length == 24 || key_length == 32);
90 case PSA_KEY_TYPE_DES:
91 return (key_length == 8 || key_length == 16 || key_length == 24);
92 case PSA_KEY_TYPE_ARC4:
93 return key_length >= 1;
94 default:
95 return false; /* Other key types are not supported */
96 }
97}
98
Antonio de Angelis8908f472018-08-31 15:44:25 +010099/*!
100 * \defgroup public Public functions
101 *
102 */
103
104/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000105psa_status_t tfm_crypto_init_key(void)
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100106{
107 /* Clear the contents of the local key_storage */
Hugues de Valon8b442442019-02-19 14:30:52 +0000108 (void)tfm_memset(key_storage, 0, sizeof(key_storage));
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000109 return PSA_SUCCESS;
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100110}
111
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000112psa_status_t tfm_crypto_get_key(psa_key_slot_t key,
113 psa_key_usage_t usage,
114 psa_algorithm_t alg,
115 uint8_t *data,
116 size_t data_size,
117 size_t *data_length)
Jamie Foxefd82732018-11-26 10:34:32 +0000118{
Jamie Fox82b87ca2018-12-11 16:41:11 +0000119 struct tfm_crypto_key_storage_s *key_store;
Jamie Foxefd82732018-11-26 10:34:32 +0000120 size_t i;
121
Jamie Fox82b87ca2018-12-11 16:41:11 +0000122 key_store = get_key_store(key);
123 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000124 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000125 }
126
Jamie Fox82b87ca2018-12-11 16:41:11 +0000127 if (key_store->in_use == TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000128 return PSA_ERROR_EMPTY_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000129 }
130
131 /* Check that usage is permitted for this key */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000132 if ((usage & key_store->policy.usage) != usage) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000133 return PSA_ERROR_NOT_PERMITTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000134 }
135
136 /* Check that alg is compatible with this key */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000137 if (alg != 0 && alg != key_store->policy.alg) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000138 return PSA_ERROR_NOT_PERMITTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000139 }
140
Jamie Fox82b87ca2018-12-11 16:41:11 +0000141 if (key_store->data_length > data_size) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000142 return PSA_ERROR_BUFFER_TOO_SMALL;
Jamie Foxefd82732018-11-26 10:34:32 +0000143 }
144
Jamie Fox82b87ca2018-12-11 16:41:11 +0000145 for (i = 0; i < key_store->data_length; i++) {
146 data[i] = key_store->data[i];
Jamie Foxefd82732018-11-26 10:34:32 +0000147 }
148
Jamie Fox82b87ca2018-12-11 16:41:11 +0000149 *data_length = key_store->data_length;
Jamie Foxefd82732018-11-26 10:34:32 +0000150
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000151 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000152}
153
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000154psa_status_t tfm_crypto_import_key(psa_invec in_vec[],
155 size_t in_len,
156 psa_outvec out_vec[],
157 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100158{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000159 struct tfm_crypto_key_storage_s *key_store = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100160 size_t i;
161
Antonio de Angelis4743e672019-04-11 11:38:48 +0100162 if ((in_len != 2) || (out_len != 0)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000163 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000164 }
165
Antonio de Angelis4743e672019-04-11 11:38:48 +0100166 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000167 return PSA_CONNECTION_REFUSED;
168 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100169 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000170
Antonio de Angelis4743e672019-04-11 11:38:48 +0100171 psa_key_slot_t key = iov->key;
172 psa_key_type_t type = iov->type;
173 const uint8_t *data = in_vec[1].base;
174 size_t data_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000175
Jamie Fox82b87ca2018-12-11 16:41:11 +0000176 key_store = get_key_store(key);
177 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000178 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100179 }
180
Jamie Fox82b87ca2018-12-11 16:41:11 +0000181 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000182 return PSA_ERROR_OCCUPIED_SLOT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100183 }
184
Jamie Fox82b87ca2018-12-11 16:41:11 +0000185 if (!key_type_is_supported(type, data_length)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000186 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100187 }
188
Jamie Fox82b87ca2018-12-11 16:41:11 +0000189 key_store->in_use = TFM_CRYPTO_IN_USE;
190 key_store->type = type;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100191
192 for (i=0; i<data_length; i++) {
Jamie Fox82b87ca2018-12-11 16:41:11 +0000193 key_store->data[i] = data[i];
Antonio de Angelis8908f472018-08-31 15:44:25 +0100194 }
195
Jamie Fox82b87ca2018-12-11 16:41:11 +0000196 key_store->data_length = data_length;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100197
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000198 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100199}
200
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000201psa_status_t tfm_crypto_destroy_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 struct tfm_crypto_key_storage_s *key_store = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100207 uint32_t i;
208
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000209 if ((in_len != 1) || (out_len != 0)) {
210 return PSA_CONNECTION_REFUSED;
211 }
212
Antonio de Angelis4743e672019-04-11 11:38:48 +0100213 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000214 return PSA_CONNECTION_REFUSED;
215 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100216 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000217
Antonio de Angelis4743e672019-04-11 11:38:48 +0100218 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000219
Jamie Fox82b87ca2018-12-11 16:41:11 +0000220 key_store = get_key_store(key);
221 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000222 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100223 }
224
Jamie Fox82b87ca2018-12-11 16:41:11 +0000225 volatile uint8_t *p_mem = (uint8_t *)key_store;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100226 uint32_t size_mem = sizeof(struct tfm_crypto_key_storage_s);
227
228 /* memset the key_storage */
229 for (i=0; i<size_mem; i++) {
230 p_mem[i] = 0;
231 }
232
233 /* Set default values */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000234 key_store->in_use = TFM_CRYPTO_NOT_IN_USE;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100235
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000236 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100237}
238
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000239psa_status_t tfm_crypto_get_key_information(psa_invec in_vec[],
240 size_t in_len,
241 psa_outvec out_vec[],
242 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100243{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000244 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000245
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000246 if ((in_len != 1) || (out_len != 2)) {
247 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000248 }
249
Antonio de Angelis4743e672019-04-11 11:38:48 +0100250 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000251 (out_vec[0].len != sizeof(psa_key_type_t)) ||
252 (out_vec[1].len != sizeof(size_t))) {
253 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000254 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100255 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Foxefd82732018-11-26 10:34:32 +0000256
Antonio de Angelis4743e672019-04-11 11:38:48 +0100257 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000258 psa_key_type_t *type = out_vec[0].base;
259 size_t *bits = out_vec[1].base;
260
Jamie Fox82b87ca2018-12-11 16:41:11 +0000261 /* Initialise output parameters contents to zero */
262 *type = (psa_key_type_t) 0;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000263 *bits = (size_t) 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000264
265 key_store = get_key_store(key);
266 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000267 return PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100268 }
269
Jamie Fox82b87ca2018-12-11 16:41:11 +0000270 if (key_store->in_use == TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000271 return PSA_ERROR_EMPTY_SLOT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100272 }
273
274 /* Get basic metadata */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000275 *type = key_store->type;
276 *bits = PSA_BYTES_TO_BITS(key_store->data_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100277
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000278 return PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100279}
280
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000281psa_status_t tfm_crypto_export_key(psa_invec in_vec[],
282 size_t in_len,
283 psa_outvec out_vec[],
284 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100285{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000286 if ((in_len != 1) || (out_len != 1)) {
287 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100288 }
289
Antonio de Angelis4743e672019-04-11 11:38:48 +0100290 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000291 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100292 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100293 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100294
Antonio de Angelis4743e672019-04-11 11:38:48 +0100295 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000296 uint8_t *data = out_vec[0].base;
297 size_t data_size = out_vec[0].len;
298
Jamie Foxefd82732018-11-26 10:34:32 +0000299 return tfm_crypto_get_key(key, PSA_KEY_USAGE_EXPORT, 0, data, data_size,
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000300 &(out_vec[0].len));
Antonio de Angelis8908f472018-08-31 15:44:25 +0100301}
302
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000303psa_status_t tfm_crypto_export_public_key(psa_invec in_vec[],
304 size_t in_len,
305 psa_outvec out_vec[],
306 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100307{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000308 (void)in_vec;
309 (void)in_len;
310 (void)out_vec;
311 (void)out_len;
Hugues de Valon8b442442019-02-19 14:30:52 +0000312
Antonio de Angelis8908f472018-08-31 15:44:25 +0100313 /* FIXME: This API is not supported yet */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000314 return PSA_ERROR_NOT_SUPPORTED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100315}
Jamie Foxefd82732018-11-26 10:34:32 +0000316
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000317psa_status_t tfm_crypto_key_policy_init(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 Angelis4743e672019-04-11 11:38:48 +0100322 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000323 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000324 }
325
Antonio de Angelis4743e672019-04-11 11:38:48 +0100326 if ((out_vec[0].len != sizeof(psa_key_policy_t)) ||
327 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000328 return PSA_CONNECTION_REFUSED;
329 }
330
331 psa_key_policy_t *policy = out_vec[0].base;
332
Jamie Foxefd82732018-11-26 10:34:32 +0000333 policy->usage = 0;
334 policy->alg = 0;
335
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000336 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000337}
338
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000339psa_status_t tfm_crypto_key_policy_set_usage(psa_invec in_vec[],
340 size_t in_len,
341 psa_outvec out_vec[],
342 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000343{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100344 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000345 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000346 }
347
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000348 if ((out_vec[0].len != sizeof(psa_key_policy_t)) ||
Antonio de Angelis4743e672019-04-11 11:38:48 +0100349 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000350 return PSA_CONNECTION_REFUSED;
351 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100352 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000353
354 psa_key_policy_t *policy = out_vec[0].base;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100355 psa_key_usage_t usage = iov->usage;
356 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000357
Jamie Foxefd82732018-11-26 10:34:32 +0000358 policy->usage = usage;
359 policy->alg = alg;
360
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000361 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000362}
363
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000364psa_status_t tfm_crypto_key_policy_get_usage(psa_invec in_vec[],
365 size_t in_len,
366 psa_outvec out_vec[],
367 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000368{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100369 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000370 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000371 }
372
Antonio de Angelis4743e672019-04-11 11:38:48 +0100373 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
374 (in_vec[1].len != sizeof(psa_key_policy_t)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000375 (out_vec[0].len != sizeof(psa_key_usage_t))) {
376 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000377 }
378
Antonio de Angelis4743e672019-04-11 11:38:48 +0100379 const psa_key_policy_t *policy = in_vec[1].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000380 psa_key_usage_t *usage = out_vec[0].base;
381
Jamie Foxefd82732018-11-26 10:34:32 +0000382 *usage = policy->usage;
383
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000384 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000385}
386
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000387psa_status_t tfm_crypto_key_policy_get_algorithm(psa_invec in_vec[],
388 size_t in_len,
389 psa_outvec out_vec[],
390 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000391{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100392 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000393 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000394 }
395
Antonio de Angelis4743e672019-04-11 11:38:48 +0100396 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
397 (in_vec[1].len != sizeof(psa_key_policy_t)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000398 (out_vec[0].len != sizeof(psa_algorithm_t))) {
399 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000400 }
401
Antonio de Angelis4743e672019-04-11 11:38:48 +0100402 const psa_key_policy_t *policy = in_vec[1].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000403 psa_algorithm_t *alg = out_vec[0].base;
404
Jamie Foxefd82732018-11-26 10:34:32 +0000405 *alg = policy->alg;
406
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000407 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000408}
409
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000410psa_status_t tfm_crypto_set_key_policy(psa_invec in_vec[],
411 size_t in_len,
412 psa_outvec out_vec[],
413 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000414{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000415 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000416
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000417 if ((in_len != 2) || (out_len != 0)) {
418 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000419 }
420
Antonio de Angelis4743e672019-04-11 11:38:48 +0100421 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000422 (in_vec[1].len != sizeof(psa_key_policy_t))) {
423 return PSA_CONNECTION_REFUSED;
424 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100425 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000426
Antonio de Angelis4743e672019-04-11 11:38:48 +0100427 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000428 const psa_key_policy_t *policy = in_vec[1].base;
429
Jamie Foxefd82732018-11-26 10:34:32 +0000430 /* Check that the policy is valid */
431 if (policy->usage & ~(PSA_KEY_USAGE_EXPORT
432 | PSA_KEY_USAGE_ENCRYPT
433 | PSA_KEY_USAGE_DECRYPT
434 | PSA_KEY_USAGE_SIGN
435 | PSA_KEY_USAGE_VERIFY
436 | PSA_KEY_USAGE_DERIVE)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000437 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000438 }
439
Jamie Fox82b87ca2018-12-11 16:41:11 +0000440 key_store = get_key_store(key);
441 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000442 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000443 }
444
Jamie Foxefd82732018-11-26 10:34:32 +0000445 /* Changing the policy of an occupied slot is not permitted as
446 * this is a requirement of the PSA Crypto API
447 */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000448 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000449 return PSA_ERROR_OCCUPIED_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000450 }
451
Jamie Fox82b87ca2018-12-11 16:41:11 +0000452 key_store->policy = *policy;
Jamie Foxefd82732018-11-26 10:34:32 +0000453
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000454 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000455}
456
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000457psa_status_t tfm_crypto_get_key_policy(psa_invec in_vec[],
458 size_t in_len,
459 psa_outvec out_vec[],
460 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000461{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000462 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000463
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000464 if ((in_len != 1) || (out_len != 1)) {
465 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000466 }
467
Antonio de Angelis4743e672019-04-11 11:38:48 +0100468 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000469 (out_vec[0].len != sizeof(psa_key_policy_t))) {
470 return PSA_CONNECTION_REFUSED;
471 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100472 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000473
Antonio de Angelis4743e672019-04-11 11:38:48 +0100474 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000475 psa_key_policy_t *policy = out_vec[0].base;
476
Jamie Fox82b87ca2018-12-11 16:41:11 +0000477 key_store = get_key_store(key);
478 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000479 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000480 }
481
Jamie Fox82b87ca2018-12-11 16:41:11 +0000482 *policy = key_store->policy;
Jamie Foxefd82732018-11-26 10:34:32 +0000483
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000484 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000485}
486
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000487psa_status_t tfm_crypto_set_key_lifetime(psa_invec in_vec[],
488 size_t in_len,
489 psa_outvec out_vec[],
490 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000491{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000492 struct tfm_crypto_key_storage_s *key_store = NULL;
493
Antonio de Angelis4743e672019-04-11 11:38:48 +0100494 if ((in_len != 1) || (out_len != 0)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000495 return PSA_CONNECTION_REFUSED;
496 }
497
Antonio de Angelis4743e672019-04-11 11:38:48 +0100498 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000499 return PSA_CONNECTION_REFUSED;
500 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100501 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000502
Antonio de Angelis4743e672019-04-11 11:38:48 +0100503 psa_key_slot_t key = iov->key;
504 psa_key_lifetime_t lifetime = iov->lifetime;
Jamie Foxefd82732018-11-26 10:34:32 +0000505
506 /* Check that the lifetime is valid */
507 if (lifetime != PSA_KEY_LIFETIME_VOLATILE
508 && lifetime != PSA_KEY_LIFETIME_PERSISTENT
509 && lifetime != PSA_KEY_LIFETIME_WRITE_ONCE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000510 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000511 }
512
Jamie Fox82b87ca2018-12-11 16:41:11 +0000513 key_store = get_key_store(key);
514 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000515 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000516 }
517
Jamie Foxefd82732018-11-26 10:34:32 +0000518 /* TF-M Crypto service does not support changing the lifetime of an occupied
519 * slot.
520 */
Jamie Fox82b87ca2018-12-11 16:41:11 +0000521 if (key_store->in_use != TFM_CRYPTO_NOT_IN_USE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000522 return PSA_ERROR_OCCUPIED_SLOT;
Jamie Foxefd82732018-11-26 10:34:32 +0000523 }
524
525 /* Only volatile keys are currently supported */
526 if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000527 return PSA_ERROR_NOT_SUPPORTED;
Jamie Foxefd82732018-11-26 10:34:32 +0000528 }
529
Jamie Fox82b87ca2018-12-11 16:41:11 +0000530 key_store->lifetime = lifetime;
Jamie Foxefd82732018-11-26 10:34:32 +0000531
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000532 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000533}
534
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000535psa_status_t tfm_crypto_get_key_lifetime(psa_invec in_vec[],
536 size_t in_len,
537 psa_outvec out_vec[],
538 size_t out_len)
Jamie Foxefd82732018-11-26 10:34:32 +0000539{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000540 struct tfm_crypto_key_storage_s *key_store = NULL;
Jamie Foxefd82732018-11-26 10:34:32 +0000541
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000542 if ((in_len != 1) || (out_len != 1)) {
543 return PSA_CONNECTION_REFUSED;
Jamie Foxefd82732018-11-26 10:34:32 +0000544 }
545
Antonio de Angelis4743e672019-04-11 11:38:48 +0100546 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000547 (out_vec[0].len != sizeof(psa_key_lifetime_t))) {
548 return PSA_CONNECTION_REFUSED;
549 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100550 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000551
Antonio de Angelis4743e672019-04-11 11:38:48 +0100552 psa_key_slot_t key = iov->key;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000553 psa_key_lifetime_t *lifetime = out_vec[0].base;
554
Jamie Fox82b87ca2018-12-11 16:41:11 +0000555 key_store = get_key_store(key);
556 if (key_store == NULL) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000557 return PSA_ERROR_INVALID_ARGUMENT;
Jamie Foxefd82732018-11-26 10:34:32 +0000558 }
559
Jamie Fox82b87ca2018-12-11 16:41:11 +0000560 *lifetime = key_store->lifetime;
Jamie Foxefd82732018-11-26 10:34:32 +0000561
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000562 return PSA_SUCCESS;
Jamie Foxefd82732018-11-26 10:34:32 +0000563}
Antonio de Angelis8908f472018-08-31 15:44:25 +0100564/*!@}*/