blob: bbbf16961dc4db9867848578f597fdcd45e58e7a [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>
Julian Hallc02fffb2020-11-23 18:22:06 +010010#include <service/secure_storage/client/psa/its/its_client.h>
11#include <protocols/rpc/common/packed-c/status.h>
12#include <psa/crypto.h>
13
14/* Service request handlers */
15static rpc_status_t nop_handler(void *context, struct call_req* req);
16static rpc_status_t generate_key_handler(void *context, struct call_req* req);
17static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
18static rpc_status_t open_key_handler(void *context, struct call_req* req);
19static rpc_status_t close_key_handler(void *context, struct call_req* req);
20static rpc_status_t export_key_handler(void *context, struct call_req* req);
21static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
22static rpc_status_t import_key_handler(void *context, struct call_req* req);
23static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
24static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
25static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
26static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
27static rpc_status_t generate_random_handler(void *context, struct call_req* req);
28
29/* Handler mapping table for service */
30static const struct service_handler handler_table[] = {
31 {TS_CRYPTO_OPCODE_NOP, nop_handler},
32 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
33 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
34 {TS_CRYPTO_OPCODE_OPEN_KEY, open_key_handler},
35 {TS_CRYPTO_OPCODE_CLOSE_KEY, close_key_handler},
36 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
37 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
38 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
39 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
40 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
41 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
42 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
43 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler}
44};
45
julhal01c3f4e9a2020-12-15 13:39:01 +000046struct rpc_interface *mbed_crypto_provider_init(struct mbed_crypto_provider *context,
Julian Hallc02fffb2020-11-23 18:22:06 +010047 struct rpc_caller *storage_provider)
48{
julhal01c3f4e9a2020-12-15 13:39:01 +000049 struct rpc_interface *rpc_interface = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010050
51 /*
52 * A storage provider is required for persistent key storage. As this
53 * is a mandatory feature of the crypto service, insist on a storage
54 * provider being available.
55 */
56 if (context && storage_provider) {
57
julhal01c3f4e9a2020-12-15 13:39:01 +000058 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
59 context->serializers[encoding] = NULL;
60
Julian Hallc02fffb2020-11-23 18:22:06 +010061 service_provider_init(&context->base_provider, context,
62 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
63
Julian Hallc02fffb2020-11-23 18:22:06 +010064 if ((psa_its_client_init(storage_provider) == PSA_SUCCESS) &&
65 (psa_crypto_init() == PSA_SUCCESS))
julhal01c3f4e9a2020-12-15 13:39:01 +000066 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010067 }
68
julhal01c3f4e9a2020-12-15 13:39:01 +000069 return rpc_interface;
Julian Hallc02fffb2020-11-23 18:22:06 +010070}
71
72void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
73{
74 (void)context;
75}
76
julhal01c3f4e9a2020-12-15 13:39:01 +000077void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
78 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010079{
julhal01c3f4e9a2020-12-15 13:39:01 +000080 if (encoding < TS_RPC_ENCODING_LIMIT)
81 context->serializers[encoding] = serializer;
82}
83
84static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
85 const struct call_req *req)
86{
87 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
88 const struct crypto_provider_serializer* serializer = NULL;
89 unsigned int encoding = call_req_get_encoding(req);
90
91 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
92
93 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010094}
95
96static rpc_status_t nop_handler(void *context, struct call_req* req)
97{
98 /* Responds to a request by returning success */
99 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
100 psa_status_t psa_status = PSA_SUCCESS;
101
102 (void)context;
103 call_req_set_opstatus(req, psa_status);
104
105 return rpc_status;
106}
107
108static rpc_status_t generate_key_handler(void *context, struct call_req* req)
109{
julhal01c3f4e9a2020-12-15 13:39:01 +0000110 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100111 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000112 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100113
114 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
115
julhal01c3f4e9a2020-12-15 13:39:01 +0000116 if (serializer)
117 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100118
119 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
120
121 psa_status_t psa_status;
122 psa_key_handle_t handle;
123
124 psa_status = psa_generate_key(&attributes, &handle);
125
126 if (psa_status == PSA_SUCCESS) {
127
128 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
129 rpc_status = serializer->serialize_generate_key_resp(resp_buf, handle);
130 }
131
132 call_req_set_opstatus(req, psa_status);
133 }
134
135 psa_reset_key_attributes(&attributes);
136
137 return rpc_status;
138}
139
140static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
141{
julhal01c3f4e9a2020-12-15 13:39:01 +0000142 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100143 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000144 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100145
146 psa_key_handle_t handle;
147
julhal01c3f4e9a2020-12-15 13:39:01 +0000148 if (serializer)
149 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100150
151 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
152
153 psa_status_t psa_status;
154
155 psa_status = psa_destroy_key(handle);
156 call_req_set_opstatus(req, psa_status);
157 }
158
159 return rpc_status;
160}
161
162static rpc_status_t open_key_handler(void *context, struct call_req* req)
163{
julhal01c3f4e9a2020-12-15 13:39:01 +0000164 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100165 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000166 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
168 psa_key_id_t id;
169
julhal01c3f4e9a2020-12-15 13:39:01 +0000170 if (serializer)
171 rpc_status = serializer->deserialize_open_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100172
173 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
174
175 psa_status_t psa_status;
176 psa_key_handle_t handle;
177
178 psa_status = psa_open_key(id, &handle);
179
180 if (psa_status == PSA_SUCCESS) {
181
182 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
183 rpc_status = serializer->serialize_open_key_resp(resp_buf, handle);
184 }
185
186 call_req_set_opstatus(req, psa_status);
187 }
188
189 return rpc_status;
190}
191
192static rpc_status_t close_key_handler(void *context, struct call_req* req)
193{
julhal01c3f4e9a2020-12-15 13:39:01 +0000194 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100195 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000196 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100197
198 psa_key_handle_t handle;
199
julhal01c3f4e9a2020-12-15 13:39:01 +0000200 if (serializer)
201 rpc_status = serializer->deserialize_close_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100202
203 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
204
205 psa_status_t psa_status;
206
207 psa_status = psa_close_key(handle);
208 call_req_set_opstatus(req, psa_status);
209 }
210
211 return rpc_status;
212}
213
214static rpc_status_t export_key_handler(void *context, struct call_req* req)
215{
julhal01c3f4e9a2020-12-15 13:39:01 +0000216 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100217 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000218 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100219
220 psa_key_handle_t handle;
221
julhal01c3f4e9a2020-12-15 13:39:01 +0000222 if (serializer)
223 rpc_status = serializer->deserialize_export_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100224
225 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
226
227 psa_status_t psa_status;
228 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
229
230 psa_status = psa_get_key_attributes(handle, &attributes);
231
232 if (psa_status == PSA_SUCCESS) {
233
234 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
235 psa_get_key_type(&attributes),
236 psa_get_key_bits(&attributes));
237
238 uint8_t *key_buffer = malloc(max_export_size);
239
240 if (key_buffer) {
241
242 size_t export_size;
243 psa_status = psa_export_key(handle, key_buffer, max_export_size, &export_size);
244
245 if (psa_status == PSA_SUCCESS) {
246
247 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
248 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
249 }
250
251 free(key_buffer);
252 }
253 else {
254 /* Failed to allocate key buffer */
255 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
256 }
257 }
258
259 call_req_set_opstatus(req, psa_status);
260 psa_reset_key_attributes(&attributes);
261 }
262
263 return rpc_status;
264}
265
266static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
267{
julhal01c3f4e9a2020-12-15 13:39:01 +0000268 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100269 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000270 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100271
272 psa_key_handle_t handle;
273
julhal01c3f4e9a2020-12-15 13:39:01 +0000274 if (serializer)
275 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100276
277 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
278
279 psa_status_t psa_status;
280 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
281
282 psa_status = psa_get_key_attributes(handle, &attributes);
283
284 if (psa_status == PSA_SUCCESS) {
285
286 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
287 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
288 psa_get_key_bits(&attributes));
289
290 uint8_t *key_buffer = malloc(max_export_size);
291
292 if (key_buffer) {
293
294 size_t export_size;
295 psa_status = psa_export_public_key(handle, key_buffer, max_export_size, &export_size);
296
297 if (psa_status == PSA_SUCCESS) {
298
299 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
300 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
301 }
302
303 free(key_buffer);
304 }
305 else {
306 /* Failed to allocate key buffer */
307 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
308 }
309 }
310
311 call_req_set_opstatus(req, psa_status);
312 psa_reset_key_attributes(&attributes);
313 }
314
315 return rpc_status;
316}
317
318static rpc_status_t import_key_handler(void *context, struct call_req* req)
319{
julhal01c3f4e9a2020-12-15 13:39:01 +0000320 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100321 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000322 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100323
julhal01c3f4e9a2020-12-15 13:39:01 +0000324 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100325
julhal01c3f4e9a2020-12-15 13:39:01 +0000326 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
327 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100328
julhal01c3f4e9a2020-12-15 13:39:01 +0000329 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100330
julhal01c3f4e9a2020-12-15 13:39:01 +0000331 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
332 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100333
julhal01c3f4e9a2020-12-15 13:39:01 +0000334 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100335
julhal01c3f4e9a2020-12-15 13:39:01 +0000336 psa_status_t psa_status;
337 psa_key_handle_t handle;
Julian Hallc02fffb2020-11-23 18:22:06 +0100338
julhal01c3f4e9a2020-12-15 13:39:01 +0000339 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100340
julhal01c3f4e9a2020-12-15 13:39:01 +0000341 if (psa_status == PSA_SUCCESS) {
342
343 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
344 rpc_status = serializer->serialize_import_key_resp(resp_buf, handle);
345 }
346
347 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +0100348 }
349
julhal01c3f4e9a2020-12-15 13:39:01 +0000350 psa_reset_key_attributes(&attributes);
351 free(key_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100352 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000353 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100354
julhal01c3f4e9a2020-12-15 13:39:01 +0000355 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
356 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100357 }
358
359 return rpc_status;
360}
361
362static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
363{
julhal01c3f4e9a2020-12-15 13:39:01 +0000364 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100365 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000366 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100367
368 psa_key_handle_t handle;
369 psa_algorithm_t alg;
370 size_t hash_len = PSA_HASH_MAX_SIZE;
371 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
372
julhal01c3f4e9a2020-12-15 13:39:01 +0000373 if (serializer)
374 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &handle, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100375
376 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
377
378 psa_status_t psa_status;
379 size_t sig_len;
380 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
381
382 psa_status = psa_sign_hash(handle, alg,
383 hash_buffer, hash_len,
384 sig_buffer, sizeof(sig_buffer), &sig_len);
385
386 if (psa_status == PSA_SUCCESS) {
387
388 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
389 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
390 }
391
392 call_req_set_opstatus(req, psa_status);
393 }
394
395 return rpc_status;
396}
397
398static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
399{
julhal01c3f4e9a2020-12-15 13:39:01 +0000400 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100401 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000402 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100403
404 psa_key_handle_t handle;
405 psa_algorithm_t alg;
406 size_t hash_len = PSA_HASH_MAX_SIZE;
407 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
408 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
409 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
410
julhal01c3f4e9a2020-12-15 13:39:01 +0000411 if (serializer)
412 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &handle, &alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100413 hash_buffer, &hash_len,
414 sig_buffer, &sig_len);
415
416 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
417
418 psa_status_t psa_status;
419
420 psa_status = psa_verify_hash(handle, alg,
421 hash_buffer, hash_len,
422 sig_buffer, sig_len);
423
424 call_req_set_opstatus(req, psa_status);
425 }
426
427 return rpc_status;
428}
429
430static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
431{
julhal01c3f4e9a2020-12-15 13:39:01 +0000432 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100433 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000434 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100435
julhal01c3f4e9a2020-12-15 13:39:01 +0000436 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100437
julhal01c3f4e9a2020-12-15 13:39:01 +0000438 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100439
julhal01c3f4e9a2020-12-15 13:39:01 +0000440 psa_key_handle_t handle;
441 psa_algorithm_t alg;
442 size_t ciphertext_len = max_param_size;
443 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
444 size_t salt_len = max_param_size;
445 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100446
julhal01c3f4e9a2020-12-15 13:39:01 +0000447 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100448
julhal01c3f4e9a2020-12-15 13:39:01 +0000449 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
450 &handle, &alg,
451 ciphertext_buffer, &ciphertext_len,
452 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100453
julhal01c3f4e9a2020-12-15 13:39:01 +0000454 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100455
julhal01c3f4e9a2020-12-15 13:39:01 +0000456 psa_status_t psa_status;
457 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100458
julhal01c3f4e9a2020-12-15 13:39:01 +0000459 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100460
julhal01c3f4e9a2020-12-15 13:39:01 +0000461 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100462
julhal01c3f4e9a2020-12-15 13:39:01 +0000463 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
464 psa_get_key_type(&attributes),
465 psa_get_key_bits(&attributes),
466 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100467
julhal01c3f4e9a2020-12-15 13:39:01 +0000468 size_t plaintext_len;
469 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100470
julhal01c3f4e9a2020-12-15 13:39:01 +0000471 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100472
julhal01c3f4e9a2020-12-15 13:39:01 +0000473 psa_status = psa_asymmetric_decrypt(handle, alg,
474 ciphertext_buffer, ciphertext_len,
475 salt_buffer, salt_len,
476 plaintext_buffer, max_decrypt_size, &plaintext_len);
477
478 if (psa_status == PSA_SUCCESS) {
479
480 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
481 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
482 plaintext_buffer, plaintext_len);
483 }
484
485 free(plaintext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100486 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000487 else {
488 /* Failed to allocate ouptput buffer */
489 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
490 }
491 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100492
julhal01c3f4e9a2020-12-15 13:39:01 +0000493 call_req_set_opstatus(req, psa_status);
494 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100495 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100496 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000497 else {
498 /* Failed to allocate buffers */
499 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
500 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100501
julhal01c3f4e9a2020-12-15 13:39:01 +0000502 free(ciphertext_buffer);
503 free(salt_buffer);
504 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100505
506 return rpc_status;
507}
508
509static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
510{
julhal01c3f4e9a2020-12-15 13:39:01 +0000511 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100512 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000513 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100514
julhal01c3f4e9a2020-12-15 13:39:01 +0000515 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100516
julhal01c3f4e9a2020-12-15 13:39:01 +0000517 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100518
julhal01c3f4e9a2020-12-15 13:39:01 +0000519 psa_key_handle_t handle;
520 psa_algorithm_t alg;
521 size_t plaintext_len = max_param_size;
522 uint8_t *plaintext_buffer = malloc(plaintext_len);
523 size_t salt_len = max_param_size;
524 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100525
julhal01c3f4e9a2020-12-15 13:39:01 +0000526 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100527
julhal01c3f4e9a2020-12-15 13:39:01 +0000528 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
529 &handle, &alg,
530 plaintext_buffer, &plaintext_len,
531 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100532
julhal01c3f4e9a2020-12-15 13:39:01 +0000533 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100534
julhal01c3f4e9a2020-12-15 13:39:01 +0000535 psa_status_t psa_status;
536 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100537
julhal01c3f4e9a2020-12-15 13:39:01 +0000538 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100539
julhal01c3f4e9a2020-12-15 13:39:01 +0000540 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100541
julhal01c3f4e9a2020-12-15 13:39:01 +0000542 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
543 psa_get_key_type(&attributes),
544 psa_get_key_bits(&attributes),
545 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100546
julhal01c3f4e9a2020-12-15 13:39:01 +0000547 size_t ciphertext_len;
548 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100549
julhal01c3f4e9a2020-12-15 13:39:01 +0000550 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100551
julhal01c3f4e9a2020-12-15 13:39:01 +0000552 psa_status = psa_asymmetric_encrypt(handle, alg,
553 plaintext_buffer, plaintext_len,
554 salt_buffer, salt_len,
555 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
556
557 if (psa_status == PSA_SUCCESS) {
558
559 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
560 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
561 ciphertext_buffer, ciphertext_len);
562 }
563
564 free(ciphertext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100565 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000566 else {
567 /* Failed to allocate ouptput buffer */
568 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
569 }
570 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100571
julhal01c3f4e9a2020-12-15 13:39:01 +0000572 call_req_set_opstatus(req, psa_status);
573 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100574 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100575 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000576 else {
577 /* Failed to allocate buffers */
578 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
579 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100580
julhal01c3f4e9a2020-12-15 13:39:01 +0000581 free(plaintext_buffer);
582 free(salt_buffer);
583 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100584
585 return rpc_status;
586}
587
588static rpc_status_t generate_random_handler(void *context, struct call_req* req)
589{
julhal01c3f4e9a2020-12-15 13:39:01 +0000590 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100591 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000592 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100593
594 size_t output_size;
595
julhal01c3f4e9a2020-12-15 13:39:01 +0000596 if (serializer)
597 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100598
599 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
600
601 psa_status_t psa_status;
602 uint8_t *output_buffer = malloc(output_size);
603
604 if (output_buffer) {
605
606 psa_status = psa_generate_random(output_buffer, output_size);
607
608 if (psa_status == PSA_SUCCESS) {
609
610 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
611 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
612 output_buffer, output_size);
613 }
614
615 call_req_set_opstatus(req, psa_status);
616 free(output_buffer);
617 }
618 else {
619 /* Failed to allocate output buffer */
620 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
621 }
622 }
623
624 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000625}