blob: 4d5a0a330f4c6d733bfeb7119547c9554f2a3637 [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>
Julian Hallc02fffb2020-11-23 18:22:06 +010011#include <service/secure_storage/client/psa/its/its_client.h>
12#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,
julhal01ffa98d82021-01-20 13:51:58 +000048 struct rpc_caller *storage_provider,
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 */
60 if (context && storage_provider) {
61
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
Julian Hallc02fffb2020-11-23 18:22:06 +010068 if ((psa_its_client_init(storage_provider) == PSA_SUCCESS) &&
69 (psa_crypto_init() == PSA_SUCCESS))
julhal01c3f4e9a2020-12-15 13:39:01 +000070 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010071 }
72
julhal01c3f4e9a2020-12-15 13:39:01 +000073 return rpc_interface;
Julian Hallc02fffb2020-11-23 18:22:06 +010074}
75
76void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
77{
78 (void)context;
julhal012c18fbf2021-02-01 08:29:28 +000079 trng_adapter_deinit();
Julian Hallc02fffb2020-11-23 18:22:06 +010080}
81
julhal01c3f4e9a2020-12-15 13:39:01 +000082void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
83 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010084{
julhal01c3f4e9a2020-12-15 13:39:01 +000085 if (encoding < TS_RPC_ENCODING_LIMIT)
86 context->serializers[encoding] = serializer;
87}
88
89static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
90 const struct call_req *req)
91{
92 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
93 const struct crypto_provider_serializer* serializer = NULL;
94 unsigned int encoding = call_req_get_encoding(req);
95
96 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
97
98 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010099}
100
101static rpc_status_t nop_handler(void *context, struct call_req* req)
102{
103 /* Responds to a request by returning success */
104 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
105 psa_status_t psa_status = PSA_SUCCESS;
106
107 (void)context;
108 call_req_set_opstatus(req, psa_status);
109
110 return rpc_status;
111}
112
113static rpc_status_t generate_key_handler(void *context, struct call_req* req)
114{
julhal01c3f4e9a2020-12-15 13:39:01 +0000115 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100116 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000117 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100118
119 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
120
julhal01c3f4e9a2020-12-15 13:39:01 +0000121 if (serializer)
122 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100123
124 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
125
126 psa_status_t psa_status;
127 psa_key_handle_t handle;
128
129 psa_status = psa_generate_key(&attributes, &handle);
130
131 if (psa_status == PSA_SUCCESS) {
132
133 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
134 rpc_status = serializer->serialize_generate_key_resp(resp_buf, handle);
135 }
136
137 call_req_set_opstatus(req, psa_status);
138 }
139
140 psa_reset_key_attributes(&attributes);
141
142 return rpc_status;
143}
144
145static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
146{
julhal01c3f4e9a2020-12-15 13:39:01 +0000147 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100148 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000149 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100150
151 psa_key_handle_t handle;
152
julhal01c3f4e9a2020-12-15 13:39:01 +0000153 if (serializer)
154 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100155
156 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
157
158 psa_status_t psa_status;
159
160 psa_status = psa_destroy_key(handle);
161 call_req_set_opstatus(req, psa_status);
162 }
163
164 return rpc_status;
165}
166
167static rpc_status_t open_key_handler(void *context, struct call_req* req)
168{
julhal01c3f4e9a2020-12-15 13:39:01 +0000169 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100170 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000171 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100172
173 psa_key_id_t id;
174
julhal01c3f4e9a2020-12-15 13:39:01 +0000175 if (serializer)
176 rpc_status = serializer->deserialize_open_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100177
178 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
179
180 psa_status_t psa_status;
181 psa_key_handle_t handle;
182
183 psa_status = psa_open_key(id, &handle);
184
185 if (psa_status == PSA_SUCCESS) {
186
187 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
188 rpc_status = serializer->serialize_open_key_resp(resp_buf, handle);
189 }
190
191 call_req_set_opstatus(req, psa_status);
192 }
193
194 return rpc_status;
195}
196
197static rpc_status_t close_key_handler(void *context, struct call_req* req)
198{
julhal01c3f4e9a2020-12-15 13:39:01 +0000199 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100200 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000201 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100202
203 psa_key_handle_t handle;
204
julhal01c3f4e9a2020-12-15 13:39:01 +0000205 if (serializer)
206 rpc_status = serializer->deserialize_close_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100207
208 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
209
210 psa_status_t psa_status;
211
212 psa_status = psa_close_key(handle);
213 call_req_set_opstatus(req, psa_status);
214 }
215
216 return rpc_status;
217}
218
219static rpc_status_t export_key_handler(void *context, struct call_req* req)
220{
julhal01c3f4e9a2020-12-15 13:39:01 +0000221 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100222 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000223 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100224
225 psa_key_handle_t handle;
226
julhal01c3f4e9a2020-12-15 13:39:01 +0000227 if (serializer)
228 rpc_status = serializer->deserialize_export_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100229
230 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
231
232 psa_status_t psa_status;
233 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
234
235 psa_status = psa_get_key_attributes(handle, &attributes);
236
237 if (psa_status == PSA_SUCCESS) {
238
239 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
240 psa_get_key_type(&attributes),
241 psa_get_key_bits(&attributes));
242
243 uint8_t *key_buffer = malloc(max_export_size);
244
245 if (key_buffer) {
246
247 size_t export_size;
248 psa_status = psa_export_key(handle, key_buffer, max_export_size, &export_size);
249
250 if (psa_status == PSA_SUCCESS) {
251
252 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
253 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
254 }
255
256 free(key_buffer);
257 }
258 else {
259 /* Failed to allocate key buffer */
260 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
261 }
262 }
263
264 call_req_set_opstatus(req, psa_status);
265 psa_reset_key_attributes(&attributes);
266 }
267
268 return rpc_status;
269}
270
271static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
272{
julhal01c3f4e9a2020-12-15 13:39:01 +0000273 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100274 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000275 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100276
277 psa_key_handle_t handle;
278
julhal01c3f4e9a2020-12-15 13:39:01 +0000279 if (serializer)
280 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100281
282 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
283
284 psa_status_t psa_status;
285 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
286
287 psa_status = psa_get_key_attributes(handle, &attributes);
288
289 if (psa_status == PSA_SUCCESS) {
290
291 size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(
292 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
293 psa_get_key_bits(&attributes));
294
295 uint8_t *key_buffer = malloc(max_export_size);
296
297 if (key_buffer) {
298
299 size_t export_size;
300 psa_status = psa_export_public_key(handle, key_buffer, max_export_size, &export_size);
301
302 if (psa_status == PSA_SUCCESS) {
303
304 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
305 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
306 }
307
308 free(key_buffer);
309 }
310 else {
311 /* Failed to allocate key buffer */
312 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
313 }
314 }
315
316 call_req_set_opstatus(req, psa_status);
317 psa_reset_key_attributes(&attributes);
318 }
319
320 return rpc_status;
321}
322
323static rpc_status_t import_key_handler(void *context, struct call_req* req)
324{
julhal01c3f4e9a2020-12-15 13:39:01 +0000325 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100326 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000327 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100328
julhal01c3f4e9a2020-12-15 13:39:01 +0000329 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100330
julhal01c3f4e9a2020-12-15 13:39:01 +0000331 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
332 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100333
julhal01c3f4e9a2020-12-15 13:39:01 +0000334 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100335
julhal01c3f4e9a2020-12-15 13:39:01 +0000336 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
337 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100338
julhal01c3f4e9a2020-12-15 13:39:01 +0000339 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100340
julhal01c3f4e9a2020-12-15 13:39:01 +0000341 psa_status_t psa_status;
342 psa_key_handle_t handle;
Julian Hallc02fffb2020-11-23 18:22:06 +0100343
julhal01c3f4e9a2020-12-15 13:39:01 +0000344 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &handle);
Julian Hallc02fffb2020-11-23 18:22:06 +0100345
julhal01c3f4e9a2020-12-15 13:39:01 +0000346 if (psa_status == PSA_SUCCESS) {
347
348 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
349 rpc_status = serializer->serialize_import_key_resp(resp_buf, handle);
350 }
351
352 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +0100353 }
354
julhal01c3f4e9a2020-12-15 13:39:01 +0000355 psa_reset_key_attributes(&attributes);
356 free(key_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100357 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000358 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100359
julhal01c3f4e9a2020-12-15 13:39:01 +0000360 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
361 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100362 }
363
364 return rpc_status;
365}
366
367static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
368{
julhal01c3f4e9a2020-12-15 13:39:01 +0000369 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100370 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000371 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100372
373 psa_key_handle_t handle;
374 psa_algorithm_t alg;
375 size_t hash_len = PSA_HASH_MAX_SIZE;
376 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
377
julhal01c3f4e9a2020-12-15 13:39:01 +0000378 if (serializer)
379 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &handle, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100380
381 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
382
383 psa_status_t psa_status;
384 size_t sig_len;
385 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
386
387 psa_status = psa_sign_hash(handle, alg,
388 hash_buffer, hash_len,
389 sig_buffer, sizeof(sig_buffer), &sig_len);
390
391 if (psa_status == PSA_SUCCESS) {
392
393 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
394 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
395 }
396
397 call_req_set_opstatus(req, psa_status);
398 }
399
400 return rpc_status;
401}
402
403static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
404{
julhal01c3f4e9a2020-12-15 13:39:01 +0000405 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100406 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000407 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100408
409 psa_key_handle_t handle;
410 psa_algorithm_t alg;
411 size_t hash_len = PSA_HASH_MAX_SIZE;
412 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
413 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
414 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
415
julhal01c3f4e9a2020-12-15 13:39:01 +0000416 if (serializer)
417 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &handle, &alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100418 hash_buffer, &hash_len,
419 sig_buffer, &sig_len);
420
421 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
422
423 psa_status_t psa_status;
424
425 psa_status = psa_verify_hash(handle, alg,
426 hash_buffer, hash_len,
427 sig_buffer, sig_len);
428
429 call_req_set_opstatus(req, psa_status);
430 }
431
432 return rpc_status;
433}
434
435static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
436{
julhal01c3f4e9a2020-12-15 13:39:01 +0000437 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100438 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000439 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100440
julhal01c3f4e9a2020-12-15 13:39:01 +0000441 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100442
julhal01c3f4e9a2020-12-15 13:39:01 +0000443 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100444
julhal01c3f4e9a2020-12-15 13:39:01 +0000445 psa_key_handle_t handle;
446 psa_algorithm_t alg;
447 size_t ciphertext_len = max_param_size;
448 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
449 size_t salt_len = max_param_size;
450 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100451
julhal01c3f4e9a2020-12-15 13:39:01 +0000452 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100453
julhal01c3f4e9a2020-12-15 13:39:01 +0000454 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
455 &handle, &alg,
456 ciphertext_buffer, &ciphertext_len,
457 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100458
julhal01c3f4e9a2020-12-15 13:39:01 +0000459 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100460
julhal01c3f4e9a2020-12-15 13:39:01 +0000461 psa_status_t psa_status;
462 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100463
julhal01c3f4e9a2020-12-15 13:39:01 +0000464 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100465
julhal01c3f4e9a2020-12-15 13:39:01 +0000466 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100467
julhal01c3f4e9a2020-12-15 13:39:01 +0000468 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
469 psa_get_key_type(&attributes),
470 psa_get_key_bits(&attributes),
471 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100472
julhal01c3f4e9a2020-12-15 13:39:01 +0000473 size_t plaintext_len;
474 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100475
julhal01c3f4e9a2020-12-15 13:39:01 +0000476 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100477
julhal01c3f4e9a2020-12-15 13:39:01 +0000478 psa_status = psa_asymmetric_decrypt(handle, alg,
479 ciphertext_buffer, ciphertext_len,
480 salt_buffer, salt_len,
481 plaintext_buffer, max_decrypt_size, &plaintext_len);
482
483 if (psa_status == PSA_SUCCESS) {
484
485 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
486 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
487 plaintext_buffer, plaintext_len);
488 }
489
490 free(plaintext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100491 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000492 else {
493 /* Failed to allocate ouptput buffer */
494 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
495 }
496 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100497
julhal01c3f4e9a2020-12-15 13:39:01 +0000498 call_req_set_opstatus(req, psa_status);
499 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100500 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100501 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000502 else {
503 /* Failed to allocate buffers */
504 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
505 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100506
julhal01c3f4e9a2020-12-15 13:39:01 +0000507 free(ciphertext_buffer);
508 free(salt_buffer);
509 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100510
511 return rpc_status;
512}
513
514static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
515{
julhal01c3f4e9a2020-12-15 13:39:01 +0000516 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100517 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000518 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100519
julhal01c3f4e9a2020-12-15 13:39:01 +0000520 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100521
julhal01c3f4e9a2020-12-15 13:39:01 +0000522 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100523
julhal01c3f4e9a2020-12-15 13:39:01 +0000524 psa_key_handle_t handle;
525 psa_algorithm_t alg;
526 size_t plaintext_len = max_param_size;
527 uint8_t *plaintext_buffer = malloc(plaintext_len);
528 size_t salt_len = max_param_size;
529 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100530
julhal01c3f4e9a2020-12-15 13:39:01 +0000531 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100532
julhal01c3f4e9a2020-12-15 13:39:01 +0000533 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
534 &handle, &alg,
535 plaintext_buffer, &plaintext_len,
536 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100537
julhal01c3f4e9a2020-12-15 13:39:01 +0000538 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100539
julhal01c3f4e9a2020-12-15 13:39:01 +0000540 psa_status_t psa_status;
541 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100542
julhal01c3f4e9a2020-12-15 13:39:01 +0000543 psa_status = psa_get_key_attributes(handle, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100544
julhal01c3f4e9a2020-12-15 13:39:01 +0000545 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100546
julhal01c3f4e9a2020-12-15 13:39:01 +0000547 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
548 psa_get_key_type(&attributes),
549 psa_get_key_bits(&attributes),
550 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100551
julhal01c3f4e9a2020-12-15 13:39:01 +0000552 size_t ciphertext_len;
553 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100554
julhal01c3f4e9a2020-12-15 13:39:01 +0000555 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100556
julhal01c3f4e9a2020-12-15 13:39:01 +0000557 psa_status = psa_asymmetric_encrypt(handle, alg,
558 plaintext_buffer, plaintext_len,
559 salt_buffer, salt_len,
560 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
561
562 if (psa_status == PSA_SUCCESS) {
563
564 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
565 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
566 ciphertext_buffer, ciphertext_len);
567 }
568
569 free(ciphertext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100570 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000571 else {
572 /* Failed to allocate ouptput buffer */
573 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
574 }
575 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100576
julhal01c3f4e9a2020-12-15 13:39:01 +0000577 call_req_set_opstatus(req, psa_status);
578 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100579 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100580 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000581 else {
582 /* Failed to allocate buffers */
583 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
584 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100585
julhal01c3f4e9a2020-12-15 13:39:01 +0000586 free(plaintext_buffer);
587 free(salt_buffer);
588 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100589
590 return rpc_status;
591}
592
593static rpc_status_t generate_random_handler(void *context, struct call_req* req)
594{
julhal01c3f4e9a2020-12-15 13:39:01 +0000595 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100596 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000597 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100598
599 size_t output_size;
600
julhal01c3f4e9a2020-12-15 13:39:01 +0000601 if (serializer)
602 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100603
604 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
605
606 psa_status_t psa_status;
607 uint8_t *output_buffer = malloc(output_size);
608
609 if (output_buffer) {
610
611 psa_status = psa_generate_random(output_buffer, output_size);
612
613 if (psa_status == PSA_SUCCESS) {
614
615 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
616 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
617 output_buffer, output_size);
618 }
619
620 call_req_set_opstatus(req, psa_status);
621 free(output_buffer);
622 }
623 else {
624 /* Failed to allocate output buffer */
625 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
626 }
627 }
628
629 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000630}