blob: b0f8be3092b88ced518bd1b8685e276ff692a8b8 [file] [log] [blame]
Julian Hallc02fffb2020-11-23 18:22:06 +01001/*
julhal01c3f4e9a2020-12-15 13:39:01 +00002 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
Julian Hallc02fffb2020-11-23 18:22:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <stdint.h>
7#include <stdlib.h>
8#include <protocols/service/crypto/packed-c/opcodes.h>
9#include <service/crypto/provider/mbedcrypto/crypto_provider.h>
julhal012c18fbf2021-02-01 08:29:28 +000010#include <service/crypto/provider/mbedcrypto/trng_adapter/trng_adapter.h>
julhal011260f102021-02-15 17:34:08 +000011#include <service/secure_storage/frontend/psa/its/its_frontend.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010012#include <protocols/rpc/common/packed-c/status.h>
13#include <psa/crypto.h>
14
15/* Service request handlers */
16static rpc_status_t nop_handler(void *context, struct call_req* req);
17static rpc_status_t generate_key_handler(void *context, struct call_req* req);
18static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
19static rpc_status_t open_key_handler(void *context, struct call_req* req);
20static rpc_status_t close_key_handler(void *context, struct call_req* req);
21static rpc_status_t export_key_handler(void *context, struct call_req* req);
22static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
23static rpc_status_t import_key_handler(void *context, struct call_req* req);
24static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
25static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
26static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
27static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
28static rpc_status_t generate_random_handler(void *context, struct call_req* req);
29
30/* Handler mapping table for service */
31static const struct service_handler handler_table[] = {
32 {TS_CRYPTO_OPCODE_NOP, nop_handler},
33 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
34 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
35 {TS_CRYPTO_OPCODE_OPEN_KEY, open_key_handler},
36 {TS_CRYPTO_OPCODE_CLOSE_KEY, close_key_handler},
37 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
38 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
39 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
40 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
41 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
42 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
43 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
44 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler}
45};
46
julhal01c3f4e9a2020-12-15 13:39:01 +000047struct rpc_interface *mbed_crypto_provider_init(struct mbed_crypto_provider *context,
julhal011260f102021-02-15 17:34:08 +000048 struct rpc_caller *storage_caller,
julhal012c18fbf2021-02-01 08:29:28 +000049 int trng_instance)
Julian Hallc02fffb2020-11-23 18:22:06 +010050{
julhal01c3f4e9a2020-12-15 13:39:01 +000051 struct rpc_interface *rpc_interface = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010052
julhal012c18fbf2021-02-01 08:29:28 +000053 trng_adapter_init(trng_instance);
julhal01ffa98d82021-01-20 13:51:58 +000054
Julian Hallc02fffb2020-11-23 18:22:06 +010055 /*
56 * A storage provider is required for persistent key storage. As this
57 * is a mandatory feature of the crypto service, insist on a storage
58 * provider being available.
59 */
julhal011260f102021-02-15 17:34:08 +000060 if (context && storage_caller) {
Julian Hallc02fffb2020-11-23 18:22:06 +010061
julhal01c3f4e9a2020-12-15 13:39:01 +000062 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
63 context->serializers[encoding] = NULL;
64
Julian Hallc02fffb2020-11-23 18:22:06 +010065 service_provider_init(&context->base_provider, context,
66 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
67
julhal011260f102021-02-15 17:34:08 +000068 struct storage_backend *storage_backend =
69 secure_storage_client_init(&context->secure_storage_client, storage_caller);
70
71 if (storage_backend &&
72 (psa_its_frontend_init(storage_backend) == PSA_SUCCESS) &&
73 (psa_crypto_init() == PSA_SUCCESS)) {
74
julhal01c3f4e9a2020-12-15 13:39:01 +000075 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
julhal011260f102021-02-15 17:34:08 +000076 }
Julian Hallc02fffb2020-11-23 18:22:06 +010077 }
78
julhal01c3f4e9a2020-12-15 13:39:01 +000079 return rpc_interface;
Julian Hallc02fffb2020-11-23 18:22:06 +010080}
81
82void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
83{
84 (void)context;
julhal012c18fbf2021-02-01 08:29:28 +000085 trng_adapter_deinit();
Julian Hallc02fffb2020-11-23 18:22:06 +010086}
87
julhal01c3f4e9a2020-12-15 13:39:01 +000088void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
89 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010090{
julhal01c3f4e9a2020-12-15 13:39:01 +000091 if (encoding < TS_RPC_ENCODING_LIMIT)
92 context->serializers[encoding] = serializer;
93}
94
95static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
96 const struct call_req *req)
97{
98 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
99 const struct crypto_provider_serializer* serializer = NULL;
100 unsigned int encoding = call_req_get_encoding(req);
101
102 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
103
104 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +0100105}
106
107static rpc_status_t nop_handler(void *context, struct call_req* req)
108{
109 /* Responds to a request by returning success */
110 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
111 psa_status_t psa_status = PSA_SUCCESS;
112
113 (void)context;
114 call_req_set_opstatus(req, psa_status);
115
116 return rpc_status;
117}
118
119static rpc_status_t generate_key_handler(void *context, struct call_req* req)
120{
julhal01c3f4e9a2020-12-15 13:39:01 +0000121 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100122 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000123 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100124
125 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
126
julhal01c3f4e9a2020-12-15 13:39:01 +0000127 if (serializer)
128 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100129
130 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
131
132 psa_status_t psa_status;
133 psa_key_handle_t handle;
134
135 psa_status = psa_generate_key(&attributes, &handle);
136
137 if (psa_status == PSA_SUCCESS) {
138
139 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
140 rpc_status = serializer->serialize_generate_key_resp(resp_buf, handle);
141 }
142
143 call_req_set_opstatus(req, psa_status);
144 }
145
146 psa_reset_key_attributes(&attributes);
147
148 return rpc_status;
149}
150
151static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
152{
julhal01c3f4e9a2020-12-15 13:39:01 +0000153 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100154 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000155 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100156
157 psa_key_handle_t handle;
158
julhal01c3f4e9a2020-12-15 13:39:01 +0000159 if (serializer)
160 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100161
162 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
163
164 psa_status_t psa_status;
165
166 psa_status = psa_destroy_key(handle);
167 call_req_set_opstatus(req, psa_status);
168 }
169
170 return rpc_status;
171}
172
173static rpc_status_t open_key_handler(void *context, struct call_req* req)
174{
julhal01c3f4e9a2020-12-15 13:39:01 +0000175 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100176 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000177 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100178
179 psa_key_id_t id;
180
julhal01c3f4e9a2020-12-15 13:39:01 +0000181 if (serializer)
182 rpc_status = serializer->deserialize_open_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100183
184 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
185
186 psa_status_t psa_status;
187 psa_key_handle_t handle;
188
189 psa_status = psa_open_key(id, &handle);
190
191 if (psa_status == PSA_SUCCESS) {
192
193 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
194 rpc_status = serializer->serialize_open_key_resp(resp_buf, handle);
195 }
196
197 call_req_set_opstatus(req, psa_status);
198 }
199
200 return rpc_status;
201}
202
203static rpc_status_t close_key_handler(void *context, struct call_req* req)
204{
julhal01c3f4e9a2020-12-15 13:39:01 +0000205 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100206 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000207 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100208
209 psa_key_handle_t handle;
210
julhal01c3f4e9a2020-12-15 13:39:01 +0000211 if (serializer)
212 rpc_status = serializer->deserialize_close_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100213
214 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
215
216 psa_status_t psa_status;
217
218 psa_status = psa_close_key(handle);
219 call_req_set_opstatus(req, psa_status);
220 }
221
222 return rpc_status;
223}
224
225static rpc_status_t export_key_handler(void *context, struct call_req* req)
226{
julhal01c3f4e9a2020-12-15 13:39:01 +0000227 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100228 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000229 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100230
231 psa_key_handle_t handle;
232
julhal01c3f4e9a2020-12-15 13:39:01 +0000233 if (serializer)
234 rpc_status = serializer->deserialize_export_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100235
236 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
237
238 psa_status_t psa_status;
239 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
240
241 psa_status = psa_get_key_attributes(handle, &attributes);
242
243 if (psa_status == PSA_SUCCESS) {
244
245 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
246 psa_get_key_type(&attributes),
247 psa_get_key_bits(&attributes));
248
249 uint8_t *key_buffer = malloc(max_export_size);
250
251 if (key_buffer) {
252
253 size_t export_size;
254 psa_status = psa_export_key(handle, key_buffer, max_export_size, &export_size);
255
256 if (psa_status == PSA_SUCCESS) {
257
258 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
259 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
260 }
261
262 free(key_buffer);
263 }
264 else {
265 /* Failed to allocate key buffer */
266 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
267 }
268 }
269
270 call_req_set_opstatus(req, psa_status);
271 psa_reset_key_attributes(&attributes);
272 }
273
274 return rpc_status;
275}
276
277static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
278{
julhal01c3f4e9a2020-12-15 13:39:01 +0000279 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100280 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000281 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100282
283 psa_key_handle_t handle;
284
julhal01c3f4e9a2020-12-15 13:39:01 +0000285 if (serializer)
286 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100287
288 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
289
290 psa_status_t psa_status;
291 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
292
293 psa_status = psa_get_key_attributes(handle, &attributes);
294
295 if (psa_status == PSA_SUCCESS) {
296
297 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
298 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
299 psa_get_key_bits(&attributes));
300
301 uint8_t *key_buffer = malloc(max_export_size);
302
303 if (key_buffer) {
304
305 size_t export_size;
306 psa_status = psa_export_public_key(handle, key_buffer, max_export_size, &export_size);
307
308 if (psa_status == PSA_SUCCESS) {
309
310 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
311 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
312 }
313
314 free(key_buffer);
315 }
316 else {
317 /* Failed to allocate key buffer */
318 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
319 }
320 }
321
322 call_req_set_opstatus(req, psa_status);
323 psa_reset_key_attributes(&attributes);
324 }
325
326 return rpc_status;
327}
328
329static rpc_status_t import_key_handler(void *context, struct call_req* req)
330{
julhal01c3f4e9a2020-12-15 13:39:01 +0000331 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100332 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000333 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100334
julhal01c3f4e9a2020-12-15 13:39:01 +0000335 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100336
julhal01c3f4e9a2020-12-15 13:39:01 +0000337 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
338 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100339
julhal01c3f4e9a2020-12-15 13:39:01 +0000340 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100341
julhal01c3f4e9a2020-12-15 13:39:01 +0000342 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
343 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100344
julhal01c3f4e9a2020-12-15 13:39:01 +0000345 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100346
julhal01c3f4e9a2020-12-15 13:39:01 +0000347 psa_status_t psa_status;
348 psa_key_handle_t handle;
Julian Hallc02fffb2020-11-23 18:22:06 +0100349
julhal01c3f4e9a2020-12-15 13:39:01 +0000350 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100351
julhal01c3f4e9a2020-12-15 13:39:01 +0000352 if (psa_status == PSA_SUCCESS) {
353
354 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
355 rpc_status = serializer->serialize_import_key_resp(resp_buf, handle);
356 }
357
358 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +0100359 }
360
julhal01c3f4e9a2020-12-15 13:39:01 +0000361 psa_reset_key_attributes(&attributes);
362 free(key_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100363 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000364 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100365
julhal01c3f4e9a2020-12-15 13:39:01 +0000366 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
367 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100368 }
369
370 return rpc_status;
371}
372
373static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
374{
julhal01c3f4e9a2020-12-15 13:39:01 +0000375 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100376 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000377 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100378
379 psa_key_handle_t handle;
380 psa_algorithm_t alg;
381 size_t hash_len = PSA_HASH_MAX_SIZE;
382 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
383
julhal01c3f4e9a2020-12-15 13:39:01 +0000384 if (serializer)
385 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &handle, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100386
387 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
388
389 psa_status_t psa_status;
390 size_t sig_len;
391 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
392
393 psa_status = psa_sign_hash(handle, alg,
394 hash_buffer, hash_len,
395 sig_buffer, sizeof(sig_buffer), &sig_len);
396
397 if (psa_status == PSA_SUCCESS) {
398
399 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
400 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
401 }
402
403 call_req_set_opstatus(req, psa_status);
404 }
405
406 return rpc_status;
407}
408
409static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
410{
julhal01c3f4e9a2020-12-15 13:39:01 +0000411 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100412 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000413 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100414
415 psa_key_handle_t handle;
416 psa_algorithm_t alg;
417 size_t hash_len = PSA_HASH_MAX_SIZE;
418 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
419 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
420 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
421
julhal01c3f4e9a2020-12-15 13:39:01 +0000422 if (serializer)
423 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &handle, &alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100424 hash_buffer, &hash_len,
425 sig_buffer, &sig_len);
426
427 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
428
429 psa_status_t psa_status;
430
431 psa_status = psa_verify_hash(handle, alg,
432 hash_buffer, hash_len,
433 sig_buffer, sig_len);
434
435 call_req_set_opstatus(req, psa_status);
436 }
437
438 return rpc_status;
439}
440
441static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
442{
julhal01c3f4e9a2020-12-15 13:39:01 +0000443 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100444 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000445 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100446
julhal01c3f4e9a2020-12-15 13:39:01 +0000447 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100448
julhal01c3f4e9a2020-12-15 13:39:01 +0000449 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100450
julhal01c3f4e9a2020-12-15 13:39:01 +0000451 psa_key_handle_t handle;
452 psa_algorithm_t alg;
453 size_t ciphertext_len = max_param_size;
454 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
455 size_t salt_len = max_param_size;
456 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100457
julhal01c3f4e9a2020-12-15 13:39:01 +0000458 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100459
julhal01c3f4e9a2020-12-15 13:39:01 +0000460 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
461 &handle, &alg,
462 ciphertext_buffer, &ciphertext_len,
463 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100464
julhal01c3f4e9a2020-12-15 13:39:01 +0000465 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100466
julhal01c3f4e9a2020-12-15 13:39:01 +0000467 psa_status_t psa_status;
468 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100469
julhal01c3f4e9a2020-12-15 13:39:01 +0000470 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100471
julhal01c3f4e9a2020-12-15 13:39:01 +0000472 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100473
julhal01c3f4e9a2020-12-15 13:39:01 +0000474 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
475 psa_get_key_type(&attributes),
476 psa_get_key_bits(&attributes),
477 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100478
julhal01c3f4e9a2020-12-15 13:39:01 +0000479 size_t plaintext_len;
480 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100481
julhal01c3f4e9a2020-12-15 13:39:01 +0000482 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100483
julhal01c3f4e9a2020-12-15 13:39:01 +0000484 psa_status = psa_asymmetric_decrypt(handle, alg,
485 ciphertext_buffer, ciphertext_len,
486 salt_buffer, salt_len,
487 plaintext_buffer, max_decrypt_size, &plaintext_len);
488
489 if (psa_status == PSA_SUCCESS) {
490
491 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
492 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
493 plaintext_buffer, plaintext_len);
494 }
495
496 free(plaintext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100497 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000498 else {
499 /* Failed to allocate ouptput buffer */
500 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
501 }
502 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100503
julhal01c3f4e9a2020-12-15 13:39:01 +0000504 call_req_set_opstatus(req, psa_status);
505 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100506 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100507 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000508 else {
509 /* Failed to allocate buffers */
510 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
511 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100512
julhal01c3f4e9a2020-12-15 13:39:01 +0000513 free(ciphertext_buffer);
514 free(salt_buffer);
515 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100516
517 return rpc_status;
518}
519
520static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
521{
julhal01c3f4e9a2020-12-15 13:39:01 +0000522 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100523 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000524 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100525
julhal01c3f4e9a2020-12-15 13:39:01 +0000526 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100527
julhal01c3f4e9a2020-12-15 13:39:01 +0000528 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100529
julhal01c3f4e9a2020-12-15 13:39:01 +0000530 psa_key_handle_t handle;
531 psa_algorithm_t alg;
532 size_t plaintext_len = max_param_size;
533 uint8_t *plaintext_buffer = malloc(plaintext_len);
534 size_t salt_len = max_param_size;
535 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100536
julhal01c3f4e9a2020-12-15 13:39:01 +0000537 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100538
julhal01c3f4e9a2020-12-15 13:39:01 +0000539 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
540 &handle, &alg,
541 plaintext_buffer, &plaintext_len,
542 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100543
julhal01c3f4e9a2020-12-15 13:39:01 +0000544 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100545
julhal01c3f4e9a2020-12-15 13:39:01 +0000546 psa_status_t psa_status;
547 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100548
julhal01c3f4e9a2020-12-15 13:39:01 +0000549 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100550
julhal01c3f4e9a2020-12-15 13:39:01 +0000551 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100552
julhal01c3f4e9a2020-12-15 13:39:01 +0000553 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
554 psa_get_key_type(&attributes),
555 psa_get_key_bits(&attributes),
556 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100557
julhal01c3f4e9a2020-12-15 13:39:01 +0000558 size_t ciphertext_len;
559 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100560
julhal01c3f4e9a2020-12-15 13:39:01 +0000561 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100562
julhal01c3f4e9a2020-12-15 13:39:01 +0000563 psa_status = psa_asymmetric_encrypt(handle, alg,
564 plaintext_buffer, plaintext_len,
565 salt_buffer, salt_len,
566 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
567
568 if (psa_status == PSA_SUCCESS) {
569
570 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
571 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
572 ciphertext_buffer, ciphertext_len);
573 }
574
575 free(ciphertext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100576 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000577 else {
578 /* Failed to allocate ouptput buffer */
579 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
580 }
581 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100582
julhal01c3f4e9a2020-12-15 13:39:01 +0000583 call_req_set_opstatus(req, psa_status);
584 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100585 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100586 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000587 else {
588 /* Failed to allocate buffers */
589 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
590 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100591
julhal01c3f4e9a2020-12-15 13:39:01 +0000592 free(plaintext_buffer);
593 free(salt_buffer);
594 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100595
596 return rpc_status;
597}
598
599static rpc_status_t generate_random_handler(void *context, struct call_req* req)
600{
julhal01c3f4e9a2020-12-15 13:39:01 +0000601 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100602 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000603 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100604
605 size_t output_size;
606
julhal01c3f4e9a2020-12-15 13:39:01 +0000607 if (serializer)
608 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100609
610 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
611
612 psa_status_t psa_status;
613 uint8_t *output_buffer = malloc(output_size);
614
615 if (output_buffer) {
616
617 psa_status = psa_generate_random(output_buffer, output_size);
618
619 if (psa_status == PSA_SUCCESS) {
620
621 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
622 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
623 output_buffer, output_size);
624 }
625
626 call_req_set_opstatus(req, psa_status);
627 free(output_buffer);
628 }
629 else {
630 /* Failed to allocate output buffer */
631 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
632 }
633 }
634
635 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000636}