blob: 90638f2ac6b4954f5dbca0f0d3ec7a6d45b6afe4 [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>
Antonio de Angelis8908f472018-08-31 15:44:25 +01009
Jamie Foxefd82732018-11-26 10:34:32 +000010#include "tfm_crypto_api.h"
11#include "crypto_utils.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 Angeliscf85ba22018-10-09 13:29:40 +010014#include "secure_fw/core/secure_utilities.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010015
16/**
17 * \brief This value defines the maximum number of simultaneous key stores
18 * supported by this implementation.
19 */
20#define TFM_CRYPTO_KEY_STORAGE_NUM (4)
21
22struct tfm_crypto_key_storage_s {
23 uint8_t in_use; /*!< Indicates if the key store is in use */
24 psa_key_type_t type; /*!< Type of the key stored */
Jamie Foxefd82732018-11-26 10:34:32 +000025 psa_key_policy_t policy; /*!< Policy of the key stored */
26 psa_key_lifetime_t lifetime; /*!< Lifetime of the key stored */
Antonio de Angelis8908f472018-08-31 15:44:25 +010027 size_t data_length; /*!< Length of the key stored */
28 uint8_t data[TFM_CRYPTO_MAX_KEY_LENGTH]; /*!< Buffer containining the key */
29};
30
31static struct tfm_crypto_key_storage_s
32 key_storage[TFM_CRYPTO_KEY_STORAGE_NUM] = {{0}};
33/*!
34 * \defgroup public Public functions
35 *
36 */
37
38/*!@{*/
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010039enum tfm_crypto_err_t tfm_crypto_init_key(void)
40{
41 /* Clear the contents of the local key_storage */
42 tfm_memset(key_storage, 0, sizeof(key_storage));
43 return TFM_CRYPTO_ERR_PSA_SUCCESS;
44}
45
Jamie Foxefd82732018-11-26 10:34:32 +000046enum tfm_crypto_err_t tfm_crypto_get_key(psa_key_slot_t key,
47 psa_key_usage_t usage,
48 psa_algorithm_t alg,
49 uint8_t *data,
50 size_t data_size,
51 size_t *data_length)
52{
53 size_t i;
54
55 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
56 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
57 }
58
59 if (key_storage[key].in_use == TFM_CRYPTO_NOT_IN_USE) {
60 return TFM_CRYPTO_ERR_PSA_ERROR_EMPTY_SLOT;
61 }
62
63 /* Check that usage is permitted for this key */
64 if ((usage & key_storage[key].policy.usage) != usage) {
65 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
66 }
67
68 /* Check that alg is compatible with this key */
69 if (alg != 0 && alg != key_storage[key].policy.alg) {
70 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
71 }
72
73 if (key_storage[key].data_length > data_size) {
74 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
75 }
76
77 for (i = 0; i < key_storage[key].data_length; i++) {
78 data[i] = key_storage[key].data[i];
79 }
80
81 *data_length = key_storage[key].data_length;
82
83 return TFM_CRYPTO_ERR_PSA_SUCCESS;
84}
85
Antonio de Angelis8908f472018-08-31 15:44:25 +010086enum tfm_crypto_err_t tfm_crypto_import_key(psa_key_slot_t key,
87 psa_key_type_t type,
88 const uint8_t *data,
89 size_t data_length)
90{
Jamie Foxefd82732018-11-26 10:34:32 +000091 enum tfm_crypto_err_t err;
Antonio de Angelis8908f472018-08-31 15:44:25 +010092 size_t i;
93
Jamie Foxefd82732018-11-26 10:34:32 +000094 err = tfm_crypto_memory_check((uint8_t *)data, data_length,
95 TFM_MEMORY_ACCESS_RO);
96 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
97 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
98 }
99
Antonio de Angelis8908f472018-08-31 15:44:25 +0100100 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
101 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
102 }
103
104 if (key_storage[key].in_use != TFM_CRYPTO_NOT_IN_USE) {
105 return TFM_CRYPTO_ERR_PSA_ERROR_OCCUPIED_SLOT;
106 }
107
108 if (data_length > TFM_CRYPTO_MAX_KEY_LENGTH) {
109 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
110 }
111
112 key_storage[key].in_use = TFM_CRYPTO_IN_USE;
113 key_storage[key].type = type;
114
115 for (i=0; i<data_length; i++) {
116 key_storage[key].data[i] = data[i];
117 }
118
119 key_storage[key].data_length = data_length;
120
Antonio de Angelis8908f472018-08-31 15:44:25 +0100121 return TFM_CRYPTO_ERR_PSA_SUCCESS;
122}
123
124enum tfm_crypto_err_t tfm_crypto_destroy_key(psa_key_slot_t key)
125{
126 uint32_t i;
127
128 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
129 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
130 }
131
132 volatile uint8_t *p_mem = (uint8_t *) &(key_storage[key]);
133 uint32_t size_mem = sizeof(struct tfm_crypto_key_storage_s);
134
135 /* memset the key_storage */
136 for (i=0; i<size_mem; i++) {
137 p_mem[i] = 0;
138 }
139
140 /* Set default values */
141 key_storage[key].in_use = TFM_CRYPTO_NOT_IN_USE;
142
143 return TFM_CRYPTO_ERR_PSA_SUCCESS;
144}
145
146enum tfm_crypto_err_t tfm_crypto_get_key_information(psa_key_slot_t key,
147 psa_key_type_t *type,
148 size_t *bits)
149{
Jamie Foxefd82732018-11-26 10:34:32 +0000150 enum tfm_crypto_err_t err;
151
152 err = tfm_crypto_memory_check(type, sizeof(psa_key_type_t),
153 TFM_MEMORY_ACCESS_RW);
154 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
155 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
156 }
157
158 err = tfm_crypto_memory_check(bits, sizeof(size_t), TFM_MEMORY_ACCESS_RW);
159 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
160 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
161 }
162
Antonio de Angelis8908f472018-08-31 15:44:25 +0100163 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
164 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
165 }
166
167 if (key_storage[key].in_use == TFM_CRYPTO_NOT_IN_USE) {
168 return TFM_CRYPTO_ERR_PSA_ERROR_EMPTY_SLOT;
169 }
170
171 /* Get basic metadata */
172 *type = key_storage[key].type;
173 *bits = PSA_BYTES_TO_BITS(key_storage[key].data_length);
174
175 return TFM_CRYPTO_ERR_PSA_SUCCESS;
176}
177
178enum tfm_crypto_err_t tfm_crypto_export_key(psa_key_slot_t key,
179 uint8_t *data,
180 size_t data_size,
181 size_t *data_length)
182{
Jamie Foxefd82732018-11-26 10:34:32 +0000183 enum tfm_crypto_err_t err;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100184
Jamie Foxefd82732018-11-26 10:34:32 +0000185 err = tfm_crypto_memory_check(data, data_size, TFM_MEMORY_ACCESS_RW);
186 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angelis8908f472018-08-31 15:44:25 +0100187 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
188 }
189
Jamie Foxefd82732018-11-26 10:34:32 +0000190 err = tfm_crypto_memory_check(data_length, sizeof(size_t),
191 TFM_MEMORY_ACCESS_RW);
192 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
193 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100194 }
195
Jamie Foxefd82732018-11-26 10:34:32 +0000196 return tfm_crypto_get_key(key, PSA_KEY_USAGE_EXPORT, 0, data, data_size,
197 data_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100198}
199
200enum tfm_crypto_err_t tfm_crypto_export_public_key(psa_key_slot_t key,
201 uint8_t *data,
202 size_t data_size,
203 size_t *data_length)
204{
205 /* FIXME: This API is not supported yet */
206 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
207}
Jamie Foxefd82732018-11-26 10:34:32 +0000208
209enum tfm_crypto_err_t tfm_crypto_key_policy_init(psa_key_policy_t *policy)
210{
211 enum tfm_crypto_err_t err;
212
213 err = tfm_crypto_memory_check(policy, sizeof(psa_key_policy_t),
214 TFM_MEMORY_ACCESS_RW);
215 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
216 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
217 }
218
219 policy->usage = 0;
220 policy->alg = 0;
221
222 return TFM_CRYPTO_ERR_PSA_SUCCESS;
223}
224
225enum tfm_crypto_err_t tfm_crypto_key_policy_set_usage(psa_key_policy_t *policy,
226 psa_key_usage_t usage,
227 psa_algorithm_t alg)
228{
229 enum tfm_crypto_err_t err;
230
231 err = tfm_crypto_memory_check(policy, sizeof(psa_key_policy_t),
232 TFM_MEMORY_ACCESS_RW);
233 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
234 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
235 }
236
237 policy->usage = usage;
238 policy->alg = alg;
239
240 return TFM_CRYPTO_ERR_PSA_SUCCESS;
241}
242
243enum tfm_crypto_err_t tfm_crypto_key_policy_get_usage(
244 const psa_key_policy_t *policy,
245 psa_key_usage_t *usage)
246{
247 enum tfm_crypto_err_t err;
248
249 err = tfm_crypto_memory_check((psa_key_policy_t *)policy,
250 sizeof(psa_key_policy_t),
251 TFM_MEMORY_ACCESS_RO);
252 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
253 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
254 }
255
256 err = tfm_crypto_memory_check((psa_key_policy_t *)usage,
257 sizeof(psa_key_usage_t),
258 TFM_MEMORY_ACCESS_RW);
259 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
260 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
261 }
262
263 *usage = policy->usage;
264
265 return TFM_CRYPTO_ERR_PSA_SUCCESS;
266}
267
268enum tfm_crypto_err_t tfm_crypto_key_policy_get_algorithm(
269 const psa_key_policy_t *policy,
270 psa_algorithm_t *alg)
271{
272 enum tfm_crypto_err_t err;
273
274 err = tfm_crypto_memory_check((psa_key_policy_t *)policy,
275 sizeof(psa_key_policy_t),
276 TFM_MEMORY_ACCESS_RO);
277 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
278 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
279 }
280
281 err = tfm_crypto_memory_check((psa_key_policy_t *)alg,
282 sizeof(psa_algorithm_t),
283 TFM_MEMORY_ACCESS_RW);
284 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
285 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
286 }
287
288 *alg = policy->alg;
289
290 return TFM_CRYPTO_ERR_PSA_SUCCESS;
291}
292
293enum tfm_crypto_err_t tfm_crypto_set_key_policy(psa_key_slot_t key,
294 const psa_key_policy_t *policy)
295{
296 enum tfm_crypto_err_t err;
297
298 err = tfm_crypto_memory_check((psa_key_policy_t *)policy,
299 sizeof(psa_key_policy_t),
300 TFM_MEMORY_ACCESS_RO);
301 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
302 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
303 }
304
305 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
306 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
307 }
308
309 /* Check that the policy is valid */
310 if (policy->usage & ~(PSA_KEY_USAGE_EXPORT
311 | PSA_KEY_USAGE_ENCRYPT
312 | PSA_KEY_USAGE_DECRYPT
313 | PSA_KEY_USAGE_SIGN
314 | PSA_KEY_USAGE_VERIFY
315 | PSA_KEY_USAGE_DERIVE)) {
316 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
317 }
318
319 /* Changing the policy of an occupied slot is not permitted as
320 * this is a requirement of the PSA Crypto API
321 */
322 if (key_storage[key].in_use != TFM_CRYPTO_NOT_IN_USE) {
323 return TFM_CRYPTO_ERR_PSA_ERROR_OCCUPIED_SLOT;
324 }
325
326 key_storage[key].policy = *policy;
327
328 return TFM_CRYPTO_ERR_PSA_SUCCESS;
329}
330
331enum tfm_crypto_err_t tfm_crypto_get_key_policy(psa_key_slot_t key,
332 psa_key_policy_t *policy)
333{
334 enum tfm_crypto_err_t err;
335
336 err = tfm_crypto_memory_check(policy, sizeof(psa_key_policy_t),
337 TFM_MEMORY_ACCESS_RW);
338 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
339 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
340 }
341
342 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
343 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
344 }
345
346 *policy = key_storage[key].policy;
347
348 return TFM_CRYPTO_ERR_PSA_SUCCESS;
349}
350
351enum tfm_crypto_err_t tfm_crypto_set_key_lifetime(psa_key_slot_t key,
352 psa_key_lifetime_t lifetime)
353{
354 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
355 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
356 }
357
358 /* Check that the lifetime is valid */
359 if (lifetime != PSA_KEY_LIFETIME_VOLATILE
360 && lifetime != PSA_KEY_LIFETIME_PERSISTENT
361 && lifetime != PSA_KEY_LIFETIME_WRITE_ONCE) {
362 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
363 }
364
365 /* TF-M Crypto service does not support changing the lifetime of an occupied
366 * slot.
367 */
368 if (key_storage[key].in_use != TFM_CRYPTO_NOT_IN_USE) {
369 return TFM_CRYPTO_ERR_PSA_ERROR_OCCUPIED_SLOT;
370 }
371
372 /* Only volatile keys are currently supported */
373 if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
374 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
375 }
376
377 key_storage[key].lifetime = lifetime;
378
379 return TFM_CRYPTO_ERR_PSA_SUCCESS;
380}
381
382enum tfm_crypto_err_t tfm_crypto_get_key_lifetime(psa_key_slot_t key,
383 psa_key_lifetime_t *lifetime)
384{
385 enum tfm_crypto_err_t err;
386
387 err = tfm_crypto_memory_check(lifetime, sizeof(psa_key_lifetime_t),
388 TFM_MEMORY_ACCESS_RW);
389 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
390 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
391 }
392
393 if (key >= TFM_CRYPTO_KEY_STORAGE_NUM) {
394 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
395 }
396
397 *lifetime = key_storage[key].lifetime;
398
399 return TFM_CRYPTO_ERR_PSA_SUCCESS;
400}
401
Antonio de Angelis8908f472018-08-31 15:44:25 +0100402/*!@}*/