blob: c186518bae7c260a1a24a85ec6820605be553c13 [file] [log] [blame]
Antonio de Angelis04debbd2019-10-14 12:12:52 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stddef.h>
9#include <stdint.h>
10
11/* FixMe: Use PSA_ERROR_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 */
16#include "tfm_mbedcrypto_include.h"
17
18#include "tfm_crypto_api.h"
19#include "tfm_crypto_defs.h"
20
21/*!
22 * \defgroup public_psa Public functions, PSA
23 *
24 */
25
26/*!@{*/
27psa_status_t tfm_crypto_key_derivation_setup(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
31{
32#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
33 return PSA_ERROR_NOT_SUPPORTED;
34#else
35 psa_status_t status = PSA_SUCCESS;
36 psa_key_derivation_operation_t *operation = NULL;
37
38 if ((in_len != 1) || (out_len != 1)) {
39 return PSA_ERROR_CONNECTION_REFUSED;
40 }
41
42 if ((out_vec[0].len != sizeof(uint32_t)) ||
43 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
44 return PSA_ERROR_CONNECTION_REFUSED;
45 }
46 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
47 uint32_t handle = iov->op_handle;
48 uint32_t *handle_out = out_vec[0].base;
49 psa_algorithm_t alg = iov->alg;
50
51 /* Allocate the operation context in the secure world */
52 status = tfm_crypto_operation_alloc(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
53 &handle,
54 (void **)&operation);
55 if (status != PSA_SUCCESS) {
56 return status;
57 }
58
59 *handle_out = handle;
60
61 status = psa_key_derivation_setup(operation, alg);
62 if (status != PSA_SUCCESS) {
63 /* Release the operation context, ignore if the operation fails. */
64 (void)tfm_crypto_operation_release(handle_out);
65 return status;
66 }
67
68 return status;
69#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
70}
71
72psa_status_t tfm_crypto_key_derivation_get_capacity(psa_invec in_vec[],
73 size_t in_len,
74 psa_outvec out_vec[],
75 size_t out_len)
76{
77#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
78 return PSA_ERROR_NOT_SUPPORTED;
79#else
80 psa_status_t status;
81 if ((in_len != 1) || (out_len != 1)) {
82 return PSA_ERROR_CONNECTION_REFUSED;
83 }
84
85 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
86 (out_vec[0].len != sizeof(size_t))) {
87 return PSA_ERROR_CONNECTION_REFUSED;
88 }
89 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
90
91 uint32_t handle = iov->op_handle;
92 size_t *capacity = out_vec[0].base;
93 psa_key_derivation_operation_t *operation = NULL;
94
95 /* Look up the corresponding operation context */
96 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
97 handle,
98 (void **)&operation);
99 if (status != PSA_SUCCESS) {
100 *capacity = 0;
101 return status;
102 }
103
104 return psa_key_derivation_get_capacity(operation, capacity);
105#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
106}
107
108psa_status_t tfm_crypto_key_derivation_set_capacity(psa_invec in_vec[],
109 size_t in_len,
110 psa_outvec out_vec[],
111 size_t out_len)
112{
113#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
114 return PSA_ERROR_NOT_SUPPORTED;
115#else
116 psa_status_t status;
117 if ((in_len != 1) || (out_len != 0)) {
118 return PSA_ERROR_CONNECTION_REFUSED;
119 }
120
121 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
122 return PSA_ERROR_CONNECTION_REFUSED;
123 }
124 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
125
126 uint32_t handle = iov->op_handle;
127 size_t capacity = iov->capacity;
128 psa_key_derivation_operation_t *operation = NULL;
129
130 /* Look up the corresponding operation context */
131 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
132 handle,
133 (void **)&operation);
134 if (status != PSA_SUCCESS) {
135 return status;
136 }
137
138 return psa_key_derivation_set_capacity(operation, capacity);
139#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
140}
141
142psa_status_t tfm_crypto_key_derivation_input_bytes(psa_invec in_vec[],
143 size_t in_len,
144 psa_outvec out_vec[],
145 size_t out_len)
146{
147#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
148 return PSA_ERROR_NOT_SUPPORTED;
149#else
150 psa_status_t status;
151 if ((in_len != 2) || (out_len != 0)) {
152 return PSA_ERROR_CONNECTION_REFUSED;
153 }
154
155 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
156 return PSA_ERROR_CONNECTION_REFUSED;
157 }
158 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
159
160 uint32_t handle = iov->op_handle;
161 psa_key_derivation_step_t step = iov->step;
162 const uint8_t *data = in_vec[1].base;
163 size_t data_length = in_vec[1].len;
164 psa_key_derivation_operation_t *operation = NULL;
165
166 /* Look up the corresponding operation context */
167 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
168 handle,
169 (void **)&operation);
170 if (status != PSA_SUCCESS) {
171 return status;
172 }
173
174 return psa_key_derivation_input_bytes(operation, step, data, data_length);
175#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
176}
177
178psa_status_t tfm_crypto_key_derivation_output_bytes(psa_invec in_vec[],
179 size_t in_len,
180 psa_outvec out_vec[],
181 size_t out_len)
182{
183#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
184 return PSA_ERROR_NOT_SUPPORTED;
185#else
186 psa_status_t status;
187 if ((in_len != 1) || (out_len != 1)) {
188 return PSA_ERROR_CONNECTION_REFUSED;
189 }
190
191 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
192 return PSA_ERROR_CONNECTION_REFUSED;
193 }
194 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
195
196 uint32_t handle = iov->op_handle;
197 uint8_t *output = out_vec[0].base;
198 size_t output_length = out_vec[0].len;
199 psa_key_derivation_operation_t *operation = NULL;
200
201 /* Look up the corresponding operation context */
202 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
203 handle,
204 (void **)&operation);
205 if (status != PSA_SUCCESS) {
206 return status;
207 }
208
209 return psa_key_derivation_output_bytes(operation, output, output_length);
210#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
211}
212
213psa_status_t tfm_crypto_key_derivation_input_key(psa_invec in_vec[],
214 size_t in_len,
215 psa_outvec out_vec[],
216 size_t out_len)
217{
218#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
219 return PSA_ERROR_NOT_SUPPORTED;
220#else
221 psa_status_t status;
222 if ((in_len != 1) || (out_len != 0)) {
223 return PSA_ERROR_CONNECTION_REFUSED;
224 }
225
226 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
227 return PSA_ERROR_CONNECTION_REFUSED;
228 }
229 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
230
231 uint32_t handle = iov->op_handle;
232 psa_key_handle_t key_handle = iov->key_handle;
233 psa_key_derivation_step_t step = iov->step;
234 psa_key_derivation_operation_t *operation = NULL;
235
236 status = tfm_crypto_check_handle_owner(key_handle, NULL);
237 if (status != PSA_SUCCESS) {
238 return status;
239 }
240
241 /* Look up the corresponding operation context */
242 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
243 handle,
244 (void **)&operation);
245 if (status != PSA_SUCCESS) {
246 return status;
247 }
248
249 return psa_key_derivation_input_key(operation, step, key_handle);
250#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
251}
252
253psa_status_t tfm_crypto_key_derivation_output_key(psa_invec in_vec[],
254 size_t in_len,
255 psa_outvec out_vec[],
256 size_t out_len)
257{
258#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
259 return PSA_ERROR_NOT_SUPPORTED;
260#else
261 psa_status_t status;
262 if ((in_len != 2) || (out_len != 1)) {
263 return PSA_ERROR_CONNECTION_REFUSED;
264 }
265
266 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
267 (in_vec[1].len != sizeof(psa_key_attributes_t)) ||
268 (out_vec[0].len != sizeof(psa_key_handle_t))) {
269 return PSA_ERROR_CONNECTION_REFUSED;
270 }
271 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
272
273 uint32_t handle = iov->op_handle;
274 const psa_key_attributes_t *key_attributes = in_vec[1].base;
275 psa_key_derivation_operation_t *operation = NULL;
276 psa_key_handle_t *key_handle = out_vec[0].base;
Jamie Fox99360e82020-02-20 16:00:09 +0000277 uint32_t index;
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100278
279 /* Look up the corresponding operation context */
280 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
281 handle,
282 (void **)&operation);
283 if (status != PSA_SUCCESS) {
284 return status;
285 }
Jamie Fox99360e82020-02-20 16:00:09 +0000286
287 status = tfm_crypto_check_key_storage(&index);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100288 if (status != PSA_SUCCESS) {
289 return status;
290 }
Jamie Fox99360e82020-02-20 16:00:09 +0000291
292 status = psa_key_derivation_output_key(key_attributes, operation,
293 key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100294 if (status == PSA_SUCCESS) {
Jamie Fox99360e82020-02-20 16:00:09 +0000295 status = tfm_crypto_set_key_storage(index, *key_handle);
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100296 }
Jamie Fox99360e82020-02-20 16:00:09 +0000297
Antonio de Angelis04debbd2019-10-14 12:12:52 +0100298 return status;
299#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
300}
301
302psa_status_t tfm_crypto_key_derivation_abort(psa_invec in_vec[],
303 size_t in_len,
304 psa_outvec out_vec[],
305 size_t out_len)
306{
307#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
308 return PSA_ERROR_NOT_SUPPORTED;
309#else
310 psa_status_t status;
311 if ((in_len != 1) || (out_len != 1)) {
312 return PSA_ERROR_CONNECTION_REFUSED;
313 }
314
315 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
316 (out_vec[0].len != sizeof(uint32_t))) {
317 return PSA_ERROR_CONNECTION_REFUSED;
318 }
319 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
320
321 uint32_t handle = iov->op_handle;
322 uint32_t *handle_out = out_vec[0].base;
323 psa_key_derivation_operation_t *operation = NULL;
324
325 /* Init the handle in the operation with the one passed from the iov */
326 *handle_out = iov->op_handle;
327
328 /* Look up the corresponding operation context */
329 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
330 handle,
331 (void **)&operation);
332 if (status != PSA_SUCCESS) {
333 /* Operation does not exist, so abort has no effect */
334 return PSA_SUCCESS;
335 }
336
337 *handle_out = handle;
338
339 status = psa_key_derivation_abort(operation);
340 if (status != PSA_SUCCESS) {
341 /* Release the operation context, ignore if the operation fails. */
342 (void)tfm_crypto_operation_release(handle_out);
343 return status;
344 }
345
346 status = tfm_crypto_operation_release(handle_out);
347
348 return status;
349#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
350}
351
352psa_status_t tfm_crypto_key_derivation_key_agreement(psa_invec in_vec[],
353 size_t in_len,
354 psa_outvec out_vec[],
355 size_t out_len)
356{
357#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
358 return PSA_ERROR_NOT_SUPPORTED;
359#else
360 psa_status_t status;
361 if ((in_len != 2) || (out_len != 0)) {
362 return PSA_ERROR_CONNECTION_REFUSED;
363 }
364
365 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
366 return PSA_ERROR_CONNECTION_REFUSED;
367 }
368 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
369
370 uint32_t handle = iov->op_handle;
371 psa_key_handle_t private_key = iov->key_handle;
372 const uint8_t *peer_key = in_vec[1].base;
373 size_t peer_key_length = in_vec[1].len;
374 psa_key_derivation_operation_t *operation = NULL;
375 psa_key_derivation_step_t step = iov->step;
376
377 status = tfm_crypto_check_handle_owner(private_key, NULL);
378 if (status != PSA_SUCCESS) {
379 return status;
380 }
381
382 /* Look up the corresponding operation context */
383 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
384 handle,
385 (void **)&operation);
386 if (status != PSA_SUCCESS) {
387 return status;
388 }
389
390 return psa_key_derivation_key_agreement(operation, step,
391 private_key,
392 peer_key,
393 peer_key_length);
394#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
395}
396
397psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
398 size_t in_len,
399 psa_outvec out_vec[],
400 size_t out_len)
401{
402#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
403 return PSA_ERROR_NOT_SUPPORTED;
404#else
405 if ((in_len != 1) || (out_len != 1)) {
406 return PSA_ERROR_CONNECTION_REFUSED;
407 }
408
409 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
410 return PSA_ERROR_CONNECTION_REFUSED;
411 }
412 uint8_t *output = out_vec[0].base;
413 size_t output_size = out_vec[0].len;
414
415 return psa_generate_random(output, output_size);
416#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
417}
418
419psa_status_t tfm_crypto_raw_key_agreement(psa_invec in_vec[],
420 size_t in_len,
421 psa_outvec out_vec[],
422 size_t out_len)
423{
424#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
425 return PSA_ERROR_NOT_SUPPORTED;
426#else
427 if ((in_len != 2) || (out_len != 1)) {
428 return PSA_ERROR_CONNECTION_REFUSED;
429 }
430
431 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
432 return PSA_ERROR_CONNECTION_REFUSED;
433 }
434 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
435 uint8_t *output = out_vec[0].base;
436 size_t output_size = out_vec[0].len;
437 psa_algorithm_t alg = iov->alg;
438 psa_key_handle_t private_key = iov->key_handle;
439 const uint8_t *peer_key = in_vec[1].base;
440 size_t peer_key_length = in_vec[1].len;
441
442 return psa_raw_key_agreement(alg, private_key, peer_key, peer_key_length,
443 output, output_size, &out_vec[0].len);
444#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
445}
446/*!@}*/