blob: d0fc7cac24758c3566f00f666cd49e4245734d35 [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 */
Julian Hallc02fffb2020-11-23 18:22:06 +010014static rpc_status_t generate_key_handler(void *context, struct call_req* req);
15static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010016static rpc_status_t export_key_handler(void *context, struct call_req* req);
17static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
18static rpc_status_t import_key_handler(void *context, struct call_req* req);
19static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
20static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
21static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
22static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
23static rpc_status_t generate_random_handler(void *context, struct call_req* req);
Julian Hall8359a632021-07-08 15:10:30 +010024static rpc_status_t copy_key_handler(void *context, struct call_req* req);
25static rpc_status_t purge_key_handler(void *context, struct call_req* req);
26static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010027
28/* Handler mapping table for service */
29static const struct service_handler handler_table[] = {
Julian Hallf5728962021-06-24 09:40:23 +010030 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
31 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
32 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
33 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
34 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
35 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
36 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
37 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
38 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
39 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler},
Julian Hall8359a632021-07-08 15:10:30 +010040 {TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler},
41 {TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler},
42 {TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler},
Julian Hallc02fffb2020-11-23 18:22:06 +010043};
44
Julian Hall9061e6c2021-06-29 14:24:20 +010045struct rpc_interface *crypto_provider_init(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010046{
Julian Hall3e614542021-07-29 11:47:47 +010047 /* Initialise the crypto provider */
Julian Hall9061e6c2021-06-29 14:24:20 +010048 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
49 context->serializers[encoding] = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010050
Julian Hall9061e6c2021-06-29 14:24:20 +010051 service_provider_init(&context->base_provider, context,
Julian Hallf5728962021-06-24 09:40:23 +010052 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
Julian Hallc02fffb2020-11-23 18:22:06 +010053
Julian Hall3e614542021-07-29 11:47:47 +010054 /* Initialise the associated discovery provider */
55 discovery_provider_init(&context->discovery_provider);
56 service_provider_extend(&context->base_provider, &context->discovery_provider.base_provider);
57
Julian Hall9061e6c2021-06-29 14:24:20 +010058 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010059}
60
Julian Hall9061e6c2021-06-29 14:24:20 +010061void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010062{
Julian Hall3e614542021-07-29 11:47:47 +010063 discovery_provider_deinit(&context->discovery_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010064}
65
Julian Hall9061e6c2021-06-29 14:24:20 +010066void crypto_provider_register_serializer(struct crypto_provider *context,
67 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010068{
Julian Hall3e614542021-07-29 11:47:47 +010069 if (encoding < TS_RPC_ENCODING_LIMIT) {
70
Julian Hallf5728962021-06-24 09:40:23 +010071 context->serializers[encoding] = serializer;
Julian Hall3e614542021-07-29 11:47:47 +010072 discovery_provider_register_supported_encoding(&context->discovery_provider, encoding);
73 }
julhal01c3f4e9a2020-12-15 13:39:01 +000074}
75
Julian Hall13e76952021-07-13 12:17:09 +010076void crypto_provider_extend(struct crypto_provider *context,
77 struct service_provider *sub_provider)
78{
79 service_provider_extend(&context->base_provider, sub_provider);
80}
81
julhal01c3f4e9a2020-12-15 13:39:01 +000082static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
Julian Hallf5728962021-06-24 09:40:23 +010083 const struct call_req *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000084{
Julian Hall9061e6c2021-06-29 14:24:20 +010085 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +010086 const struct crypto_provider_serializer* serializer = NULL;
87 unsigned int encoding = call_req_get_encoding(req);
julhal01c3f4e9a2020-12-15 13:39:01 +000088
Julian Hallf5728962021-06-24 09:40:23 +010089 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
julhal01c3f4e9a2020-12-15 13:39:01 +000090
Julian Hallf5728962021-06-24 09:40:23 +010091 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010092}
93
Julian Hallc02fffb2020-11-23 18:22:06 +010094static rpc_status_t generate_key_handler(void *context, struct call_req* req)
95{
Julian Hallf5728962021-06-24 09:40:23 +010096 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
97 struct call_param_buf *req_buf = call_req_get_req_buf(req);
98 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +010099
Julian Hallf5728962021-06-24 09:40:23 +0100100 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100101
Julian Hallf5728962021-06-24 09:40:23 +0100102 if (serializer)
103 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100104
Julian Hallf5728962021-06-24 09:40:23 +0100105 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100106
Julian Hallf5728962021-06-24 09:40:23 +0100107 psa_status_t psa_status;
108 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100109
Julian Hallf5728962021-06-24 09:40:23 +0100110 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100111
Julian Hallf5728962021-06-24 09:40:23 +0100112 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100113
Julian Hallf5728962021-06-24 09:40:23 +0100114 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
115 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
116 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100117
Julian Hallf5728962021-06-24 09:40:23 +0100118 call_req_set_opstatus(req, psa_status);
119 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100120
Julian Hallf5728962021-06-24 09:40:23 +0100121 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100122
Julian Hallf5728962021-06-24 09:40:23 +0100123 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100124}
125
126static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
127{
Julian Hallf5728962021-06-24 09:40:23 +0100128 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
129 struct call_param_buf *req_buf = call_req_get_req_buf(req);
130 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100131
Julian Hallf5728962021-06-24 09:40:23 +0100132 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100133
Julian Hallf5728962021-06-24 09:40:23 +0100134 if (serializer)
135 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100136
Julian Hallf5728962021-06-24 09:40:23 +0100137 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100138
Julian Hallf5728962021-06-24 09:40:23 +0100139 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100140
Julian Hallf5728962021-06-24 09:40:23 +0100141 psa_status = psa_destroy_key(id);
142 call_req_set_opstatus(req, psa_status);
143 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100144
Julian Hallf5728962021-06-24 09:40:23 +0100145 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100146}
147
148static rpc_status_t export_key_handler(void *context, struct call_req* req)
149{
Julian Hallf5728962021-06-24 09:40:23 +0100150 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
151 struct call_param_buf *req_buf = call_req_get_req_buf(req);
152 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100153
Julian Hallf5728962021-06-24 09:40:23 +0100154 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100155
Julian Hallf5728962021-06-24 09:40:23 +0100156 if (serializer)
157 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100158
Julian Hallf5728962021-06-24 09:40:23 +0100159 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100160
Julian Hall464021a2021-07-29 15:20:10 +0100161 size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
162 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100163
Julian Hall464021a2021-07-29 15:20:10 +0100164 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100165
Julian Hall464021a2021-07-29 15:20:10 +0100166 size_t export_size;
167 psa_status_t psa_status = psa_export_key(id, key_buffer,
168 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100169
Julian Hall464021a2021-07-29 15:20:10 +0100170 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100171
Julian Hall464021a2021-07-29 15:20:10 +0100172 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
173 rpc_status = serializer->serialize_export_key_resp(resp_buf,
174 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100175 }
Julian Hallec81a502021-07-12 11:36:37 +0100176
Julian Hall464021a2021-07-29 15:20:10 +0100177 free(key_buffer);
178 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100179 }
Julian Hall464021a2021-07-29 15:20:10 +0100180 else {
181 /* Failed to allocate key buffer */
182 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
183 }
Julian Hallf5728962021-06-24 09:40:23 +0100184 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100185
Julian Hallf5728962021-06-24 09:40:23 +0100186 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100187}
188
189static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
190{
Julian Hallf5728962021-06-24 09:40:23 +0100191 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
192 struct call_param_buf *req_buf = call_req_get_req_buf(req);
193 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100194
Julian Hallf5728962021-06-24 09:40:23 +0100195 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100196
Julian Hallf5728962021-06-24 09:40:23 +0100197 if (serializer)
198 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100199
Julian Hallf5728962021-06-24 09:40:23 +0100200 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100201
Julian Hallec81a502021-07-12 11:36:37 +0100202 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
203 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100204
Julian Hallec81a502021-07-12 11:36:37 +0100205 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100206
Julian Hallec81a502021-07-12 11:36:37 +0100207 size_t export_size;
208 psa_status_t psa_status = psa_export_public_key(id, key_buffer,
209 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100210
Julian Hallec81a502021-07-12 11:36:37 +0100211 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100212
Julian Hallec81a502021-07-12 11:36:37 +0100213 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
214 rpc_status = serializer->serialize_export_public_key_resp(resp_buf,
215 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100216 }
Julian Hallec81a502021-07-12 11:36:37 +0100217
218 free(key_buffer);
219 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100220 }
Julian Hallec81a502021-07-12 11:36:37 +0100221 else {
222 /* Failed to allocate key buffer */
223 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
224 }
Julian Hallf5728962021-06-24 09:40:23 +0100225 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100226
Julian Hallf5728962021-06-24 09:40:23 +0100227 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100228}
229
230static rpc_status_t import_key_handler(void *context, struct call_req* req)
231{
Julian Hallf5728962021-06-24 09:40:23 +0100232 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
233 struct call_param_buf *req_buf = call_req_get_req_buf(req);
234 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100235
Julian Hallf5728962021-06-24 09:40:23 +0100236 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100237
Julian Hallf5728962021-06-24 09:40:23 +0100238 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
239 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100240
Julian Hallf5728962021-06-24 09:40:23 +0100241 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100242
Julian Hallf5728962021-06-24 09:40:23 +0100243 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallec81a502021-07-12 11:36:37 +0100244 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes,
245 key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100246
Julian Hallf5728962021-06-24 09:40:23 +0100247 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100248
Julian Hallf5728962021-06-24 09:40:23 +0100249 psa_status_t psa_status;
250 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100251
Julian Hallf5728962021-06-24 09:40:23 +0100252 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100253
Julian Hallf5728962021-06-24 09:40:23 +0100254 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000255
Julian Hallf5728962021-06-24 09:40:23 +0100256 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
257 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
258 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000259
Julian Hallf5728962021-06-24 09:40:23 +0100260 call_req_set_opstatus(req, psa_status);
261 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100262
Julian Hallf5728962021-06-24 09:40:23 +0100263 psa_reset_key_attributes(&attributes);
264 free(key_buffer);
265 }
266 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100267
Julian Hallf5728962021-06-24 09:40:23 +0100268 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
269 }
270 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100271
Julian Hallf5728962021-06-24 09:40:23 +0100272 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100273}
274
275static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
276{
Julian Hallf5728962021-06-24 09:40:23 +0100277 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
278 struct call_param_buf *req_buf = call_req_get_req_buf(req);
279 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100280
Julian Hallf5728962021-06-24 09:40:23 +0100281 psa_key_id_t id;
282 psa_algorithm_t alg;
283 size_t hash_len = PSA_HASH_MAX_SIZE;
284 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100285
Julian Hallf5728962021-06-24 09:40:23 +0100286 if (serializer)
287 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100288
Julian Hallf5728962021-06-24 09:40:23 +0100289 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100290
Julian Hallf5728962021-06-24 09:40:23 +0100291 psa_status_t psa_status;
292 size_t sig_len;
293 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100294
Julian Hallf5728962021-06-24 09:40:23 +0100295 psa_status = psa_sign_hash(id, alg,
296 hash_buffer, hash_len,
297 sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100298
Julian Hallf5728962021-06-24 09:40:23 +0100299 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100300
Julian Hallf5728962021-06-24 09:40:23 +0100301 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
302 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
303 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100304
Julian Hallf5728962021-06-24 09:40:23 +0100305 call_req_set_opstatus(req, psa_status);
306 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100307
Julian Hallf5728962021-06-24 09:40:23 +0100308 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100309}
310
311static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
312{
Julian Hallf5728962021-06-24 09:40:23 +0100313 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
314 struct call_param_buf *req_buf = call_req_get_req_buf(req);
315 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100316
Julian Hallf5728962021-06-24 09:40:23 +0100317 psa_key_id_t id;
318 psa_algorithm_t alg;
319 size_t hash_len = PSA_HASH_MAX_SIZE;
320 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
321 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
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 if (serializer)
325 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
326 hash_buffer, &hash_len,
327 sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100328
Julian Hallf5728962021-06-24 09:40:23 +0100329 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100330
Julian Hallf5728962021-06-24 09:40:23 +0100331 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100332
Julian Hallf5728962021-06-24 09:40:23 +0100333 psa_status = psa_verify_hash(id, alg,
334 hash_buffer, hash_len,
335 sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100336
Julian Hallf5728962021-06-24 09:40:23 +0100337 call_req_set_opstatus(req, psa_status);
338 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100339
Julian Hallf5728962021-06-24 09:40:23 +0100340 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100341}
342
343static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
344{
Julian Hallf5728962021-06-24 09:40:23 +0100345 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
346 struct call_param_buf *req_buf = call_req_get_req_buf(req);
347 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100348
Julian Hallf5728962021-06-24 09:40:23 +0100349 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100350
Julian Hallf5728962021-06-24 09:40:23 +0100351 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100352
Julian Hallf5728962021-06-24 09:40:23 +0100353 psa_key_id_t id;
354 psa_algorithm_t alg;
355 size_t ciphertext_len = max_param_size;
356 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
357 size_t salt_len = max_param_size;
358 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100359
Julian Hallf5728962021-06-24 09:40:23 +0100360 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100361
Julian Hallf5728962021-06-24 09:40:23 +0100362 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
363 &id, &alg,
364 ciphertext_buffer, &ciphertext_len,
365 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100366
Julian Hallf5728962021-06-24 09:40:23 +0100367 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100368
Julian Hallf5728962021-06-24 09:40:23 +0100369 psa_status_t psa_status;
370 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100371
Julian Hallf5728962021-06-24 09:40:23 +0100372 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100373
Julian Hallf5728962021-06-24 09:40:23 +0100374 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100375
Julian Hallf5728962021-06-24 09:40:23 +0100376 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
377 psa_get_key_type(&attributes),
378 psa_get_key_bits(&attributes),
379 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100380
Julian Hallf5728962021-06-24 09:40:23 +0100381 size_t plaintext_len;
382 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100383
Julian Hallf5728962021-06-24 09:40:23 +0100384 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100385
Julian Hallf5728962021-06-24 09:40:23 +0100386 /* Salt is an optional parameter */
387 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100388
Julian Hallf5728962021-06-24 09:40:23 +0100389 psa_status = psa_asymmetric_decrypt(id, alg,
390 ciphertext_buffer, ciphertext_len,
391 salt, salt_len,
392 plaintext_buffer, max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000393
Julian Hallf5728962021-06-24 09:40:23 +0100394 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000395
Julian Hallf5728962021-06-24 09:40:23 +0100396 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
397 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
398 plaintext_buffer, plaintext_len);
399 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000400
Julian Hallf5728962021-06-24 09:40:23 +0100401 free(plaintext_buffer);
402 }
403 else {
404 /* Failed to allocate ouptput buffer */
405 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
406 }
407 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100408
Julian Hallf5728962021-06-24 09:40:23 +0100409 call_req_set_opstatus(req, psa_status);
410 psa_reset_key_attributes(&attributes);
411 }
412 }
413 else {
414 /* Failed to allocate buffers */
415 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
416 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100417
Julian Hallf5728962021-06-24 09:40:23 +0100418 free(ciphertext_buffer);
419 free(salt_buffer);
420 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100421
Julian Hallf5728962021-06-24 09:40:23 +0100422 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100423}
424
425static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
426{
Julian Hallf5728962021-06-24 09:40:23 +0100427 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
428 struct call_param_buf *req_buf = call_req_get_req_buf(req);
429 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100430
Julian Hallf5728962021-06-24 09:40:23 +0100431 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100432
Julian Hallf5728962021-06-24 09:40:23 +0100433 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100434
Julian Hallf5728962021-06-24 09:40:23 +0100435 psa_key_id_t id;
436 psa_algorithm_t alg;
437 size_t plaintext_len = max_param_size;
438 uint8_t *plaintext_buffer = malloc(plaintext_len);
439 size_t salt_len = max_param_size;
440 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100441
Julian Hallf5728962021-06-24 09:40:23 +0100442 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100443
Julian Hallf5728962021-06-24 09:40:23 +0100444 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
445 &id, &alg,
446 plaintext_buffer, &plaintext_len,
447 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100448
Julian Hallf5728962021-06-24 09:40:23 +0100449 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100450
Julian Hallf5728962021-06-24 09:40:23 +0100451 psa_status_t psa_status;
452 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100453
Julian Hallf5728962021-06-24 09:40:23 +0100454 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100455
Julian Hallf5728962021-06-24 09:40:23 +0100456 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100457
Julian Hallf5728962021-06-24 09:40:23 +0100458 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
459 psa_get_key_type(&attributes),
460 psa_get_key_bits(&attributes),
461 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100462
Julian Hallf5728962021-06-24 09:40:23 +0100463 size_t ciphertext_len;
464 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100465
Julian Hallf5728962021-06-24 09:40:23 +0100466 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100467
Julian Hallf5728962021-06-24 09:40:23 +0100468 /* Salt is an optional parameter */
469 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100470
Julian Hallf5728962021-06-24 09:40:23 +0100471 psa_status = psa_asymmetric_encrypt(id, alg,
472 plaintext_buffer, plaintext_len,
473 salt, salt_len,
474 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000475
Julian Hallf5728962021-06-24 09:40:23 +0100476 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000477
Julian Hallf5728962021-06-24 09:40:23 +0100478 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
479 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
480 ciphertext_buffer, ciphertext_len);
481 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000482
Julian Hallf5728962021-06-24 09:40:23 +0100483 free(ciphertext_buffer);
484 }
485 else {
486 /* Failed to allocate ouptput buffer */
487 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
488 }
489 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100490
Julian Hallf5728962021-06-24 09:40:23 +0100491 call_req_set_opstatus(req, psa_status);
492 psa_reset_key_attributes(&attributes);
493 }
494 }
495 else {
496 /* Failed to allocate buffers */
497 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
498 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100499
Julian Hallf5728962021-06-24 09:40:23 +0100500 free(plaintext_buffer);
501 free(salt_buffer);
502 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100503
Julian Hallf5728962021-06-24 09:40:23 +0100504 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100505}
506
507static rpc_status_t generate_random_handler(void *context, struct call_req* req)
508{
Julian Hallf5728962021-06-24 09:40:23 +0100509 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
510 struct call_param_buf *req_buf = call_req_get_req_buf(req);
511 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100512
Julian Hallf5728962021-06-24 09:40:23 +0100513 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100514
Julian Hallf5728962021-06-24 09:40:23 +0100515 if (serializer)
516 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100517
Julian Hallf5728962021-06-24 09:40:23 +0100518 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100519
Julian Hallf5728962021-06-24 09:40:23 +0100520 psa_status_t psa_status;
521 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100522
Julian Hallf5728962021-06-24 09:40:23 +0100523 if (output_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100524
Julian Hallf5728962021-06-24 09:40:23 +0100525 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100526
Julian Hallf5728962021-06-24 09:40:23 +0100527 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100528
Julian Hallf5728962021-06-24 09:40:23 +0100529 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
530 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
531 output_buffer, output_size);
532 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100533
Julian Hallf5728962021-06-24 09:40:23 +0100534 call_req_set_opstatus(req, psa_status);
535 free(output_buffer);
536 }
537 else {
538 /* Failed to allocate output buffer */
539 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
540 }
541 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100542
Julian Hallf5728962021-06-24 09:40:23 +0100543 return rpc_status;
544}
545
Julian Hall8359a632021-07-08 15:10:30 +0100546static rpc_status_t copy_key_handler(void *context, struct call_req* req)
547{
548 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
549 struct call_param_buf *req_buf = call_req_get_req_buf(req);
550 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
551
552 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
553 psa_key_id_t source_key_id;
554
555 if (serializer)
556 rpc_status = serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
557
558 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
559
560 psa_key_id_t target_key_id;
561
562 psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
563
564 if (psa_status == PSA_SUCCESS) {
565
566 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
567 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
568 }
569
570 call_req_set_opstatus(req, psa_status);
571 }
572
573 psa_reset_key_attributes(&attributes);
574
575 return rpc_status;
576}
577
578static rpc_status_t purge_key_handler(void *context, struct call_req* req)
579{
580 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
581 struct call_param_buf *req_buf = call_req_get_req_buf(req);
582 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
583
584 psa_key_id_t id;
585
586 if (serializer)
587 rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
588
589 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
590
591 psa_status_t psa_status = psa_purge_key(id);
592 call_req_set_opstatus(req, psa_status);
593 }
594
595 return rpc_status;
596}
597
598static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req)
599{
600 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
601 struct call_param_buf *req_buf = call_req_get_req_buf(req);
602 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
603
604 psa_key_id_t id;
605
606 if (serializer)
607 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
608
609 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
610
611 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
612
613 psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
614
615 if (psa_status == PSA_SUCCESS) {
616
617 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
618 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf, &attributes);
619 }
620
621 psa_reset_key_attributes(&attributes);
622 call_req_set_opstatus(req, psa_status);
623 }
624
625 return rpc_status;
626}