blob: 1cf138d0d914c4af3f127ddeccc915c1478f97d3 [file] [log] [blame]
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +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_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_get_generator_capacity(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
31{
32 psa_status_t status;
33 if ((in_len != 1) || (out_len != 1)) {
34 return PSA_CONNECTION_REFUSED;
35 }
36
37 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
38 (out_vec[0].len != sizeof(size_t))) {
39 return PSA_CONNECTION_REFUSED;
40 }
41 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
42
43 uint32_t handle = iov->op_handle;
44 size_t *capacity = out_vec[0].base;
45 psa_crypto_generator_t *generator = NULL;
46
47 /* Look up the corresponding operation context */
48 status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
49 handle,
50 (void **)&generator);
51 if (status != PSA_SUCCESS) {
52 *capacity = 0;
53 return status;
54 }
55
56 return psa_get_generator_capacity(generator, capacity);
57}
58
59psa_status_t tfm_crypto_generator_read(psa_invec in_vec[],
60 size_t in_len,
61 psa_outvec out_vec[],
62 size_t out_len)
63{
64 psa_status_t status;
65 if ((in_len != 1) || (out_len != 1)) {
66 return PSA_CONNECTION_REFUSED;
67 }
68
69 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
70 return PSA_CONNECTION_REFUSED;
71 }
72 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
73
74 uint32_t handle = iov->op_handle;
75 uint8_t *output = out_vec[0].base;
76 size_t output_length = out_vec[0].len;
77 psa_crypto_generator_t *generator = NULL;
78
79 /* Look up the corresponding operation context */
80 status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
81 handle,
82 (void **)&generator);
83 if (status != PSA_SUCCESS) {
84 return status;
85 }
86
87 return psa_generator_read(generator, output, output_length);
88}
89
90psa_status_t tfm_crypto_generator_import_key(psa_invec in_vec[],
91 size_t in_len,
92 psa_outvec out_vec[],
93 size_t out_len)
94{
95 psa_status_t status;
96 if ((in_len != 2) || (out_len != 0)) {
97 return PSA_CONNECTION_REFUSED;
98 }
99
100 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
101 (in_vec[1].len != sizeof(size_t))) {
102 return PSA_CONNECTION_REFUSED;
103 }
104 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
105
106 uint32_t handle = iov->op_handle;
107 psa_key_handle_t key_handle = iov->key_handle;
108 psa_key_type_t type = iov->type;
109 size_t bits = *(size_t *)(in_vec[1].base);
110 psa_crypto_generator_t *generator = NULL;
111
112 /* Look up the corresponding operation context */
113 status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
114 handle,
115 (void **)&generator);
116 if (status != PSA_SUCCESS) {
117 return status;
118 }
119
120 return psa_generator_import_key(key_handle, type, bits, generator);
121}
122
123psa_status_t tfm_crypto_generator_abort(psa_invec in_vec[],
124 size_t in_len,
125 psa_outvec out_vec[],
126 size_t out_len)
127{
128 psa_status_t status;
129 if ((in_len != 1) || (out_len != 1)) {
130 return PSA_CONNECTION_REFUSED;
131 }
132
133 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
134 (out_vec[0].len != sizeof(uint32_t))) {
135 return PSA_CONNECTION_REFUSED;
136 }
137 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
138
139 uint32_t handle = iov->op_handle;
140 uint32_t *handle_out = out_vec[0].base;
141 psa_crypto_generator_t *generator = NULL;
142
143 /* Init the handle in the operation with the one passed from the iov */
144 *handle_out = iov->op_handle;
145
146 /* Look up the corresponding operation context */
147 status = tfm_crypto_operation_lookup(TFM_CRYPTO_GENERATOR_OPERATION,
148 handle,
149 (void **)&generator);
150 if (status != PSA_SUCCESS) {
151 /* Operation does not exist, so abort has no effect */
152 return PSA_SUCCESS;
153 }
154
155 *handle_out = handle;
156
157 status = psa_generator_abort(generator);
158 if (status != PSA_SUCCESS) {
159 return status;
160 }
161
162 status = tfm_crypto_operation_release(handle_out);
163
164 return status;
165}
166
167psa_status_t tfm_crypto_key_derivation(psa_invec in_vec[],
168 size_t in_len,
169 psa_outvec out_vec[],
170 size_t out_len)
171{
172 psa_status_t status;
173 if (!((in_len == 1) || (in_len == 2) || (in_len == 3)) || (out_len != 1)) {
174 return PSA_CONNECTION_REFUSED;
175 }
176
177 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
178 (out_vec[0].len != sizeof(uint32_t))) {
179 return PSA_CONNECTION_REFUSED;
180 }
181 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
182
183 uint32_t handle = iov->op_handle;
184 uint32_t *handle_out = out_vec[0].base;
185 psa_key_handle_t key_handle = iov->key_handle;
186 psa_algorithm_t alg = iov->alg;
187 const uint8_t *salt = NULL;
188 size_t salt_length = 0;
189 const uint8_t *label = NULL;
190 size_t label_length = 0;
191 size_t capacity = iov->capacity;
192 psa_crypto_generator_t *generator = NULL;
193
194 if (in_len > 1) {
195 salt = in_vec[2].base;
196 salt_length = in_vec[2].len;
197 }
198
199 if (in_len > 2) {
200 label = in_vec[3].base;
201 label_length = in_vec[3].len;
202 }
203
204 /* Allocate the generator context in the secure world */
205 status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
206 &handle,
207 (void **)&generator);
208 if (status != PSA_SUCCESS) {
209 return status;
210 }
211
212 *handle_out = handle;
213
214 return psa_key_derivation(generator, key_handle, alg, salt, salt_length,
215 label, label_length, capacity);
216}
217
218psa_status_t tfm_crypto_key_agreement(psa_invec in_vec[],
219 size_t in_len,
220 psa_outvec out_vec[],
221 size_t out_len)
222{
223 psa_status_t status;
224 if ((in_len != 2) || (out_len != 1)) {
225 return PSA_CONNECTION_REFUSED;
226 }
227
228 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
229 (out_vec[0].len != sizeof(uint32_t))) {
230 return PSA_CONNECTION_REFUSED;
231 }
232 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
233
234 uint32_t handle = iov->op_handle;
235 uint32_t *handle_out = out_vec[0].base;
236 psa_key_handle_t private_key = iov->key_handle;
237 psa_algorithm_t alg = iov->alg;
238 const uint8_t *peer_key = in_vec[1].base;
239 size_t peer_key_length = in_vec[1].len;
240 psa_crypto_generator_t *generator = NULL;
241
242 /* Allocate the generator context in the secure world */
243 status = tfm_crypto_operation_alloc(TFM_CRYPTO_GENERATOR_OPERATION,
244 &handle,
245 (void **)&generator);
246 if (status != PSA_SUCCESS) {
247 return status;
248 }
249
250 *handle_out = handle;
251
252 return psa_key_agreement(generator, private_key,
253 peer_key, peer_key_length, alg);
254}
255
256psa_status_t tfm_crypto_generate_random(psa_invec in_vec[],
257 size_t in_len,
258 psa_outvec out_vec[],
259 size_t out_len)
260{
261 if ((in_len != 1) || (out_len != 1)) {
262 return PSA_CONNECTION_REFUSED;
263 }
264
265 if (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) {
266 return PSA_CONNECTION_REFUSED;
267 }
268 uint8_t *output = out_vec[0].base;
269 size_t output_size = out_vec[0].len;
270
271 return psa_generate_random(output, output_size);
272}
273
274psa_status_t tfm_crypto_generate_key(psa_invec in_vec[],
275 size_t in_len,
276 psa_outvec out_vec[],
277 size_t out_len)
278{
279 if (!((in_len == 2) || (in_len == 3)) || (out_len != 0)) {
280 return PSA_CONNECTION_REFUSED;
281 }
282
283 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
284 (in_vec[1].len != sizeof(size_t))) {
285 return PSA_CONNECTION_REFUSED;
286 }
287 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
288 psa_key_handle_t key_handle = iov->key_handle;
289 psa_key_type_t type = iov->type;
290 size_t bits = *((size_t *)(in_vec[1].base));
291 const void *extra = NULL;
292 size_t extra_size = 0;
293
294 if (in_len == 3) {
295 extra = in_vec[2].base;
296 extra_size = in_vec[2].len;
297 }
298
299 return psa_generate_key(key_handle, type, bits, extra, extra_size);
300}
301/*!@}*/