blob: ea9cce685dc27511bb26c1dac400ba9b26c2f578 [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 Hallf5728962021-06-24 09:40:23 +0100161 psa_status_t psa_status;
162 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100163
Julian Hallf5728962021-06-24 09:40:23 +0100164 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100165
Julian Hallf5728962021-06-24 09:40:23 +0100166 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
Julian Hallf5728962021-06-24 09:40:23 +0100168 size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
169 psa_get_key_type(&attributes),
170 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100171
Julian Hallec81a502021-07-12 11:36:37 +0100172 if (max_export_size) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100173
Julian Hallec81a502021-07-12 11:36:37 +0100174 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100175
Julian Hallec81a502021-07-12 11:36:37 +0100176 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100177
Julian Hallec81a502021-07-12 11:36:37 +0100178 size_t export_size;
179 psa_status_t psa_status = psa_export_key(id, key_buffer,
180 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100181
Julian Hallec81a502021-07-12 11:36:37 +0100182 if (psa_status == PSA_SUCCESS) {
183
184 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
185 rpc_status = serializer->serialize_export_key_resp(resp_buf,
186 key_buffer, export_size);
187 }
188
189 free(key_buffer);
Julian Hallf5728962021-06-24 09:40:23 +0100190 }
Julian Hallec81a502021-07-12 11:36:37 +0100191 else {
192 /* Failed to allocate key buffer */
193 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
194 }
Julian Hallf5728962021-06-24 09:40:23 +0100195 }
196 else {
Julian Hallec81a502021-07-12 11:36:37 +0100197
198 /* No sensible export size was returned so
199 * key attributes must be in an invalid state.
200 */
201 psa_status = PSA_ERROR_GENERIC_ERROR;
Julian Hallf5728962021-06-24 09:40:23 +0100202 }
203 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100204
Julian Hallf5728962021-06-24 09:40:23 +0100205 call_req_set_opstatus(req, psa_status);
206 psa_reset_key_attributes(&attributes);
207 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100208
Julian Hallf5728962021-06-24 09:40:23 +0100209 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100210}
211
212static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
213{
Julian Hallf5728962021-06-24 09:40:23 +0100214 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
215 struct call_param_buf *req_buf = call_req_get_req_buf(req);
216 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100217
Julian Hallf5728962021-06-24 09:40:23 +0100218 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100219
Julian Hallf5728962021-06-24 09:40:23 +0100220 if (serializer)
221 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100222
Julian Hallf5728962021-06-24 09:40:23 +0100223 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100224
Julian Hallec81a502021-07-12 11:36:37 +0100225 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
226 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100227
Julian Hallec81a502021-07-12 11:36:37 +0100228 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100229
Julian Hallec81a502021-07-12 11:36:37 +0100230 size_t export_size;
231 psa_status_t psa_status = psa_export_public_key(id, key_buffer,
232 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100233
Julian Hallec81a502021-07-12 11:36:37 +0100234 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100235
Julian Hallec81a502021-07-12 11:36:37 +0100236 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
237 rpc_status = serializer->serialize_export_public_key_resp(resp_buf,
238 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100239 }
Julian Hallec81a502021-07-12 11:36:37 +0100240
241 free(key_buffer);
242 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100243 }
Julian Hallec81a502021-07-12 11:36:37 +0100244 else {
245 /* Failed to allocate key buffer */
246 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
247 }
Julian Hallf5728962021-06-24 09:40:23 +0100248 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100249
Julian Hallf5728962021-06-24 09:40:23 +0100250 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100251}
252
253static rpc_status_t import_key_handler(void *context, struct call_req* req)
254{
Julian Hallf5728962021-06-24 09:40:23 +0100255 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
256 struct call_param_buf *req_buf = call_req_get_req_buf(req);
257 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100258
Julian Hallf5728962021-06-24 09:40:23 +0100259 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100260
Julian Hallf5728962021-06-24 09:40:23 +0100261 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
262 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100263
Julian Hallf5728962021-06-24 09:40:23 +0100264 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100265
Julian Hallf5728962021-06-24 09:40:23 +0100266 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallec81a502021-07-12 11:36:37 +0100267 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes,
268 key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100269
Julian Hallf5728962021-06-24 09:40:23 +0100270 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100271
Julian Hallf5728962021-06-24 09:40:23 +0100272 psa_status_t psa_status;
273 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100274
Julian Hallf5728962021-06-24 09:40:23 +0100275 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100276
Julian Hallf5728962021-06-24 09:40:23 +0100277 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000278
Julian Hallf5728962021-06-24 09:40:23 +0100279 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
280 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
281 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000282
Julian Hallf5728962021-06-24 09:40:23 +0100283 call_req_set_opstatus(req, psa_status);
284 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100285
Julian Hallf5728962021-06-24 09:40:23 +0100286 psa_reset_key_attributes(&attributes);
287 free(key_buffer);
288 }
289 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100290
Julian Hallf5728962021-06-24 09:40:23 +0100291 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
292 }
293 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100294
Julian Hallf5728962021-06-24 09:40:23 +0100295 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100296}
297
298static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
299{
Julian Hallf5728962021-06-24 09:40:23 +0100300 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
301 struct call_param_buf *req_buf = call_req_get_req_buf(req);
302 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100303
Julian Hallf5728962021-06-24 09:40:23 +0100304 psa_key_id_t id;
305 psa_algorithm_t alg;
306 size_t hash_len = PSA_HASH_MAX_SIZE;
307 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100308
Julian Hallf5728962021-06-24 09:40:23 +0100309 if (serializer)
310 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100311
Julian Hallf5728962021-06-24 09:40:23 +0100312 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100313
Julian Hallf5728962021-06-24 09:40:23 +0100314 psa_status_t psa_status;
315 size_t sig_len;
316 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100317
Julian Hallf5728962021-06-24 09:40:23 +0100318 psa_status = psa_sign_hash(id, alg,
319 hash_buffer, hash_len,
320 sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100321
Julian Hallf5728962021-06-24 09:40:23 +0100322 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100323
Julian Hallf5728962021-06-24 09:40:23 +0100324 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
325 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
326 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100327
Julian Hallf5728962021-06-24 09:40:23 +0100328 call_req_set_opstatus(req, psa_status);
329 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100330
Julian Hallf5728962021-06-24 09:40:23 +0100331 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100332}
333
334static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
335{
Julian Hallf5728962021-06-24 09:40:23 +0100336 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
337 struct call_param_buf *req_buf = call_req_get_req_buf(req);
338 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100339
Julian Hallf5728962021-06-24 09:40:23 +0100340 psa_key_id_t id;
341 psa_algorithm_t alg;
342 size_t hash_len = PSA_HASH_MAX_SIZE;
343 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
344 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
345 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100346
Julian Hallf5728962021-06-24 09:40:23 +0100347 if (serializer)
348 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
349 hash_buffer, &hash_len,
350 sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100351
Julian Hallf5728962021-06-24 09:40:23 +0100352 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100353
Julian Hallf5728962021-06-24 09:40:23 +0100354 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100355
Julian Hallf5728962021-06-24 09:40:23 +0100356 psa_status = psa_verify_hash(id, alg,
357 hash_buffer, hash_len,
358 sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100359
Julian Hallf5728962021-06-24 09:40:23 +0100360 call_req_set_opstatus(req, psa_status);
361 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100362
Julian Hallf5728962021-06-24 09:40:23 +0100363 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100364}
365
366static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
367{
Julian Hallf5728962021-06-24 09:40:23 +0100368 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
369 struct call_param_buf *req_buf = call_req_get_req_buf(req);
370 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100371
Julian Hallf5728962021-06-24 09:40:23 +0100372 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100373
Julian Hallf5728962021-06-24 09:40:23 +0100374 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100375
Julian Hallf5728962021-06-24 09:40:23 +0100376 psa_key_id_t id;
377 psa_algorithm_t alg;
378 size_t ciphertext_len = max_param_size;
379 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
380 size_t salt_len = max_param_size;
381 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100382
Julian Hallf5728962021-06-24 09:40:23 +0100383 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100384
Julian Hallf5728962021-06-24 09:40:23 +0100385 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
386 &id, &alg,
387 ciphertext_buffer, &ciphertext_len,
388 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100389
Julian Hallf5728962021-06-24 09:40:23 +0100390 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100391
Julian Hallf5728962021-06-24 09:40:23 +0100392 psa_status_t psa_status;
393 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100394
Julian Hallf5728962021-06-24 09:40:23 +0100395 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100396
Julian Hallf5728962021-06-24 09:40:23 +0100397 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100398
Julian Hallf5728962021-06-24 09:40:23 +0100399 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
400 psa_get_key_type(&attributes),
401 psa_get_key_bits(&attributes),
402 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100403
Julian Hallf5728962021-06-24 09:40:23 +0100404 size_t plaintext_len;
405 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100406
Julian Hallf5728962021-06-24 09:40:23 +0100407 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100408
Julian Hallf5728962021-06-24 09:40:23 +0100409 /* Salt is an optional parameter */
410 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100411
Julian Hallf5728962021-06-24 09:40:23 +0100412 psa_status = psa_asymmetric_decrypt(id, alg,
413 ciphertext_buffer, ciphertext_len,
414 salt, salt_len,
415 plaintext_buffer, max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000416
Julian Hallf5728962021-06-24 09:40:23 +0100417 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000418
Julian Hallf5728962021-06-24 09:40:23 +0100419 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
420 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
421 plaintext_buffer, plaintext_len);
422 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000423
Julian Hallf5728962021-06-24 09:40:23 +0100424 free(plaintext_buffer);
425 }
426 else {
427 /* Failed to allocate ouptput buffer */
428 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
429 }
430 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100431
Julian Hallf5728962021-06-24 09:40:23 +0100432 call_req_set_opstatus(req, psa_status);
433 psa_reset_key_attributes(&attributes);
434 }
435 }
436 else {
437 /* Failed to allocate buffers */
438 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
439 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100440
Julian Hallf5728962021-06-24 09:40:23 +0100441 free(ciphertext_buffer);
442 free(salt_buffer);
443 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100444
Julian Hallf5728962021-06-24 09:40:23 +0100445 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100446}
447
448static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
449{
Julian Hallf5728962021-06-24 09:40:23 +0100450 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
451 struct call_param_buf *req_buf = call_req_get_req_buf(req);
452 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100453
Julian Hallf5728962021-06-24 09:40:23 +0100454 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100455
Julian Hallf5728962021-06-24 09:40:23 +0100456 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100457
Julian Hallf5728962021-06-24 09:40:23 +0100458 psa_key_id_t id;
459 psa_algorithm_t alg;
460 size_t plaintext_len = max_param_size;
461 uint8_t *plaintext_buffer = malloc(plaintext_len);
462 size_t salt_len = max_param_size;
463 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100464
Julian Hallf5728962021-06-24 09:40:23 +0100465 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100466
Julian Hallf5728962021-06-24 09:40:23 +0100467 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
468 &id, &alg,
469 plaintext_buffer, &plaintext_len,
470 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100471
Julian Hallf5728962021-06-24 09:40:23 +0100472 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100473
Julian Hallf5728962021-06-24 09:40:23 +0100474 psa_status_t psa_status;
475 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100476
Julian Hallf5728962021-06-24 09:40:23 +0100477 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100478
Julian Hallf5728962021-06-24 09:40:23 +0100479 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100480
Julian Hallf5728962021-06-24 09:40:23 +0100481 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
482 psa_get_key_type(&attributes),
483 psa_get_key_bits(&attributes),
484 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100485
Julian Hallf5728962021-06-24 09:40:23 +0100486 size_t ciphertext_len;
487 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100488
Julian Hallf5728962021-06-24 09:40:23 +0100489 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100490
Julian Hallf5728962021-06-24 09:40:23 +0100491 /* Salt is an optional parameter */
492 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100493
Julian Hallf5728962021-06-24 09:40:23 +0100494 psa_status = psa_asymmetric_encrypt(id, alg,
495 plaintext_buffer, plaintext_len,
496 salt, salt_len,
497 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000498
Julian Hallf5728962021-06-24 09:40:23 +0100499 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000500
Julian Hallf5728962021-06-24 09:40:23 +0100501 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
502 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
503 ciphertext_buffer, ciphertext_len);
504 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000505
Julian Hallf5728962021-06-24 09:40:23 +0100506 free(ciphertext_buffer);
507 }
508 else {
509 /* Failed to allocate ouptput buffer */
510 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
511 }
512 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100513
Julian Hallf5728962021-06-24 09:40:23 +0100514 call_req_set_opstatus(req, psa_status);
515 psa_reset_key_attributes(&attributes);
516 }
517 }
518 else {
519 /* Failed to allocate buffers */
520 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
521 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100522
Julian Hallf5728962021-06-24 09:40:23 +0100523 free(plaintext_buffer);
524 free(salt_buffer);
525 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100526
Julian Hallf5728962021-06-24 09:40:23 +0100527 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100528}
529
530static rpc_status_t generate_random_handler(void *context, struct call_req* req)
531{
Julian Hallf5728962021-06-24 09:40:23 +0100532 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
533 struct call_param_buf *req_buf = call_req_get_req_buf(req);
534 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100535
Julian Hallf5728962021-06-24 09:40:23 +0100536 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100537
Julian Hallf5728962021-06-24 09:40:23 +0100538 if (serializer)
539 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100540
Julian Hallf5728962021-06-24 09:40:23 +0100541 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100542
Julian Hallf5728962021-06-24 09:40:23 +0100543 psa_status_t psa_status;
544 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100545
Julian Hallf5728962021-06-24 09:40:23 +0100546 if (output_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100547
Julian Hallf5728962021-06-24 09:40:23 +0100548 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100549
Julian Hallf5728962021-06-24 09:40:23 +0100550 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100551
Julian Hallf5728962021-06-24 09:40:23 +0100552 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
553 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
554 output_buffer, output_size);
555 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100556
Julian Hallf5728962021-06-24 09:40:23 +0100557 call_req_set_opstatus(req, psa_status);
558 free(output_buffer);
559 }
560 else {
561 /* Failed to allocate output buffer */
562 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
563 }
564 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100565
Julian Hallf5728962021-06-24 09:40:23 +0100566 return rpc_status;
567}
568
Julian Hall8359a632021-07-08 15:10:30 +0100569static rpc_status_t copy_key_handler(void *context, struct call_req* req)
570{
571 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
572 struct call_param_buf *req_buf = call_req_get_req_buf(req);
573 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
574
575 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
576 psa_key_id_t source_key_id;
577
578 if (serializer)
579 rpc_status = serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
580
581 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
582
583 psa_key_id_t target_key_id;
584
585 psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
586
587 if (psa_status == PSA_SUCCESS) {
588
589 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
590 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
591 }
592
593 call_req_set_opstatus(req, psa_status);
594 }
595
596 psa_reset_key_attributes(&attributes);
597
598 return rpc_status;
599}
600
601static rpc_status_t purge_key_handler(void *context, struct call_req* req)
602{
603 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
604 struct call_param_buf *req_buf = call_req_get_req_buf(req);
605 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
606
607 psa_key_id_t id;
608
609 if (serializer)
610 rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
611
612 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
613
614 psa_status_t psa_status = psa_purge_key(id);
615 call_req_set_opstatus(req, psa_status);
616 }
617
618 return rpc_status;
619}
620
621static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req)
622{
623 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
624 struct call_param_buf *req_buf = call_req_get_req_buf(req);
625 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
626
627 psa_key_id_t id;
628
629 if (serializer)
630 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
631
632 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
633
634 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
635
636 psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
637
638 if (psa_status == PSA_SUCCESS) {
639
640 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
641 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf, &attributes);
642 }
643
644 psa_reset_key_attributes(&attributes);
645 call_req_set_opstatus(req, psa_status);
646 }
647
648 return rpc_status;
649}