blob: 80958f5949eff09f44421b147c1afc636e956d5d [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;
277 //int32_t partition_id = 0;
278 //uint32_t index = 0;
279
280 /* Look up the corresponding operation context */
281 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
282 handle,
283 (void **)&operation);
284 if (status != PSA_SUCCESS) {
285 return status;
286 }
287 /*
288 status = tfm_crypto_check_key_storage(&partition_id, &index);
289 if (status != PSA_SUCCESS) {
290 return status;
291 }
292 */
293 status = psa_key_derivation_output_key(key_attributes, operation, key_handle);
294 /*
295 if (status == PSA_SUCCESS) {
296 status = tfm_crypto_set_key_storage(partition_id, index, *key_handle);
297 }
298 */
299 return status;
300#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
301}
302
303psa_status_t tfm_crypto_key_derivation_abort(psa_invec in_vec[],
304 size_t in_len,
305 psa_outvec out_vec[],
306 size_t out_len)
307{
308#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
309 return PSA_ERROR_NOT_SUPPORTED;
310#else
311 psa_status_t status;
312 if ((in_len != 1) || (out_len != 1)) {
313 return PSA_ERROR_CONNECTION_REFUSED;
314 }
315
316 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
317 (out_vec[0].len != sizeof(uint32_t))) {
318 return PSA_ERROR_CONNECTION_REFUSED;
319 }
320 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
321
322 uint32_t handle = iov->op_handle;
323 uint32_t *handle_out = out_vec[0].base;
324 psa_key_derivation_operation_t *operation = NULL;
325
326 /* Init the handle in the operation with the one passed from the iov */
327 *handle_out = iov->op_handle;
328
329 /* Look up the corresponding operation context */
330 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
331 handle,
332 (void **)&operation);
333 if (status != PSA_SUCCESS) {
334 /* Operation does not exist, so abort has no effect */
335 return PSA_SUCCESS;
336 }
337
338 *handle_out = handle;
339
340 status = psa_key_derivation_abort(operation);
341 if (status != PSA_SUCCESS) {
342 /* Release the operation context, ignore if the operation fails. */
343 (void)tfm_crypto_operation_release(handle_out);
344 return status;
345 }
346
347 status = tfm_crypto_operation_release(handle_out);
348
349 return status;
350#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
351}
352
353psa_status_t tfm_crypto_key_derivation_key_agreement(psa_invec in_vec[],
354 size_t in_len,
355 psa_outvec out_vec[],
356 size_t out_len)
357{
358#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
359 return PSA_ERROR_NOT_SUPPORTED;
360#else
361 psa_status_t status;
362 if ((in_len != 2) || (out_len != 0)) {
363 return PSA_ERROR_CONNECTION_REFUSED;
364 }
365
366 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
367 return PSA_ERROR_CONNECTION_REFUSED;
368 }
369 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
370
371 uint32_t handle = iov->op_handle;
372 psa_key_handle_t private_key = iov->key_handle;
373 const uint8_t *peer_key = in_vec[1].base;
374 size_t peer_key_length = in_vec[1].len;
375 psa_key_derivation_operation_t *operation = NULL;
376 psa_key_derivation_step_t step = iov->step;
377
378 status = tfm_crypto_check_handle_owner(private_key, NULL);
379 if (status != PSA_SUCCESS) {
380 return status;
381 }
382
383 /* Look up the corresponding operation context */
384 status = tfm_crypto_operation_lookup(TFM_CRYPTO_KEY_DERIVATION_OPERATION,
385 handle,
386 (void **)&operation);
387 if (status != PSA_SUCCESS) {
388 return status;
389 }
390
391 return psa_key_derivation_key_agreement(operation, step,
392 private_key,
393 peer_key,
394 peer_key_length);
395#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
396}
397
398psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
399 size_t in_len,
400 psa_outvec out_vec[],
401 size_t out_len)
402{
403#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
404 return PSA_ERROR_NOT_SUPPORTED;
405#else
406 if ((in_len != 1) || (out_len != 1)) {
407 return PSA_ERROR_CONNECTION_REFUSED;
408 }
409
410 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
411 return PSA_ERROR_CONNECTION_REFUSED;
412 }
413 uint8_t *output = out_vec[0].base;
414 size_t output_size = out_vec[0].len;
415
416 return psa_generate_random(output, output_size);
417#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
418}
419
420psa_status_t tfm_crypto_raw_key_agreement(psa_invec in_vec[],
421 size_t in_len,
422 psa_outvec out_vec[],
423 size_t out_len)
424{
425#ifdef TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED
426 return PSA_ERROR_NOT_SUPPORTED;
427#else
428 if ((in_len != 2) || (out_len != 1)) {
429 return PSA_ERROR_CONNECTION_REFUSED;
430 }
431
432 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
433 return PSA_ERROR_CONNECTION_REFUSED;
434 }
435 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
436 uint8_t *output = out_vec[0].base;
437 size_t output_size = out_vec[0].len;
438 psa_algorithm_t alg = iov->alg;
439 psa_key_handle_t private_key = iov->key_handle;
440 const uint8_t *peer_key = in_vec[1].base;
441 size_t peer_key_length = in_vec[1].len;
442
443 return psa_raw_key_agreement(alg, private_key, peer_key, peer_key_length,
444 output, output_size, &out_vec[0].len);
445#endif /* TFM_CRYPTO_KEY_DERIVATION_MODULE_DISABLED */
446}
447/*!@}*/