blob: a374954ec86514e88846fc5406f308e94f94ec6a [file] [log] [blame]
Julian Hallc02fffb2020-11-23 18:22:06 +01001/*
2 * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <cstring>
8#include <cstdlib>
9#include "crypto_client.h"
10#include <protocols/rpc/common/packed-c/status.h>
11#include <service/common/serializer/protobuf/pb_helper.h>
12#include <rpc_caller.h>
13#include <service/crypto/protobuf/opcodes.pb.h>
14#include <service/crypto/protobuf/generate_key.pb.h>
15#include <service/crypto/protobuf/destroy_key.pb.h>
16#include <service/crypto/protobuf/import_key.pb.h>
17#include <service/crypto/protobuf/open_key.pb.h>
18#include <service/crypto/protobuf/close_key.pb.h>
19#include <service/crypto/protobuf/export_key.pb.h>
20#include <service/crypto/protobuf/export_public_key.pb.h>
21#include <service/crypto/protobuf/sign_hash.pb.h>
22#include <service/crypto/protobuf/verify_hash.pb.h>
23#include <service/crypto/protobuf/asymmetric_encrypt.pb.h>
24#include <service/crypto/protobuf/asymmetric_decrypt.pb.h>
25#include <service/crypto/protobuf/generate_random.pb.h>
26#include <pb_encode.h>
27#include <pb_decode.h>
28
29crypto_client::crypto_client() :
30 m_caller(NULL),
31 m_err_rpc_status(TS_RPC_CALL_ACCEPTED)
32{
33
34}
35
36crypto_client::crypto_client(struct rpc_caller *caller) :
37 m_caller(caller),
38 m_err_rpc_status(TS_RPC_CALL_ACCEPTED)
39{
40
41}
42
43crypto_client::~crypto_client()
44{
45
46}
47
48int crypto_client::err_rpc_status() const
49{
50 return m_err_rpc_status;
51}
52
53psa_status_t crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle)
54{
55 size_t req_len;
56 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
57 ts_crypto_GenerateKeyIn req_msg = ts_crypto_GenerateKeyIn_init_default;
58
59 translate_key_attributes(req_msg.attributes, *attributes);
60 req_msg.has_attributes = true;
61
62 if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) {
63
64 rpc_call_handle call_handle;
65 uint8_t *req_buf;
66
67 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
68
69 if (call_handle) {
70
71 uint8_t *resp_buf;
72 size_t resp_len;
73 int opstatus;
74
75 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
76 pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &req_msg);
77
78 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
79 ts_crypto_Opcode_GENERATE_KEY, &opstatus, &resp_buf, &resp_len);
80
81 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
82
83 psa_status = opstatus;
84
85 if (psa_status == PSA_SUCCESS) {
86
87 ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default;
88 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
89
90 if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) {
91
92 *handle = resp_msg.handle;
93 }
94 else {
95 /* Failed to decode response message */
96 psa_status = PSA_ERROR_GENERIC_ERROR;
97 }
98 }
99 }
100
101 rpc_caller_end(m_caller, call_handle);
102 }
103 }
104
105 return psa_status;
106}
107
108psa_status_t crypto_client::destroy_key(psa_key_handle_t handle)
109{
110 size_t req_len;
111 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
112 ts_crypto_DestroyKeyIn req_msg = ts_crypto_DestroyKeyIn_init_default;
113
114 req_msg.handle = handle;
115
116 if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) {
117
118 rpc_call_handle call_handle;
119 uint8_t *req_buf;
120
121 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
122
123 if (call_handle) {
124
125 uint8_t *resp_buf;
126 size_t resp_len;
127 int opstatus;
128
129 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
130 pb_encode(&ostream, ts_crypto_DestroyKeyIn_fields, &req_msg);
131
132 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
133 ts_crypto_Opcode_DESTROY_KEY, &opstatus, &resp_buf, &resp_len);
134
135 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
136
137 rpc_caller_end(m_caller, call_handle);
138 }
139 }
140
141 return psa_status;
142}
143
144psa_status_t crypto_client::open_key(psa_key_id_t id, psa_key_handle_t *handle)
145{
146 size_t req_len;
147 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
148 ts_crypto_OpenKeyIn req_msg = ts_crypto_OpenKeyIn_init_default;
149 req_msg.id = id;
150
151 if (pb_get_encoded_size(&req_len, ts_crypto_OpenKeyIn_fields, &req_msg)) {
152
153 rpc_call_handle call_handle;
154 uint8_t *req_buf;
155
156 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
157
158 if (call_handle) {
159
160 uint8_t *resp_buf;
161 size_t resp_len;
162 int opstatus;
163
164 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
165 pb_encode(&ostream, ts_crypto_OpenKeyIn_fields, &req_msg);
166
167 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
168 ts_crypto_Opcode_OPEN_KEY, &opstatus, &resp_buf, &resp_len);
169
170 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
171
172 psa_status = opstatus;
173
174 if (psa_status == PSA_SUCCESS) {
175
176 ts_crypto_OpenKeyOut resp_msg = ts_crypto_OpenKeyOut_init_default;
177 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
178
179 if (pb_decode(&istream, ts_crypto_OpenKeyOut_fields, &resp_msg)) {
180
181 *handle = resp_msg.handle;
182 }
183 else {
184 /* Failed to decode response message */
185 psa_status = PSA_ERROR_GENERIC_ERROR;
186 }
187 }
188 }
189
190 rpc_caller_end(m_caller, call_handle);
191 }
192 }
193
194 return psa_status;
195}
196
197psa_status_t crypto_client::close_key(psa_key_handle_t handle)
198{
199 size_t req_len;
200 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
201 ts_crypto_CloseKeyIn req_msg = ts_crypto_CloseKeyIn_init_default;
202
203 req_msg.handle = handle;
204
205 if (pb_get_encoded_size(&req_len, ts_crypto_CloseKeyIn_fields, &req_msg)) {
206
207 rpc_call_handle call_handle;
208 uint8_t *req_buf;
209
210 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
211
212 if (call_handle) {
213
214 uint8_t *resp_buf;
215 size_t resp_len;
216 int opstatus;
217
218 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
219 pb_encode(&ostream, ts_crypto_CloseKeyIn_fields, &req_msg);
220
221 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
222 ts_crypto_Opcode_CLOSE_KEY, &opstatus, &resp_buf, &resp_len);
223
224 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
225
226 rpc_caller_end(m_caller, call_handle);
227 }
228 }
229
230 return psa_status;
231}
232
233psa_status_t crypto_client::import_key(const psa_key_attributes_t *attributes,
234 const uint8_t *data, size_t data_length, psa_key_handle_t *handle)
235{
236 size_t req_len;
237 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
238 ts_crypto_ImportKeyIn req_msg = ts_crypto_ImportKeyIn_init_default;
239 pb_bytes_array_t *key_byte_array = pb_malloc_byte_array_containing_bytes(data, data_length);
240
241 translate_key_attributes(req_msg.attributes, *attributes);
242 req_msg.has_attributes = true;
243 req_msg.data = pb_out_byte_array(key_byte_array);
244
245 if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) {
246
247 rpc_call_handle call_handle;
248 uint8_t *req_buf;
249
250 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
251
252 if (call_handle) {
253
254 uint8_t *resp_buf;
255 size_t resp_len;
256 int opstatus;
257
258 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
259 pb_encode(&ostream, ts_crypto_ImportKeyIn_fields, &req_msg);
260
261 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
262 ts_crypto_Opcode_IMPORT_KEY, &opstatus, &resp_buf, &resp_len);
263
264 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
265
266 psa_status = opstatus;
267
268 if (psa_status == PSA_SUCCESS) {
269
270 ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default;
271 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
272
273 if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) {
274
275 *handle = resp_msg.handle;
276 }
277 else {
278 /* Failed to decode response message */
279 psa_status = PSA_ERROR_GENERIC_ERROR;
280 }
281 }
282 }
283
284 rpc_caller_end(m_caller, call_handle);
285 }
286 }
287
288 ::free(key_byte_array);
289
290 return psa_status;
291}
292
293psa_status_t crypto_client::export_key(psa_key_handle_t handle,
294 uint8_t *data, size_t data_size,
295 size_t *data_length)
296{
297 size_t req_len;
298 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
299 ts_crypto_ExportKeyIn req_msg = ts_crypto_ExportKeyIn_init_default;
300 req_msg.handle = handle;
301
302 *data_length = 0; /* For failure case */
303
304 if (pb_get_encoded_size(&req_len, ts_crypto_ExportKeyIn_fields, &req_msg)) {
305
306 rpc_call_handle call_handle;
307 uint8_t *req_buf;
308
309 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
310
311 if (call_handle) {
312
313 uint8_t *resp_buf;
314 size_t resp_len;
315 int opstatus;
316
317 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
318 pb_encode(&ostream, ts_crypto_ExportKeyIn_fields, &req_msg);
319
320 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
321 ts_crypto_Opcode_EXPORT_KEY, &opstatus, &resp_buf, &resp_len);
322
323 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
324
325 psa_status = opstatus;
326
327 if (psa_status == PSA_SUCCESS) {
328
329 ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default;
330 pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
331
332 if (exported_key) {
333
334 resp_msg.data = pb_in_byte_array(exported_key);
335 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
336
337 if (pb_decode(&istream, ts_crypto_ExportKeyOut_fields, &resp_msg)) {
338
339 if (exported_key->size <= data_size) {
340
341 memcpy(data, exported_key->bytes, exported_key->size);
342 *data_length = exported_key->size;
343 }
344 else {
345 /* Provided buffer is too small */
346 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
347 }
348 }
349 else {
350 /* Failed to decode response message */
351 psa_status = PSA_ERROR_GENERIC_ERROR;
352 }
353
354 ::free(exported_key);
355 }
356 else {
357 /* Failed to allocate buffer for exported key */
358 psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
359 }
360 }
361 }
362
363 rpc_caller_end(m_caller, call_handle);
364 }
365 }
366
367 return psa_status;
368}
369
370psa_status_t crypto_client::export_public_key(psa_key_handle_t handle,
371 uint8_t *data, size_t data_size, size_t *data_length)
372{
373 size_t req_len;
374 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
375 ts_crypto_ExportPublicKeyIn req_msg = ts_crypto_ExportPublicKeyIn_init_default;
376 req_msg.handle = handle;
377
378 *data_length = 0; /* For failure case */
379
380 if (pb_get_encoded_size(&req_len, ts_crypto_ExportPublicKeyIn_fields, &req_msg)) {
381
382 rpc_call_handle call_handle;
383 uint8_t *req_buf;
384
385 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
386
387 if (call_handle) {
388
389 uint8_t *resp_buf;
390 size_t resp_len;
391 int opstatus;
392
393 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
394 pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &req_msg);
395
396 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
397 ts_crypto_Opcode_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len);
398
399 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
400
401 psa_status = opstatus;
402
403 if (psa_status == PSA_SUCCESS) {
404
405 ts_crypto_ExportPublicKeyOut resp_msg = ts_crypto_ExportPublicKeyOut_init_default;
406 pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len);
407
408 if (exported_key) {
409
410 resp_msg.data = pb_in_byte_array(exported_key);
411 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
412
413 if (pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) {
414
415 if (exported_key->size <= data_size) {
416
417 memcpy(data, exported_key->bytes, exported_key->size);
418 *data_length = exported_key->size;
419 }
420 else {
421 /* Provided buffer is too small */
422 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
423 }
424 }
425 else {
426 /* Failed to decode response message */
427 psa_status = PSA_ERROR_GENERIC_ERROR;
428 }
429
430 ::free(exported_key);
431 }
432 else {
433 /* Failed to alloocate buffer for exported key */
434 psa_status = PSA_ERROR_INSUFFICIENT_MEMORY;
435 }
436 }
437 }
438
439 rpc_caller_end(m_caller, call_handle);
440 }
441 }
442
443 return psa_status;
444}
445
446psa_status_t crypto_client::sign_hash(psa_key_handle_t handle, psa_algorithm_t alg,
447 const uint8_t *hash, size_t hash_length,
448 uint8_t *signature, size_t signature_size, size_t *signature_length)
449{
450 size_t req_len;
451 pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length);
452 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
453 ts_crypto_SignHashIn req_msg = ts_crypto_SignHashIn_init_default;
454
455 *signature_length = 0; /* For failure case */
456
457 req_msg.handle = handle;
458 req_msg.alg = alg;
459 req_msg.hash = pb_out_byte_array(hash_byte_array);
460
461 if (pb_get_encoded_size(&req_len, ts_crypto_SignHashIn_fields, &req_msg)) {
462
463 rpc_call_handle call_handle;
464 uint8_t *req_buf;
465
466 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
467
468 if (call_handle) {
469
470 uint8_t *resp_buf;
471 size_t resp_len;
472 int opstatus;
473
474 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
475 pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg);
476
477 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
478 ts_crypto_Opcode_SIGN_HASH, &opstatus, &resp_buf, &resp_len);
479
480 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
481
482 psa_status = opstatus;
483
484 if (psa_status == PSA_SUCCESS) {
485
486 pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array(PSA_SIGNATURE_MAX_SIZE);
487 ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default;
488 resp_msg.signature = pb_in_byte_array(sig_byte_array);
489
490 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
491
492 if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) {
493
494 if (sig_byte_array->size <= signature_size) {
495
496 memcpy(signature, sig_byte_array->bytes, sig_byte_array->size);
497 *signature_length = sig_byte_array->size;
498 }
499 else {
500 /* Provided buffer is too small */
501 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
502 }
503 }
504 else {
505 /* Failed to decode response message */
506 psa_status = PSA_ERROR_GENERIC_ERROR;
507 }
508
509 ::free(sig_byte_array);
510 }
511 }
512
513 rpc_caller_end(m_caller, call_handle);
514 }
515 }
516
517 ::free(hash_byte_array);
518
519 return psa_status;
520}
521
522
523psa_status_t crypto_client::verify_hash(psa_key_handle_t handle, psa_algorithm_t alg,
524 const uint8_t *hash, size_t hash_length,
525 const uint8_t *signature, size_t signature_length)
526{
527 size_t req_len;
528 pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length);
529 pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array_containing_bytes(signature, signature_length);
530 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
531 ts_crypto_VerifyHashIn req_msg = ts_crypto_VerifyHashIn_init_default;
532
533 req_msg.handle = handle;
534 req_msg.alg = alg;
535 req_msg.hash = pb_out_byte_array(hash_byte_array);
536 req_msg.signature = pb_out_byte_array(sig_byte_array);
537
538 if (pb_get_encoded_size(&req_len, ts_crypto_VerifyHashIn_fields, &req_msg)) {
539
540 rpc_call_handle call_handle;
541 uint8_t *req_buf;
542
543 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
544
545 if (call_handle) {
546
547 uint8_t *resp_buf;
548 size_t resp_len;
549 int opstatus;
550
551 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
552 pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg);
553
554 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
555 ts_crypto_Opcode_VERIFY_HASH, &opstatus, &resp_buf, &resp_len);
556
557 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus;
558
559 rpc_caller_end(m_caller, call_handle);
560 }
561 }
562
563 ::free(hash_byte_array);
564 ::free(sig_byte_array);
565
566 return psa_status;
567}
568
569psa_status_t crypto_client::asymmetric_encrypt(psa_key_handle_t handle, psa_algorithm_t alg,
570 const uint8_t *input, size_t input_length,
571 const uint8_t *salt, size_t salt_length,
572 uint8_t *output, size_t output_size, size_t *output_length)
573{
574 size_t req_len;
575 pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length);
576 pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length);
577 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
578 ts_crypto_AsymmetricEncryptIn req_msg = ts_crypto_AsymmetricEncryptIn_init_default;
579
580 *output_length = 0; /* For failure case */
581
582 req_msg.handle = handle;
583 req_msg.alg = alg;
584 req_msg.plaintext = pb_out_byte_array(plaintext_byte_array);
585 req_msg.salt = pb_out_byte_array(salt_byte_array);
586
587 if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricEncryptIn_fields, &req_msg)) {
588
589 rpc_call_handle call_handle;
590 uint8_t *req_buf;
591
592 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
593
594 if (call_handle) {
595
596 uint8_t *resp_buf;
597 size_t resp_len;
598 int opstatus = PSA_ERROR_GENERIC_ERROR;
599
600 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
601 pb_encode(&ostream, ts_crypto_AsymmetricEncryptIn_fields, &req_msg);
602
603 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
604 ts_crypto_Opcode_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len);
605
606 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
607
608 psa_status = opstatus;
609
610 if (psa_status == PSA_SUCCESS) {
611
612 pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array(output_size);
613 ts_crypto_AsymmetricEncryptOut resp_msg = ts_crypto_AsymmetricEncryptOut_init_default;
614 resp_msg.ciphertext = pb_in_byte_array(ciphertext_byte_array);
615
616 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
617
618 if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) {
619
620 if (ciphertext_byte_array->size <= output_size) {
621
622 memcpy(output, ciphertext_byte_array->bytes, ciphertext_byte_array->size);
623 *output_length = ciphertext_byte_array->size;
624 }
625 else {
626 /* Provided buffer is too small */
627 psa_status = PSA_ERROR_BUFFER_TOO_SMALL;
628 }
629 }
630 else {
631 /* Failed to decode response message */
632 psa_status = PSA_ERROR_GENERIC_ERROR;
633 }
634
635 ::free(ciphertext_byte_array);
636 }
637 }
638
639 rpc_caller_end(m_caller, call_handle);
640 }
641 }
642
643 ::free(plaintext_byte_array);
644 ::free(salt_byte_array);
645
646 return psa_status;
647}
648
649psa_status_t crypto_client::asymmetric_decrypt(psa_key_handle_t handle, psa_algorithm_t alg,
650 const uint8_t *input, size_t input_length,
651 const uint8_t *salt, size_t salt_length,
652 uint8_t *output, size_t output_size, size_t *output_length)
653{
654 size_t req_len;
655 pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length);
656 pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length);
657 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
658 ts_crypto_AsymmetricDecryptIn req_msg = ts_crypto_AsymmetricDecryptIn_init_default;
659
660 *output_length = 0; /* For failure case */
661
662 req_msg.handle = handle;
663 req_msg.alg = alg;
664 req_msg.ciphertext = pb_out_byte_array(ciphertext_byte_array);
665 req_msg.salt = pb_out_byte_array(salt_byte_array);
666
667 if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricDecryptIn_fields, &req_msg)) {
668
669 rpc_call_handle call_handle;
670 uint8_t *req_buf;
671
672 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
673
674 if (call_handle) {
675
676 uint8_t *resp_buf;
677 size_t resp_len;
678 int opstatus;
679
680 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
681 pb_encode(&ostream, ts_crypto_AsymmetricDecryptIn_fields, &req_msg);
682
683 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
684 ts_crypto_Opcode_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len);
685
686 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
687
688 psa_status = opstatus;
689
690 if (psa_status == PSA_SUCCESS) {
691
692 pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array(output_size);
693 ts_crypto_AsymmetricDecryptOut resp_msg = ts_crypto_AsymmetricDecryptOut_init_default;
694 resp_msg.plaintext = pb_in_byte_array(plaintext_byte_array);
695
696 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
697
698 if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) {
699
700 if (plaintext_byte_array->size <= output_size) {
701
702 memcpy(output, plaintext_byte_array->bytes, plaintext_byte_array->size);
703 *output_length = plaintext_byte_array->size;
704 }
705 else {
706 /* Provided buffer is too small */
707 m_err_rpc_status = PSA_ERROR_BUFFER_TOO_SMALL;
708 }
709 }
710 else {
711 /* Failed to decode response message */
712 m_err_rpc_status = PSA_ERROR_GENERIC_ERROR;
713 }
714
715 ::free(plaintext_byte_array);
716 }
717 }
718
719 rpc_caller_end(m_caller, call_handle);
720 }
721 }
722
723 ::free(ciphertext_byte_array);
724 ::free(salt_byte_array);
725
726 return psa_status;
727}
728
729psa_status_t crypto_client::generate_random(uint8_t *output, size_t output_size)
730{
731 size_t req_len;
732 psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
733 ts_crypto_GenerateRandomIn req_msg = ts_crypto_GenerateRandomIn_init_default;
734
735 req_msg.size = output_size;
736
737 if (pb_get_encoded_size(&req_len, ts_crypto_GenerateRandomIn_fields, &req_msg)) {
738
739 rpc_call_handle call_handle;
740 uint8_t *req_buf;
741
742 call_handle = rpc_caller_begin(m_caller, &req_buf, req_len);
743
744 if (call_handle) {
745
746 uint8_t *resp_buf;
747 size_t resp_len;
748 int opstatus;
749
750 pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len);
751 pb_encode(&ostream, ts_crypto_GenerateRandomIn_fields, &req_msg);
752
753 m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle,
754 ts_crypto_Opcode_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len);
755
756 if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) {
757
758 psa_status = opstatus;
759
760 if (psa_status == PSA_SUCCESS) {
761
762 pb_bytes_array_t *output_byte_array = pb_malloc_byte_array(output_size);
763 ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default;
764 resp_msg.random_bytes = pb_in_byte_array(output_byte_array);
765
766 pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len);
767
768 if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) {
769
770 if (output_byte_array->size == output_size) {
771
772 memcpy(output, output_byte_array->bytes, output_byte_array->size);
773 }
774 else {
775 /* Mismatch between requested and generated length */
776 psa_status = PSA_ERROR_GENERIC_ERROR;
777 }
778 }
779 else {
780 /* Failed to decode response message */
781 psa_status = PSA_ERROR_GENERIC_ERROR;
782 }
783
784 ::free(output_byte_array);
785 }
786 }
787
788 rpc_caller_end(m_caller, call_handle);
789 }
790 }
791
792 return psa_status;
793}
794
795void crypto_client::translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes,
796 const psa_key_attributes_t &psa_attributes)
797{
798 proto_attributes.type = psa_get_key_type(&psa_attributes);
799 proto_attributes.key_bits = psa_get_key_bits(&psa_attributes);
800 proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes);
801 proto_attributes.id = psa_get_key_id(&psa_attributes);
802
803 proto_attributes.has_policy = true;
804 proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes);
805 proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes);
806 }