blob: 6ebf1b534dba113e01125cb032cfd71dcb86738d [file] [log] [blame]
Julian Halld4071382021-07-07 16:45:53 +01001/*
2 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <string.h>
8#include <stdlib.h>
9#include <psa/crypto.h>
10#include "psa_crypto_client.h"
11#include <protocols/rpc/common/packed-c/status.h>
12#include <protocols/service/crypto/packed-c/opcodes.h>
Julian Halle7bccbe2021-07-16 09:50:34 +010013#include <protocols/service/crypto/packed-c/cipher.h>
Julian Halld4071382021-07-07 16:45:53 +010014#include <common/tlv/tlv.h>
15
Julian Halle7bccbe2021-07-16 09:50:34 +010016static psa_status_t common_cipher_setup(psa_cipher_operation_t *operation,
17 psa_key_id_t key,
18 psa_algorithm_t alg,
19 uint32_t opcode)
20{
21 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
22 struct ts_crypto_cipher_setup_in req_msg;
23 size_t req_len = sizeof(struct ts_crypto_cipher_setup_in);
24
25 req_msg.key_id = key;
26 req_msg.alg = alg;
27
28 rpc_call_handle call_handle;
29 uint8_t *req_buf;
30
31 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
32
33 if (call_handle) {
34
35 uint8_t *resp_buf;
36 size_t resp_len;
37 int opstatus;
38
39 memcpy(req_buf, &req_msg, req_len);
40
41 psa_crypto_client_instance.rpc_status =
42 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
43 opcode, &opstatus, &resp_buf, &resp_len);
44
45 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
46
47 psa_status = opstatus;
48
49 if (psa_status == PSA_SUCCESS) {
50
51 if (resp_len >= sizeof(struct ts_crypto_cipher_setup_out)) {
52
53 struct ts_crypto_cipher_setup_out resp_msg;
54 memcpy(&resp_msg, resp_buf, sizeof(struct ts_crypto_cipher_setup_out));
55 operation->handle = resp_msg.op_handle;
56 }
57 else {
58 /* Failed to decode response message */
59 psa_status = PSA_ERROR_GENERIC_ERROR;
60 }
61 }
62 }
63
64 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
65 }
66
67 return psa_status;
68}
69
Julian Halld4071382021-07-07 16:45:53 +010070psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
71 psa_key_id_t key,
72 psa_algorithm_t alg)
73{
Julian Halle7bccbe2021-07-16 09:50:34 +010074 return common_cipher_setup(operation, key, alg, TS_CRYPTO_OPCODE_CIPHER_ENCRYPT_SETUP);
Julian Halld4071382021-07-07 16:45:53 +010075}
76
77psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
78 psa_key_id_t key,
79 psa_algorithm_t alg)
80{
Julian Halle7bccbe2021-07-16 09:50:34 +010081 return common_cipher_setup(operation, key, alg, TS_CRYPTO_OPCODE_CIPHER_DECRYPT_SETUP);
Julian Halld4071382021-07-07 16:45:53 +010082}
83
84psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
85 uint8_t *iv,
86 size_t iv_size,
87 size_t *iv_length)
88{
Julian Halle7bccbe2021-07-16 09:50:34 +010089 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
90 struct ts_crypto_cipher_generate_iv_in req_msg;
91 size_t req_fixed_len = sizeof(struct ts_crypto_cipher_generate_iv_in);
92 size_t req_len = req_fixed_len;
93
94 *iv_length = 0;
95 req_msg.op_handle = operation->handle;
96
97 rpc_call_handle call_handle;
98 uint8_t *req_buf;
99
100 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
101
102 if (call_handle) {
103
104 uint8_t *resp_buf;
105 size_t resp_len;
106 int opstatus;
107
108 memcpy(req_buf, &req_msg, req_fixed_len);
109
110 psa_crypto_client_instance.rpc_status =
111 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
112 TS_CRYPTO_OPCODE_CIPHER_GENERATE_IV, &opstatus, &resp_buf, &resp_len);
113
114 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
115
116 psa_status = opstatus;
117
118 if (psa_status == PSA_SUCCESS) {
119
120 struct tlv_const_iterator resp_iter;
121 struct tlv_record decoded_record;
122 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
123
124 if (tlv_find_decode(&resp_iter,
125 TS_CRYPTO_CIPHER_GENERATE_IV_OUT_TAG_IV, &decoded_record)) {
126
127 if (decoded_record.length <= iv_size) {
128
129 memcpy(iv, decoded_record.value, decoded_record.length);
130 *iv_length = decoded_record.length;
131 }
132 else {
133 /* Provided buffer is too small */
134 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
135 }
136 }
137 else {
138 /* Mandatory response parameter missing */
139 psa_status = PSA_ERROR_GENERIC_ERROR;
140 }
141 }
142 }
143
144 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
145 }
146
147 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100148}
149
150psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
151 const uint8_t *iv,
152 size_t iv_length)
153{
Julian Halle7bccbe2021-07-16 09:50:34 +0100154 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
155 struct ts_crypto_cipher_set_iv_in req_msg;
156 size_t req_fixed_len = sizeof(struct ts_crypto_cipher_set_iv_in);
157 size_t req_len = req_fixed_len;
158
159 req_msg.op_handle = operation->handle;
160
161 /* Mandatory input data parameter */
162 struct tlv_record data_record;
163 data_record.tag = TS_CRYPTO_CIPHER_SET_IV_IN_TAG_IV;
164 data_record.length = iv_length;
165 data_record.value = iv;
166 req_len += tlv_required_space(data_record.length);
167
168 rpc_call_handle call_handle;
169 uint8_t *req_buf;
170
171 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
172
173 if (call_handle) {
174
175 uint8_t *resp_buf;
176 size_t resp_len;
177 int opstatus;
178 struct tlv_iterator req_iter;
179
180 memcpy(req_buf, &req_msg, req_fixed_len);
181
182 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
183 tlv_encode(&req_iter, &data_record);
184
185 psa_crypto_client_instance.rpc_status =
186 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
187 TS_CRYPTO_OPCODE_CIPHER_SET_IV, &opstatus, &resp_buf, &resp_len);
188
189 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
190
191 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
192 }
193
194 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100195}
196
197psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
198 const uint8_t *input,
199 size_t input_length,
200 uint8_t *output,
201 size_t output_size,
202 size_t *output_length)
203{
Julian Halle7bccbe2021-07-16 09:50:34 +0100204 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
205 struct ts_crypto_cipher_update_in req_msg;
206 size_t req_fixed_len = sizeof(struct ts_crypto_cipher_update_in);
207 size_t req_len = req_fixed_len;
208
209 *output_length = 0;
210 req_msg.op_handle = operation->handle;
211
212 /* Mandatory input data parameter */
213 struct tlv_record data_record;
214 data_record.tag = TS_CRYPTO_CIPHER_UPDATE_IN_TAG_DATA;
215 data_record.length = input_length;
216 data_record.value = input;
217 req_len += tlv_required_space(data_record.length);
218
219 rpc_call_handle call_handle;
220 uint8_t *req_buf;
221
222 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
223
224 if (call_handle) {
225
226 uint8_t *resp_buf;
227 size_t resp_len;
228 int opstatus;
229 struct tlv_iterator req_iter;
230
231 memcpy(req_buf, &req_msg, req_fixed_len);
232
233 tlv_iterator_begin(&req_iter, &req_buf[req_fixed_len], req_len - req_fixed_len);
234 tlv_encode(&req_iter, &data_record);
235
236 psa_crypto_client_instance.rpc_status =
237 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
238 TS_CRYPTO_OPCODE_CIPHER_UPDATE, &opstatus, &resp_buf, &resp_len);
239
240 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
241
242 psa_status = opstatus;
243
244 if (psa_status == PSA_SUCCESS) {
245
246 struct tlv_const_iterator resp_iter;
247 struct tlv_record decoded_record;
248 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
249
250 if (tlv_find_decode(&resp_iter,
251 TS_CRYPTO_CIPHER_UPDATE_OUT_TAG_DATA, &decoded_record)) {
252
253 if (decoded_record.length <= output_size) {
254
255 memcpy(output, decoded_record.value, decoded_record.length);
256 *output_length = decoded_record.length;
257 }
258 else {
259 /* Provided buffer is too small */
260 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
261 }
262 }
263 else {
264 /* Mandatory response parameter missing */
265 psa_status = PSA_ERROR_GENERIC_ERROR;
266 }
267 }
268 }
269
270 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
271 }
272
273 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100274}
275
276psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
277 uint8_t *output,
278 size_t output_size,
279 size_t *output_length)
280{
Julian Halle7bccbe2021-07-16 09:50:34 +0100281 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
282 struct ts_crypto_cipher_finish_in req_msg;
283 size_t req_fixed_len = sizeof(struct ts_crypto_cipher_finish_in);
284 size_t req_len = req_fixed_len;
285
286 *output_length = 0;
287 req_msg.op_handle = operation->handle;
288
289 rpc_call_handle call_handle;
290 uint8_t *req_buf;
291
292 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
293
294 if (call_handle) {
295
296 uint8_t *resp_buf;
297 size_t resp_len;
298 int opstatus;
299
300 memcpy(req_buf, &req_msg, req_fixed_len);
301
302 psa_crypto_client_instance.rpc_status =
303 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
304 TS_CRYPTO_OPCODE_CIPHER_FINISH, &opstatus, &resp_buf, &resp_len);
305
306 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) {
307
308 psa_status = opstatus;
309
310 if (psa_status == PSA_SUCCESS) {
311
312 struct tlv_const_iterator resp_iter;
313 struct tlv_record decoded_record;
314 tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
315
316 if (tlv_find_decode(&resp_iter,
317 TS_CRYPTO_CIPHER_FINISH_OUT_TAG_DATA, &decoded_record)) {
318
319 if (decoded_record.length <= output_size) {
320
321 memcpy(output, decoded_record.value, decoded_record.length);
322 *output_length = decoded_record.length;
323 }
324 else {
325 /* Provided buffer is too small */
326 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
327 }
328 }
329 else {
330 /* Mandatory response parameter missing */
331 psa_status = PSA_ERROR_GENERIC_ERROR;
332 }
333 }
334 }
335
336 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
337 }
338
339 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100340}
341
342psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
343{
Julian Halle7bccbe2021-07-16 09:50:34 +0100344 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
345 struct ts_crypto_cipher_abort_in req_msg;
346 size_t req_fixed_len = sizeof(struct ts_crypto_cipher_abort_in);
347 size_t req_len = req_fixed_len;
348
349 req_msg.op_handle = operation->handle;
350
351 rpc_call_handle call_handle;
352 uint8_t *req_buf;
353
354 call_handle = rpc_caller_begin(psa_crypto_client_instance.caller, &req_buf, req_len);
355
356 if (call_handle) {
357
358 uint8_t *resp_buf;
359 size_t resp_len;
360 int opstatus;
361
362 memcpy(req_buf, &req_msg, req_fixed_len);
363
364 psa_crypto_client_instance.rpc_status =
365 rpc_caller_invoke(psa_crypto_client_instance.caller, call_handle,
366 TS_CRYPTO_OPCODE_CIPHER_ABORT, &opstatus, &resp_buf, &resp_len);
367
368 if (psa_crypto_client_instance.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
369
370 rpc_caller_end(psa_crypto_client_instance.caller, call_handle);
371 }
372
373 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100374}