blob: 389e8bcd4c81dd1fb7243af20427e12d53b916b1 [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);
Julian Hallc02fffb2020-11-23 18:22:06 +010019static rpc_status_t export_key_handler(void *context, struct call_req* req);
20static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
21static rpc_status_t import_key_handler(void *context, struct call_req* req);
22static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
23static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
24static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
25static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
26static rpc_status_t generate_random_handler(void *context, struct call_req* req);
27
28/* Handler mapping table for service */
29static const struct service_handler handler_table[] = {
30 {TS_CRYPTO_OPCODE_NOP, nop_handler},
31 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
32 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
Julian Hallc02fffb2020-11-23 18:22:06 +010033 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
34 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
35 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
36 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
37 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
38 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
39 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
40 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler}
41};
42
julhal01c3f4e9a2020-12-15 13:39:01 +000043struct rpc_interface *mbed_crypto_provider_init(struct mbed_crypto_provider *context,
julhal013a4207d2021-03-08 13:32:08 +000044 struct storage_backend *storage_backend,
julhal012c18fbf2021-02-01 08:29:28 +000045 int trng_instance)
Julian Hallc02fffb2020-11-23 18:22:06 +010046{
julhal01c3f4e9a2020-12-15 13:39:01 +000047 struct rpc_interface *rpc_interface = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010048
julhal012c18fbf2021-02-01 08:29:28 +000049 trng_adapter_init(trng_instance);
julhal01ffa98d82021-01-20 13:51:58 +000050
Julian Hallc02fffb2020-11-23 18:22:06 +010051 /*
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 */
julhal013a4207d2021-03-08 13:32:08 +000056 if (context && storage_backend) {
Julian Hallc02fffb2020-11-23 18:22:06 +010057
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
julhal013a4207d2021-03-08 13:32:08 +000064 if ((psa_its_frontend_init(storage_backend) == PSA_SUCCESS) &&
julhal011260f102021-02-15 17:34:08 +000065 (psa_crypto_init() == PSA_SUCCESS)) {
66
julhal01c3f4e9a2020-12-15 13:39:01 +000067 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
julhal011260f102021-02-15 17:34:08 +000068 }
Julian Hallc02fffb2020-11-23 18:22:06 +010069 }
70
julhal01c3f4e9a2020-12-15 13:39:01 +000071 return rpc_interface;
Julian Hallc02fffb2020-11-23 18:22:06 +010072}
73
74void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
75{
76 (void)context;
julhal012c18fbf2021-02-01 08:29:28 +000077 trng_adapter_deinit();
Julian Hallc02fffb2020-11-23 18:22:06 +010078}
79
julhal01c3f4e9a2020-12-15 13:39:01 +000080void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
81 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010082{
julhal01c3f4e9a2020-12-15 13:39:01 +000083 if (encoding < TS_RPC_ENCODING_LIMIT)
84 context->serializers[encoding] = serializer;
85}
86
87static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
88 const struct call_req *req)
89{
90 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
91 const struct crypto_provider_serializer* serializer = NULL;
92 unsigned int encoding = call_req_get_encoding(req);
93
94 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
95
96 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010097}
98
99static rpc_status_t nop_handler(void *context, struct call_req* req)
100{
101 /* Responds to a request by returning success */
102 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
103 psa_status_t psa_status = PSA_SUCCESS;
104
105 (void)context;
106 call_req_set_opstatus(req, psa_status);
107
108 return rpc_status;
109}
110
111static rpc_status_t generate_key_handler(void *context, struct call_req* req)
112{
julhal01c3f4e9a2020-12-15 13:39:01 +0000113 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100114 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000115 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100116
117 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
118
julhal01c3f4e9a2020-12-15 13:39:01 +0000119 if (serializer)
120 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100121
122 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
123
124 psa_status_t psa_status;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200125 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100126
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200127 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100128
129 if (psa_status == PSA_SUCCESS) {
130
131 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200132 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100133 }
134
135 call_req_set_opstatus(req, psa_status);
136 }
137
138 psa_reset_key_attributes(&attributes);
139
140 return rpc_status;
141}
142
143static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
144{
julhal01c3f4e9a2020-12-15 13:39:01 +0000145 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100146 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000147 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100148
Julian Hallc02fffb2020-11-23 18:22:06 +0100149 psa_key_id_t id;
150
julhal01c3f4e9a2020-12-15 13:39:01 +0000151 if (serializer)
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200152 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100153
154 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
155
156 psa_status_t psa_status;
157
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200158 psa_status = psa_destroy_key(id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100159 call_req_set_opstatus(req, psa_status);
160 }
161
162 return rpc_status;
163}
164
165static rpc_status_t export_key_handler(void *context, struct call_req* req)
166{
julhal01c3f4e9a2020-12-15 13:39:01 +0000167 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100168 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000169 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100170
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200171 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100172
julhal01c3f4e9a2020-12-15 13:39:01 +0000173 if (serializer)
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200174 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100175
176 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
177
178 psa_status_t psa_status;
179 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
180
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200181 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100182
183 if (psa_status == PSA_SUCCESS) {
184
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200185 size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
Julian Hallc02fffb2020-11-23 18:22:06 +0100186 psa_get_key_type(&attributes),
187 psa_get_key_bits(&attributes));
188
189 uint8_t *key_buffer = malloc(max_export_size);
190
191 if (key_buffer) {
192
193 size_t export_size;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200194 psa_status = psa_export_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100195
196 if (psa_status == PSA_SUCCESS) {
197
198 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
199 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
200 }
201
202 free(key_buffer);
203 }
204 else {
205 /* Failed to allocate key buffer */
206 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
207 }
208 }
209
210 call_req_set_opstatus(req, psa_status);
211 psa_reset_key_attributes(&attributes);
212 }
213
214 return rpc_status;
215}
216
217static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
218{
julhal01c3f4e9a2020-12-15 13:39:01 +0000219 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100220 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000221 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100222
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200223 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100224
julhal01c3f4e9a2020-12-15 13:39:01 +0000225 if (serializer)
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200226 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100227
228 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
229
230 psa_status_t psa_status;
231 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
232
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200233 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100234
235 if (psa_status == PSA_SUCCESS) {
236
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200237 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
Julian Hallc02fffb2020-11-23 18:22:06 +0100238 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
239 psa_get_key_bits(&attributes));
240
241 uint8_t *key_buffer = malloc(max_export_size);
242
243 if (key_buffer) {
244
245 size_t export_size;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200246 psa_status = psa_export_public_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100247
248 if (psa_status == PSA_SUCCESS) {
249
250 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
251 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
252 }
253
254 free(key_buffer);
255 }
256 else {
257 /* Failed to allocate key buffer */
258 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
259 }
260 }
261
262 call_req_set_opstatus(req, psa_status);
263 psa_reset_key_attributes(&attributes);
264 }
265
266 return rpc_status;
267}
268
269static rpc_status_t import_key_handler(void *context, struct call_req* req)
270{
julhal01c3f4e9a2020-12-15 13:39:01 +0000271 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100272 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000273 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100274
julhal01c3f4e9a2020-12-15 13:39:01 +0000275 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100276
julhal01c3f4e9a2020-12-15 13:39:01 +0000277 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
278 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100279
julhal01c3f4e9a2020-12-15 13:39:01 +0000280 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100281
julhal01c3f4e9a2020-12-15 13:39:01 +0000282 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
283 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100284
julhal01c3f4e9a2020-12-15 13:39:01 +0000285 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100286
julhal01c3f4e9a2020-12-15 13:39:01 +0000287 psa_status_t psa_status;
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200288 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100289
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200290 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100291
julhal01c3f4e9a2020-12-15 13:39:01 +0000292 if (psa_status == PSA_SUCCESS) {
293
294 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200295 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
julhal01c3f4e9a2020-12-15 13:39:01 +0000296 }
297
298 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +0100299 }
300
julhal01c3f4e9a2020-12-15 13:39:01 +0000301 psa_reset_key_attributes(&attributes);
302 free(key_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100303 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000304 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100305
julhal01c3f4e9a2020-12-15 13:39:01 +0000306 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
307 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100308 }
309
310 return rpc_status;
311}
312
313static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
314{
julhal01c3f4e9a2020-12-15 13:39:01 +0000315 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100316 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000317 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100318
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200319 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100320 psa_algorithm_t alg;
321 size_t hash_len = PSA_HASH_MAX_SIZE;
322 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
323
julhal01c3f4e9a2020-12-15 13:39:01 +0000324 if (serializer)
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200325 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100326
327 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
328
329 psa_status_t psa_status;
330 size_t sig_len;
331 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
332
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200333 psa_status = psa_sign_hash(id, alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100334 hash_buffer, hash_len,
335 sig_buffer, sizeof(sig_buffer), &sig_len);
336
337 if (psa_status == PSA_SUCCESS) {
338
339 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
340 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
341 }
342
343 call_req_set_opstatus(req, psa_status);
344 }
345
346 return rpc_status;
347}
348
349static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
350{
julhal01c3f4e9a2020-12-15 13:39:01 +0000351 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100352 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000353 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100354
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200355 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100356 psa_algorithm_t alg;
357 size_t hash_len = PSA_HASH_MAX_SIZE;
358 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
359 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
360 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
361
julhal01c3f4e9a2020-12-15 13:39:01 +0000362 if (serializer)
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200363 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100364 hash_buffer, &hash_len,
365 sig_buffer, &sig_len);
366
367 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
368
369 psa_status_t psa_status;
370
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200371 psa_status = psa_verify_hash(id, alg,
Julian Hallc02fffb2020-11-23 18:22:06 +0100372 hash_buffer, hash_len,
373 sig_buffer, sig_len);
374
375 call_req_set_opstatus(req, psa_status);
376 }
377
378 return rpc_status;
379}
380
381static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
382{
julhal01c3f4e9a2020-12-15 13:39:01 +0000383 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100384 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000385 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100386
julhal01c3f4e9a2020-12-15 13:39:01 +0000387 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100388
julhal01c3f4e9a2020-12-15 13:39:01 +0000389 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100390
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200391 psa_key_id_t id;
julhal01c3f4e9a2020-12-15 13:39:01 +0000392 psa_algorithm_t alg;
393 size_t ciphertext_len = max_param_size;
394 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
395 size_t salt_len = max_param_size;
396 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100397
julhal01c3f4e9a2020-12-15 13:39:01 +0000398 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100399
julhal01c3f4e9a2020-12-15 13:39:01 +0000400 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200401 &id, &alg,
julhal01c3f4e9a2020-12-15 13:39:01 +0000402 ciphertext_buffer, &ciphertext_len,
403 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100404
julhal01c3f4e9a2020-12-15 13:39:01 +0000405 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100406
julhal01c3f4e9a2020-12-15 13:39:01 +0000407 psa_status_t psa_status;
408 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100409
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200410 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100411
julhal01c3f4e9a2020-12-15 13:39:01 +0000412 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100413
julhal01c3f4e9a2020-12-15 13:39:01 +0000414 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
415 psa_get_key_type(&attributes),
416 psa_get_key_bits(&attributes),
417 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100418
julhal01c3f4e9a2020-12-15 13:39:01 +0000419 size_t plaintext_len;
420 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100421
julhal01c3f4e9a2020-12-15 13:39:01 +0000422 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100423
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200424 psa_status = psa_asymmetric_decrypt(id, alg,
julhal01c3f4e9a2020-12-15 13:39:01 +0000425 ciphertext_buffer, ciphertext_len,
426 salt_buffer, salt_len,
427 plaintext_buffer, max_decrypt_size, &plaintext_len);
428
429 if (psa_status == PSA_SUCCESS) {
430
431 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
432 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
433 plaintext_buffer, plaintext_len);
434 }
435
436 free(plaintext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100437 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000438 else {
439 /* Failed to allocate ouptput buffer */
440 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
441 }
442 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100443
julhal01c3f4e9a2020-12-15 13:39:01 +0000444 call_req_set_opstatus(req, psa_status);
445 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100446 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100447 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000448 else {
449 /* Failed to allocate buffers */
450 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
451 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100452
julhal01c3f4e9a2020-12-15 13:39:01 +0000453 free(ciphertext_buffer);
454 free(salt_buffer);
455 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100456
457 return rpc_status;
458}
459
460static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
461{
julhal01c3f4e9a2020-12-15 13:39:01 +0000462 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100463 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000464 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100465
julhal01c3f4e9a2020-12-15 13:39:01 +0000466 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100467
julhal01c3f4e9a2020-12-15 13:39:01 +0000468 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100469
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200470 psa_key_id_t id;
julhal01c3f4e9a2020-12-15 13:39:01 +0000471 psa_algorithm_t alg;
472 size_t plaintext_len = max_param_size;
473 uint8_t *plaintext_buffer = malloc(plaintext_len);
474 size_t salt_len = max_param_size;
475 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100476
julhal01c3f4e9a2020-12-15 13:39:01 +0000477 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100478
julhal01c3f4e9a2020-12-15 13:39:01 +0000479 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200480 &id, &alg,
julhal01c3f4e9a2020-12-15 13:39:01 +0000481 plaintext_buffer, &plaintext_len,
482 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100483
julhal01c3f4e9a2020-12-15 13:39:01 +0000484 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100485
julhal01c3f4e9a2020-12-15 13:39:01 +0000486 psa_status_t psa_status;
487 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100488
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200489 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100490
julhal01c3f4e9a2020-12-15 13:39:01 +0000491 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100492
julhal01c3f4e9a2020-12-15 13:39:01 +0000493 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
494 psa_get_key_type(&attributes),
495 psa_get_key_bits(&attributes),
496 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100497
julhal01c3f4e9a2020-12-15 13:39:01 +0000498 size_t ciphertext_len;
499 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100500
julhal01c3f4e9a2020-12-15 13:39:01 +0000501 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100502
Balint Dobszay3c52ce62021-05-10 16:27:18 +0200503 psa_status = psa_asymmetric_encrypt(id, alg,
julhal01c3f4e9a2020-12-15 13:39:01 +0000504 plaintext_buffer, plaintext_len,
505 salt_buffer, salt_len,
506 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
507
508 if (psa_status == PSA_SUCCESS) {
509
510 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
511 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
512 ciphertext_buffer, ciphertext_len);
513 }
514
515 free(ciphertext_buffer);
Julian Hallc02fffb2020-11-23 18:22:06 +0100516 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000517 else {
518 /* Failed to allocate ouptput buffer */
519 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
520 }
521 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100522
julhal01c3f4e9a2020-12-15 13:39:01 +0000523 call_req_set_opstatus(req, psa_status);
524 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100525 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100526 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000527 else {
528 /* Failed to allocate buffers */
529 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
530 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100531
julhal01c3f4e9a2020-12-15 13:39:01 +0000532 free(plaintext_buffer);
533 free(salt_buffer);
534 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100535
536 return rpc_status;
537}
538
539static rpc_status_t generate_random_handler(void *context, struct call_req* req)
540{
julhal01c3f4e9a2020-12-15 13:39:01 +0000541 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
Julian Hallc02fffb2020-11-23 18:22:06 +0100542 struct call_param_buf *req_buf = call_req_get_req_buf(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000543 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100544
545 size_t output_size;
546
julhal01c3f4e9a2020-12-15 13:39:01 +0000547 if (serializer)
548 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100549
550 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
551
552 psa_status_t psa_status;
553 uint8_t *output_buffer = malloc(output_size);
554
555 if (output_buffer) {
556
557 psa_status = psa_generate_random(output_buffer, output_size);
558
559 if (psa_status == PSA_SUCCESS) {
560
561 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
562 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
563 output_buffer, output_size);
564 }
565
566 call_req_set_opstatus(req, psa_status);
567 free(output_buffer);
568 }
569 else {
570 /* Failed to allocate output buffer */
571 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
572 }
573 }
574
575 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000576}