blob: e8ee7af01bf881021bda93410741b1be3e8f7181 [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
Julian Hall99a57e32021-07-28 14:18:50 +010031 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +010032
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
Julian Hall99a57e32021-07-28 14:18:50 +010041 psa_crypto_client_instance.base.rpc_status =
42 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +010043 opcode, &opstatus, &resp_buf, &resp_len);
44
Julian Hall99a57e32021-07-28 14:18:50 +010045 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halle7bccbe2021-07-16 09:50:34 +010046
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
Julian Hall99a57e32021-07-28 14:18:50 +010064 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +010065 }
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
Julian Hall99a57e32021-07-28 14:18:50 +0100100 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +0100101
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
Julian Hall99a57e32021-07-28 14:18:50 +0100110 psa_crypto_client_instance.base.rpc_status =
111 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +0100112 TS_CRYPTO_OPCODE_CIPHER_GENERATE_IV, &opstatus, &resp_buf, &resp_len);
113
Julian Hall99a57e32021-07-28 14:18:50 +0100114 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halle7bccbe2021-07-16 09:50:34 +0100115
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
Julian Hall99a57e32021-07-28 14:18:50 +0100144 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +0100145 }
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
Julian Hall99a57e32021-07-28 14:18:50 +0100171 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +0100172
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
Julian Hall99a57e32021-07-28 14:18:50 +0100185 psa_crypto_client_instance.base.rpc_status =
186 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +0100187 TS_CRYPTO_OPCODE_CIPHER_SET_IV, &opstatus, &resp_buf, &resp_len);
188
Julian Hall99a57e32021-07-28 14:18:50 +0100189 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Halle7bccbe2021-07-16 09:50:34 +0100190
Julian Hall99a57e32021-07-28 14:18:50 +0100191 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +0100192 }
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
Julian Hall99a57e32021-07-28 14:18:50 +0100222 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +0100223
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
Julian Hall99a57e32021-07-28 14:18:50 +0100236 psa_crypto_client_instance.base.rpc_status =
237 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +0100238 TS_CRYPTO_OPCODE_CIPHER_UPDATE, &opstatus, &resp_buf, &resp_len);
239
Julian Hall99a57e32021-07-28 14:18:50 +0100240 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halle7bccbe2021-07-16 09:50:34 +0100241
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
Julian Hall99a57e32021-07-28 14:18:50 +0100270 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +0100271 }
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
Julian Hall99a57e32021-07-28 14:18:50 +0100292 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +0100293
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
Julian Hall99a57e32021-07-28 14:18:50 +0100302 psa_crypto_client_instance.base.rpc_status =
303 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +0100304 TS_CRYPTO_OPCODE_CIPHER_FINISH, &opstatus, &resp_buf, &resp_len);
305
Julian Hall99a57e32021-07-28 14:18:50 +0100306 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Halle7bccbe2021-07-16 09:50:34 +0100307
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
Julian Hall99a57e32021-07-28 14:18:50 +0100336 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +0100337 }
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
Julian Hall99a57e32021-07-28 14:18:50 +0100354 call_handle = rpc_caller_begin(psa_crypto_client_instance.base.caller, &req_buf, req_len);
Julian Halle7bccbe2021-07-16 09:50:34 +0100355
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
Julian Hall99a57e32021-07-28 14:18:50 +0100364 psa_crypto_client_instance.base.rpc_status =
365 rpc_caller_invoke(psa_crypto_client_instance.base.caller, call_handle,
Julian Halle7bccbe2021-07-16 09:50:34 +0100366 TS_CRYPTO_OPCODE_CIPHER_ABORT, &opstatus, &resp_buf, &resp_len);
367
Julian Hall99a57e32021-07-28 14:18:50 +0100368 if (psa_crypto_client_instance.base.rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
Julian Halle7bccbe2021-07-16 09:50:34 +0100369
Julian Hall99a57e32021-07-28 14:18:50 +0100370 rpc_caller_end(psa_crypto_client_instance.base.caller, call_handle);
Julian Halle7bccbe2021-07-16 09:50:34 +0100371 }
372
373 return psa_status;
Julian Halld4071382021-07-07 16:45:53 +0100374}
Julian Halld670b412021-07-19 15:16:27 +0100375
Julian Hall188953d2021-07-30 12:11:43 +0100376static size_t max_cipher_update_size(void)
377{
378 /* Returns the maximum number of bytes that may be
379 * carried as a parameter of the cipher_update operation
380 * using the packed-c encoding.
381 */
382 size_t payload_space = psa_crypto_client_instance.base.service_info.max_payload;
383 size_t overhead = sizeof(struct ts_crypto_cipher_update_in) + TLV_HDR_LEN;
384
385 return (payload_space > overhead) ? payload_space - overhead : 0;
386}
387
388static psa_status_t multi_cipher_update(psa_cipher_operation_t *operation,
389 const uint8_t *input,
390 size_t input_length,
391 uint8_t *output,
392 size_t output_size,
393 size_t *output_length)
394{
395 psa_status_t psa_status = PSA_SUCCESS;
396 size_t max_update_size = max_cipher_update_size();
397 size_t bytes_input = 0;
398 size_t bytes_output = 0;
399
400 *output_length = 0;
401
402 if (!max_update_size) {
403
404 /* Don't know the max update size so assume that the entire
405 * input and output can be handled in a single update. If
406 * this isn't true, the first cipher update operation will fail
407 * safely.
408 */
409 max_update_size = input_length;
410 }
411
412 while ((bytes_input < input_length) && (bytes_output < output_size)) {
413
414 size_t update_output_len = 0;
415 size_t bytes_remaining = input_length - bytes_input;
416 size_t update_len = (bytes_remaining < max_update_size) ?
417 bytes_remaining :
418 max_update_size;
419
420 psa_status = psa_cipher_update(operation,
421 &input[bytes_input], update_len,
422 &output[bytes_output], output_size - bytes_output, &update_output_len);
423
424 if (psa_status != PSA_SUCCESS) {
425
426 psa_cipher_abort(operation);
427 break;
428 }
429
430 bytes_input += update_len;
431 bytes_output += update_output_len;
432 }
433
434 if (psa_status == PSA_SUCCESS) {
435
436 if (bytes_output < output_size) {
437
438 size_t finish_output_len = 0;
439
440 psa_status = psa_cipher_finish(operation,
441 &output[bytes_output], output_size - bytes_output, &finish_output_len);
442
443 if (psa_status == PSA_SUCCESS) {
444
445 *output_length = bytes_output + finish_output_len;
446 }
447 }
448 else {
449
450 psa_cipher_abort(operation);
451 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
452 }
453 }
454
455 return psa_status;
456}
457
Julian Halld670b412021-07-19 15:16:27 +0100458psa_status_t psa_cipher_encrypt(psa_key_id_t key,
459 psa_algorithm_t alg,
460 const uint8_t *input,
461 size_t input_length,
462 uint8_t *output,
463 size_t output_size,
464 size_t *output_length)
465{
Julian Hall188953d2021-07-30 12:11:43 +0100466 psa_cipher_operation_t operation = psa_cipher_operation_init();
467 psa_status_t psa_status = psa_cipher_encrypt_setup(&operation, key, alg);
468
469 if (psa_status == PSA_SUCCESS) {
470
471 psa_status = multi_cipher_update(&operation,
472 input, input_length,
473 output, output_size, output_length);
474 }
475
476 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100477}
478
479psa_status_t psa_cipher_decrypt(psa_key_id_t key,
480 psa_algorithm_t alg,
481 const uint8_t *input,
482 size_t input_length,
483 uint8_t *output,
484 size_t output_size,
485 size_t *output_length)
486{
Julian Hall188953d2021-07-30 12:11:43 +0100487 psa_cipher_operation_t operation = psa_cipher_operation_init();
488 psa_status_t psa_status = psa_cipher_decrypt_setup(&operation, key, alg);
489
490 if (psa_status == PSA_SUCCESS) {
491
492 psa_status = multi_cipher_update(&operation,
493 input, input_length,
494 output, output_size, output_length);
495 }
496
497 return psa_status;
Julian Halld670b412021-07-19 15:16:27 +0100498}