blob: 394f4935f00693a733ba6efa23653d20dfebc65d [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>
Julian Hall9061e6c2021-06-29 14:24:20 +01009#include <service/crypto/provider/crypto_provider.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010010#include <protocols/rpc/common/packed-c/status.h>
11#include <psa/crypto.h>
12
13/* Service request handlers */
14static rpc_status_t nop_handler(void *context, struct call_req* req);
15static rpc_status_t generate_key_handler(void *context, struct call_req* req);
16static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010017static rpc_status_t export_key_handler(void *context, struct call_req* req);
18static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
19static rpc_status_t import_key_handler(void *context, struct call_req* req);
20static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
21static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
22static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
23static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
24static rpc_status_t generate_random_handler(void *context, struct call_req* req);
Julian Hall8359a632021-07-08 15:10:30 +010025static rpc_status_t copy_key_handler(void *context, struct call_req* req);
26static rpc_status_t purge_key_handler(void *context, struct call_req* req);
27static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010028
29/* Handler mapping table for service */
30static const struct service_handler handler_table[] = {
Julian Hallf5728962021-06-24 09:40:23 +010031 {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_EXPORT_KEY, export_key_handler},
35 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
36 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
37 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
38 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
39 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
40 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
41 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler},
Julian Hall8359a632021-07-08 15:10:30 +010042 {TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler},
43 {TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler},
44 {TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler},
Julian Hallc02fffb2020-11-23 18:22:06 +010045};
46
Julian Hall9061e6c2021-06-29 14:24:20 +010047struct rpc_interface *crypto_provider_init(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010048{
Julian Hall9061e6c2021-06-29 14:24:20 +010049 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
50 context->serializers[encoding] = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010051
Julian Hall9061e6c2021-06-29 14:24:20 +010052 service_provider_init(&context->base_provider, context,
Julian Hallf5728962021-06-24 09:40:23 +010053 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
Julian Hallc02fffb2020-11-23 18:22:06 +010054
Julian Hall9061e6c2021-06-29 14:24:20 +010055 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010056}
57
Julian Hall9061e6c2021-06-29 14:24:20 +010058void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010059{
Julian Hall7bfb18e2021-07-13 15:48:13 +010060
Julian Hallc02fffb2020-11-23 18:22:06 +010061}
62
Julian Hall9061e6c2021-06-29 14:24:20 +010063void crypto_provider_register_serializer(struct crypto_provider *context,
64 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010065{
Julian Hallf5728962021-06-24 09:40:23 +010066 if (encoding < TS_RPC_ENCODING_LIMIT)
67 context->serializers[encoding] = serializer;
julhal01c3f4e9a2020-12-15 13:39:01 +000068}
69
Julian Hall13e76952021-07-13 12:17:09 +010070void crypto_provider_extend(struct crypto_provider *context,
71 struct service_provider *sub_provider)
72{
73 service_provider_extend(&context->base_provider, sub_provider);
74}
75
julhal01c3f4e9a2020-12-15 13:39:01 +000076static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
Julian Hallf5728962021-06-24 09:40:23 +010077 const struct call_req *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000078{
Julian Hall9061e6c2021-06-29 14:24:20 +010079 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +010080 const struct crypto_provider_serializer* serializer = NULL;
81 unsigned int encoding = call_req_get_encoding(req);
julhal01c3f4e9a2020-12-15 13:39:01 +000082
Julian Hallf5728962021-06-24 09:40:23 +010083 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
julhal01c3f4e9a2020-12-15 13:39:01 +000084
Julian Hallf5728962021-06-24 09:40:23 +010085 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010086}
87
88static rpc_status_t nop_handler(void *context, struct call_req* req)
89{
Julian Hallf5728962021-06-24 09:40:23 +010090 /* Responds to a request by returning success */
91 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
92 psa_status_t psa_status = PSA_SUCCESS;
Julian Hallc02fffb2020-11-23 18:22:06 +010093
Julian Hallf5728962021-06-24 09:40:23 +010094 (void)context;
95 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +010096
Julian Hallf5728962021-06-24 09:40:23 +010097 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +010098}
99
100static rpc_status_t generate_key_handler(void *context, struct call_req* req)
101{
Julian Hallf5728962021-06-24 09:40:23 +0100102 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
103 struct call_param_buf *req_buf = call_req_get_req_buf(req);
104 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100105
Julian Hallf5728962021-06-24 09:40:23 +0100106 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100107
Julian Hallf5728962021-06-24 09:40:23 +0100108 if (serializer)
109 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100110
Julian Hallf5728962021-06-24 09:40:23 +0100111 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100112
Julian Hallf5728962021-06-24 09:40:23 +0100113 psa_status_t psa_status;
114 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100115
Julian Hallf5728962021-06-24 09:40:23 +0100116 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100117
Julian Hallf5728962021-06-24 09:40:23 +0100118 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100119
Julian Hallf5728962021-06-24 09:40:23 +0100120 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
121 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
122 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100123
Julian Hallf5728962021-06-24 09:40:23 +0100124 call_req_set_opstatus(req, psa_status);
125 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100126
Julian Hallf5728962021-06-24 09:40:23 +0100127 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100128
Julian Hallf5728962021-06-24 09:40:23 +0100129 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100130}
131
132static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
133{
Julian Hallf5728962021-06-24 09:40:23 +0100134 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
135 struct call_param_buf *req_buf = call_req_get_req_buf(req);
136 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100137
Julian Hallf5728962021-06-24 09:40:23 +0100138 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100139
Julian Hallf5728962021-06-24 09:40:23 +0100140 if (serializer)
141 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100142
Julian Hallf5728962021-06-24 09:40:23 +0100143 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100144
Julian Hallf5728962021-06-24 09:40:23 +0100145 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100146
Julian Hallf5728962021-06-24 09:40:23 +0100147 psa_status = psa_destroy_key(id);
148 call_req_set_opstatus(req, psa_status);
149 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100150
Julian Hallf5728962021-06-24 09:40:23 +0100151 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100152}
153
154static rpc_status_t export_key_handler(void *context, struct call_req* req)
155{
Julian Hallf5728962021-06-24 09:40:23 +0100156 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
157 struct call_param_buf *req_buf = call_req_get_req_buf(req);
158 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100159
Julian Hallf5728962021-06-24 09:40:23 +0100160 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100161
Julian Hallf5728962021-06-24 09:40:23 +0100162 if (serializer)
163 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100164
Julian Hallf5728962021-06-24 09:40:23 +0100165 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100166
Julian Hallf5728962021-06-24 09:40:23 +0100167 psa_status_t psa_status;
168 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100169
Julian Hallf5728962021-06-24 09:40:23 +0100170 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100171
Julian Hallf5728962021-06-24 09:40:23 +0100172 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100173
Julian Hallf5728962021-06-24 09:40:23 +0100174 size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
175 psa_get_key_type(&attributes),
176 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100177
Julian Hallec81a502021-07-12 11:36:37 +0100178 if (max_export_size) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100179
Julian Hallec81a502021-07-12 11:36:37 +0100180 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100181
Julian Hallec81a502021-07-12 11:36:37 +0100182 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100183
Julian Hallec81a502021-07-12 11:36:37 +0100184 size_t export_size;
185 psa_status_t psa_status = psa_export_key(id, key_buffer,
186 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100187
Julian Hallec81a502021-07-12 11:36:37 +0100188 if (psa_status == PSA_SUCCESS) {
189
190 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
191 rpc_status = serializer->serialize_export_key_resp(resp_buf,
192 key_buffer, export_size);
193 }
194
195 free(key_buffer);
Julian Hallf5728962021-06-24 09:40:23 +0100196 }
Julian Hallec81a502021-07-12 11:36:37 +0100197 else {
198 /* Failed to allocate key buffer */
199 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
200 }
Julian Hallf5728962021-06-24 09:40:23 +0100201 }
202 else {
Julian Hallec81a502021-07-12 11:36:37 +0100203
204 /* No sensible export size was returned so
205 * key attributes must be in an invalid state.
206 */
207 psa_status = PSA_ERROR_GENERIC_ERROR;
Julian Hallf5728962021-06-24 09:40:23 +0100208 }
209 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100210
Julian Hallf5728962021-06-24 09:40:23 +0100211 call_req_set_opstatus(req, psa_status);
212 psa_reset_key_attributes(&attributes);
213 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100214
Julian Hallf5728962021-06-24 09:40:23 +0100215 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100216}
217
218static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
219{
Julian Hallf5728962021-06-24 09:40:23 +0100220 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
221 struct call_param_buf *req_buf = call_req_get_req_buf(req);
222 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100223
Julian Hallf5728962021-06-24 09:40:23 +0100224 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100225
Julian Hallf5728962021-06-24 09:40:23 +0100226 if (serializer)
227 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100228
Julian Hallf5728962021-06-24 09:40:23 +0100229 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100230
Julian Hallec81a502021-07-12 11:36:37 +0100231 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
232 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100233
Julian Hallec81a502021-07-12 11:36:37 +0100234 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100235
Julian Hallec81a502021-07-12 11:36:37 +0100236 size_t export_size;
237 psa_status_t psa_status = psa_export_public_key(id, key_buffer,
238 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100239
Julian Hallec81a502021-07-12 11:36:37 +0100240 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100241
Julian Hallec81a502021-07-12 11:36:37 +0100242 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
243 rpc_status = serializer->serialize_export_public_key_resp(resp_buf,
244 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100245 }
Julian Hallec81a502021-07-12 11:36:37 +0100246
247 free(key_buffer);
248 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100249 }
Julian Hallec81a502021-07-12 11:36:37 +0100250 else {
251 /* Failed to allocate key buffer */
252 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
253 }
Julian Hallf5728962021-06-24 09:40:23 +0100254 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100255
Julian Hallf5728962021-06-24 09:40:23 +0100256 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100257}
258
259static rpc_status_t import_key_handler(void *context, struct call_req* req)
260{
Julian Hallf5728962021-06-24 09:40:23 +0100261 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
262 struct call_param_buf *req_buf = call_req_get_req_buf(req);
263 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100264
Julian Hallf5728962021-06-24 09:40:23 +0100265 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100266
Julian Hallf5728962021-06-24 09:40:23 +0100267 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
268 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100269
Julian Hallf5728962021-06-24 09:40:23 +0100270 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100271
Julian Hallf5728962021-06-24 09:40:23 +0100272 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallec81a502021-07-12 11:36:37 +0100273 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes,
274 key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100275
Julian Hallf5728962021-06-24 09:40:23 +0100276 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100277
Julian Hallf5728962021-06-24 09:40:23 +0100278 psa_status_t psa_status;
279 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100280
Julian Hallf5728962021-06-24 09:40:23 +0100281 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100282
Julian Hallf5728962021-06-24 09:40:23 +0100283 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000284
Julian Hallf5728962021-06-24 09:40:23 +0100285 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
286 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
287 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000288
Julian Hallf5728962021-06-24 09:40:23 +0100289 call_req_set_opstatus(req, psa_status);
290 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100291
Julian Hallf5728962021-06-24 09:40:23 +0100292 psa_reset_key_attributes(&attributes);
293 free(key_buffer);
294 }
295 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100296
Julian Hallf5728962021-06-24 09:40:23 +0100297 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
298 }
299 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100300
Julian Hallf5728962021-06-24 09:40:23 +0100301 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100302}
303
304static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
305{
Julian Hallf5728962021-06-24 09:40:23 +0100306 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
307 struct call_param_buf *req_buf = call_req_get_req_buf(req);
308 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100309
Julian Hallf5728962021-06-24 09:40:23 +0100310 psa_key_id_t id;
311 psa_algorithm_t alg;
312 size_t hash_len = PSA_HASH_MAX_SIZE;
313 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100314
Julian Hallf5728962021-06-24 09:40:23 +0100315 if (serializer)
316 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100317
Julian Hallf5728962021-06-24 09:40:23 +0100318 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100319
Julian Hallf5728962021-06-24 09:40:23 +0100320 psa_status_t psa_status;
321 size_t sig_len;
322 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100323
Julian Hallf5728962021-06-24 09:40:23 +0100324 psa_status = psa_sign_hash(id, alg,
325 hash_buffer, hash_len,
326 sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100327
Julian Hallf5728962021-06-24 09:40:23 +0100328 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100329
Julian Hallf5728962021-06-24 09:40:23 +0100330 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
331 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
332 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100333
Julian Hallf5728962021-06-24 09:40:23 +0100334 call_req_set_opstatus(req, psa_status);
335 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100336
Julian Hallf5728962021-06-24 09:40:23 +0100337 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100338}
339
340static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
341{
Julian Hallf5728962021-06-24 09:40:23 +0100342 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
343 struct call_param_buf *req_buf = call_req_get_req_buf(req);
344 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100345
Julian Hallf5728962021-06-24 09:40:23 +0100346 psa_key_id_t id;
347 psa_algorithm_t alg;
348 size_t hash_len = PSA_HASH_MAX_SIZE;
349 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
350 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
351 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100352
Julian Hallf5728962021-06-24 09:40:23 +0100353 if (serializer)
354 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
355 hash_buffer, &hash_len,
356 sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100357
Julian Hallf5728962021-06-24 09:40:23 +0100358 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100359
Julian Hallf5728962021-06-24 09:40:23 +0100360 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100361
Julian Hallf5728962021-06-24 09:40:23 +0100362 psa_status = psa_verify_hash(id, alg,
363 hash_buffer, hash_len,
364 sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100365
Julian Hallf5728962021-06-24 09:40:23 +0100366 call_req_set_opstatus(req, psa_status);
367 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100368
Julian Hallf5728962021-06-24 09:40:23 +0100369 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100370}
371
372static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
373{
Julian Hallf5728962021-06-24 09:40:23 +0100374 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
375 struct call_param_buf *req_buf = call_req_get_req_buf(req);
376 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100377
Julian Hallf5728962021-06-24 09:40:23 +0100378 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100379
Julian Hallf5728962021-06-24 09:40:23 +0100380 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100381
Julian Hallf5728962021-06-24 09:40:23 +0100382 psa_key_id_t id;
383 psa_algorithm_t alg;
384 size_t ciphertext_len = max_param_size;
385 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
386 size_t salt_len = max_param_size;
387 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100388
Julian Hallf5728962021-06-24 09:40:23 +0100389 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100390
Julian Hallf5728962021-06-24 09:40:23 +0100391 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
392 &id, &alg,
393 ciphertext_buffer, &ciphertext_len,
394 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100395
Julian Hallf5728962021-06-24 09:40:23 +0100396 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100397
Julian Hallf5728962021-06-24 09:40:23 +0100398 psa_status_t psa_status;
399 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100400
Julian Hallf5728962021-06-24 09:40:23 +0100401 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100402
Julian Hallf5728962021-06-24 09:40:23 +0100403 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100404
Julian Hallf5728962021-06-24 09:40:23 +0100405 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
406 psa_get_key_type(&attributes),
407 psa_get_key_bits(&attributes),
408 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100409
Julian Hallf5728962021-06-24 09:40:23 +0100410 size_t plaintext_len;
411 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100412
Julian Hallf5728962021-06-24 09:40:23 +0100413 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100414
Julian Hallf5728962021-06-24 09:40:23 +0100415 /* Salt is an optional parameter */
416 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100417
Julian Hallf5728962021-06-24 09:40:23 +0100418 psa_status = psa_asymmetric_decrypt(id, alg,
419 ciphertext_buffer, ciphertext_len,
420 salt, salt_len,
421 plaintext_buffer, max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000422
Julian Hallf5728962021-06-24 09:40:23 +0100423 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000424
Julian Hallf5728962021-06-24 09:40:23 +0100425 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
426 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
427 plaintext_buffer, plaintext_len);
428 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000429
Julian Hallf5728962021-06-24 09:40:23 +0100430 free(plaintext_buffer);
431 }
432 else {
433 /* Failed to allocate ouptput buffer */
434 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
435 }
436 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100437
Julian Hallf5728962021-06-24 09:40:23 +0100438 call_req_set_opstatus(req, psa_status);
439 psa_reset_key_attributes(&attributes);
440 }
441 }
442 else {
443 /* Failed to allocate buffers */
444 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
445 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100446
Julian Hallf5728962021-06-24 09:40:23 +0100447 free(ciphertext_buffer);
448 free(salt_buffer);
449 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100450
Julian Hallf5728962021-06-24 09:40:23 +0100451 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100452}
453
454static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
455{
Julian Hallf5728962021-06-24 09:40:23 +0100456 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
457 struct call_param_buf *req_buf = call_req_get_req_buf(req);
458 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100459
Julian Hallf5728962021-06-24 09:40:23 +0100460 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100461
Julian Hallf5728962021-06-24 09:40:23 +0100462 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100463
Julian Hallf5728962021-06-24 09:40:23 +0100464 psa_key_id_t id;
465 psa_algorithm_t alg;
466 size_t plaintext_len = max_param_size;
467 uint8_t *plaintext_buffer = malloc(plaintext_len);
468 size_t salt_len = max_param_size;
469 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100470
Julian Hallf5728962021-06-24 09:40:23 +0100471 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100472
Julian Hallf5728962021-06-24 09:40:23 +0100473 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
474 &id, &alg,
475 plaintext_buffer, &plaintext_len,
476 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100477
Julian Hallf5728962021-06-24 09:40:23 +0100478 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100479
Julian Hallf5728962021-06-24 09:40:23 +0100480 psa_status_t psa_status;
481 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100482
Julian Hallf5728962021-06-24 09:40:23 +0100483 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100484
Julian Hallf5728962021-06-24 09:40:23 +0100485 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100486
Julian Hallf5728962021-06-24 09:40:23 +0100487 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
488 psa_get_key_type(&attributes),
489 psa_get_key_bits(&attributes),
490 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100491
Julian Hallf5728962021-06-24 09:40:23 +0100492 size_t ciphertext_len;
493 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100494
Julian Hallf5728962021-06-24 09:40:23 +0100495 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100496
Julian Hallf5728962021-06-24 09:40:23 +0100497 /* Salt is an optional parameter */
498 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100499
Julian Hallf5728962021-06-24 09:40:23 +0100500 psa_status = psa_asymmetric_encrypt(id, alg,
501 plaintext_buffer, plaintext_len,
502 salt, salt_len,
503 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000504
Julian Hallf5728962021-06-24 09:40:23 +0100505 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000506
Julian Hallf5728962021-06-24 09:40:23 +0100507 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
508 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
509 ciphertext_buffer, ciphertext_len);
510 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000511
Julian Hallf5728962021-06-24 09:40:23 +0100512 free(ciphertext_buffer);
513 }
514 else {
515 /* Failed to allocate ouptput buffer */
516 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
517 }
518 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100519
Julian Hallf5728962021-06-24 09:40:23 +0100520 call_req_set_opstatus(req, psa_status);
521 psa_reset_key_attributes(&attributes);
522 }
523 }
524 else {
525 /* Failed to allocate buffers */
526 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
527 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100528
Julian Hallf5728962021-06-24 09:40:23 +0100529 free(plaintext_buffer);
530 free(salt_buffer);
531 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100532
Julian Hallf5728962021-06-24 09:40:23 +0100533 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100534}
535
536static rpc_status_t generate_random_handler(void *context, struct call_req* req)
537{
Julian Hallf5728962021-06-24 09:40:23 +0100538 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
539 struct call_param_buf *req_buf = call_req_get_req_buf(req);
540 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100541
Julian Hallf5728962021-06-24 09:40:23 +0100542 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100543
Julian Hallf5728962021-06-24 09:40:23 +0100544 if (serializer)
545 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100546
Julian Hallf5728962021-06-24 09:40:23 +0100547 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100548
Julian Hallf5728962021-06-24 09:40:23 +0100549 psa_status_t psa_status;
550 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100551
Julian Hallf5728962021-06-24 09:40:23 +0100552 if (output_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100553
Julian Hallf5728962021-06-24 09:40:23 +0100554 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100555
Julian Hallf5728962021-06-24 09:40:23 +0100556 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100557
Julian Hallf5728962021-06-24 09:40:23 +0100558 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
559 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
560 output_buffer, output_size);
561 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100562
Julian Hallf5728962021-06-24 09:40:23 +0100563 call_req_set_opstatus(req, psa_status);
564 free(output_buffer);
565 }
566 else {
567 /* Failed to allocate output buffer */
568 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
569 }
570 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100571
Julian Hallf5728962021-06-24 09:40:23 +0100572 return rpc_status;
573}
574
Julian Hall8359a632021-07-08 15:10:30 +0100575static rpc_status_t copy_key_handler(void *context, struct call_req* req)
576{
577 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
578 struct call_param_buf *req_buf = call_req_get_req_buf(req);
579 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
580
581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
582 psa_key_id_t source_key_id;
583
584 if (serializer)
585 rpc_status = serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
586
587 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
588
589 psa_key_id_t target_key_id;
590
591 psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
592
593 if (psa_status == PSA_SUCCESS) {
594
595 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
596 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
597 }
598
599 call_req_set_opstatus(req, psa_status);
600 }
601
602 psa_reset_key_attributes(&attributes);
603
604 return rpc_status;
605}
606
607static rpc_status_t purge_key_handler(void *context, struct call_req* req)
608{
609 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
610 struct call_param_buf *req_buf = call_req_get_req_buf(req);
611 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
612
613 psa_key_id_t id;
614
615 if (serializer)
616 rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
617
618 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
619
620 psa_status_t psa_status = psa_purge_key(id);
621 call_req_set_opstatus(req, psa_status);
622 }
623
624 return rpc_status;
625}
626
627static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req)
628{
629 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
630 struct call_param_buf *req_buf = call_req_get_req_buf(req);
631 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
632
633 psa_key_id_t id;
634
635 if (serializer)
636 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
637
638 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
639
640 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
641
642 psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
643
644 if (psa_status == PSA_SUCCESS) {
645
646 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
647 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf, &attributes);
648 }
649
650 psa_reset_key_attributes(&attributes);
651 call_req_set_opstatus(req, psa_status);
652 }
653
654 return rpc_status;
655}