blob: 67a5b340d3d1d4cf50bf475cedf032522552b616 [file] [log] [blame]
Julian Hallc02fffb2020-11-23 18:22:06 +01001/*
Julian Hall0562ae02022-02-11 14:08:13 +00002 * Copyright (c) 2020-2022, 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);
Julian Hall0562ae02022-02-11 14:08:13 +000019static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req);
20static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010021static 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},
Julian Hall0562ae02022-02-11 14:08:13 +000035 {TS_CRYPTO_OPCODE_SIGN_HASH, asymmetric_sign_handler},
36 {TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_handler},
Julian Hallf5728962021-06-24 09:40:23 +010037 {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 Hall0562ae02022-02-11 14:08:13 +000043 {TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler},
44 {TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_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 Hall3e614542021-07-29 11:47:47 +010049 /* Initialise the crypto provider */
Julian Hall9061e6c2021-06-29 14:24:20 +010050 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
51 context->serializers[encoding] = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010052
Julian Hall9061e6c2021-06-29 14:24:20 +010053 service_provider_init(&context->base_provider, context,
Julian Hallf5728962021-06-24 09:40:23 +010054 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
Julian Hallc02fffb2020-11-23 18:22:06 +010055
Julian Hall3e614542021-07-29 11:47:47 +010056 /* Initialise the associated discovery provider */
57 discovery_provider_init(&context->discovery_provider);
58 service_provider_extend(&context->base_provider, &context->discovery_provider.base_provider);
59
Julian Hall9061e6c2021-06-29 14:24:20 +010060 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010061}
62
Julian Hall9061e6c2021-06-29 14:24:20 +010063void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010064{
Julian Hall3e614542021-07-29 11:47:47 +010065 discovery_provider_deinit(&context->discovery_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010066}
67
Julian Hall9061e6c2021-06-29 14:24:20 +010068void crypto_provider_register_serializer(struct crypto_provider *context,
69 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010070{
Julian Hall3e614542021-07-29 11:47:47 +010071 if (encoding < TS_RPC_ENCODING_LIMIT) {
72
Julian Hallf5728962021-06-24 09:40:23 +010073 context->serializers[encoding] = serializer;
Julian Hall3e614542021-07-29 11:47:47 +010074 discovery_provider_register_supported_encoding(&context->discovery_provider, encoding);
75 }
julhal01c3f4e9a2020-12-15 13:39:01 +000076}
77
Julian Hall13e76952021-07-13 12:17:09 +010078void crypto_provider_extend(struct crypto_provider *context,
79 struct service_provider *sub_provider)
80{
81 service_provider_extend(&context->base_provider, sub_provider);
82}
83
julhal01c3f4e9a2020-12-15 13:39:01 +000084static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
Julian Hallf5728962021-06-24 09:40:23 +010085 const struct call_req *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000086{
Julian Hall9061e6c2021-06-29 14:24:20 +010087 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +010088 const struct crypto_provider_serializer* serializer = NULL;
89 unsigned int encoding = call_req_get_encoding(req);
julhal01c3f4e9a2020-12-15 13:39:01 +000090
Julian Hallf5728962021-06-24 09:40:23 +010091 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
julhal01c3f4e9a2020-12-15 13:39:01 +000092
Julian Hallf5728962021-06-24 09:40:23 +010093 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010094}
95
Julian Hallc02fffb2020-11-23 18:22:06 +010096static rpc_status_t generate_key_handler(void *context, struct call_req* req)
97{
Julian Hallf5728962021-06-24 09:40:23 +010098 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
99 struct call_param_buf *req_buf = call_req_get_req_buf(req);
100 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100101
Julian Hallf5728962021-06-24 09:40:23 +0100102 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100103
Julian Hallf5728962021-06-24 09:40:23 +0100104 if (serializer)
105 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100106
Julian Hallf5728962021-06-24 09:40:23 +0100107 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100108
Julian Hallf5728962021-06-24 09:40:23 +0100109 psa_status_t psa_status;
110 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100111
Julian Hallf5728962021-06-24 09:40:23 +0100112 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100113
Julian Hallf5728962021-06-24 09:40:23 +0100114 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100115
Julian Hallf5728962021-06-24 09:40:23 +0100116 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
117 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
118 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100119
Julian Hallf5728962021-06-24 09:40:23 +0100120 call_req_set_opstatus(req, psa_status);
121 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100122
Julian Hallf5728962021-06-24 09:40:23 +0100123 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100124
Julian Hallf5728962021-06-24 09:40:23 +0100125 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100126}
127
128static rpc_status_t destroy_key_handler(void *context, struct call_req* req)
129{
Julian Hallf5728962021-06-24 09:40:23 +0100130 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
131 struct call_param_buf *req_buf = call_req_get_req_buf(req);
132 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100133
Julian Hallf5728962021-06-24 09:40:23 +0100134 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100135
Julian Hallf5728962021-06-24 09:40:23 +0100136 if (serializer)
137 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100138
Julian Hallf5728962021-06-24 09:40:23 +0100139 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100140
Julian Hallf5728962021-06-24 09:40:23 +0100141 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100142
Julian Hallf5728962021-06-24 09:40:23 +0100143 psa_status = psa_destroy_key(id);
144 call_req_set_opstatus(req, psa_status);
145 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100146
Julian Hallf5728962021-06-24 09:40:23 +0100147 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100148}
149
150static rpc_status_t export_key_handler(void *context, struct call_req* req)
151{
Julian Hallf5728962021-06-24 09:40:23 +0100152 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
153 struct call_param_buf *req_buf = call_req_get_req_buf(req);
154 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100155
Julian Hallf5728962021-06-24 09:40:23 +0100156 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100157
Julian Hallf5728962021-06-24 09:40:23 +0100158 if (serializer)
159 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100160
Julian Hallf5728962021-06-24 09:40:23 +0100161 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100162
Julian Hall464021a2021-07-29 15:20:10 +0100163 size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
164 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100165
Julian Hall464021a2021-07-29 15:20:10 +0100166 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
Julian Hall464021a2021-07-29 15:20:10 +0100168 size_t export_size;
169 psa_status_t psa_status = psa_export_key(id, key_buffer,
170 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100171
Julian Hall464021a2021-07-29 15:20:10 +0100172 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100173
Julian Hall464021a2021-07-29 15:20:10 +0100174 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
175 rpc_status = serializer->serialize_export_key_resp(resp_buf,
176 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100177 }
Julian Hallec81a502021-07-12 11:36:37 +0100178
Julian Hall464021a2021-07-29 15:20:10 +0100179 free(key_buffer);
180 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100181 }
Julian Hall464021a2021-07-29 15:20:10 +0100182 else {
183 /* Failed to allocate key buffer */
184 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
185 }
Julian Hallf5728962021-06-24 09:40:23 +0100186 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100187
Julian Hallf5728962021-06-24 09:40:23 +0100188 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100189}
190
191static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
192{
Julian Hallf5728962021-06-24 09:40:23 +0100193 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
194 struct call_param_buf *req_buf = call_req_get_req_buf(req);
195 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100196
Julian Hallf5728962021-06-24 09:40:23 +0100197 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100198
Julian Hallf5728962021-06-24 09:40:23 +0100199 if (serializer)
200 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100201
Julian Hallf5728962021-06-24 09:40:23 +0100202 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100203
Julian Hallec81a502021-07-12 11:36:37 +0100204 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
205 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100206
Julian Hallec81a502021-07-12 11:36:37 +0100207 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100208
Julian Hallec81a502021-07-12 11:36:37 +0100209 size_t export_size;
210 psa_status_t psa_status = psa_export_public_key(id, key_buffer,
211 max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100212
Julian Hallec81a502021-07-12 11:36:37 +0100213 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100214
Julian Hallec81a502021-07-12 11:36:37 +0100215 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
216 rpc_status = serializer->serialize_export_public_key_resp(resp_buf,
217 key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100218 }
Julian Hallec81a502021-07-12 11:36:37 +0100219
220 free(key_buffer);
221 call_req_set_opstatus(req, psa_status);
Julian Hallf5728962021-06-24 09:40:23 +0100222 }
Julian Hallec81a502021-07-12 11:36:37 +0100223 else {
224 /* Failed to allocate key buffer */
225 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
226 }
Julian Hallf5728962021-06-24 09:40:23 +0100227 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100228
Julian Hallf5728962021-06-24 09:40:23 +0100229 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100230}
231
232static rpc_status_t import_key_handler(void *context, struct call_req* req)
233{
Julian Hallf5728962021-06-24 09:40:23 +0100234 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
235 struct call_param_buf *req_buf = call_req_get_req_buf(req);
236 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100237
Julian Hallf5728962021-06-24 09:40:23 +0100238 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100239
Julian Hallf5728962021-06-24 09:40:23 +0100240 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
241 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100242
Julian Hallf5728962021-06-24 09:40:23 +0100243 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100244
Julian Hallf5728962021-06-24 09:40:23 +0100245 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallec81a502021-07-12 11:36:37 +0100246 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes,
247 key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100248
Julian Hallf5728962021-06-24 09:40:23 +0100249 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100250
Julian Hallf5728962021-06-24 09:40:23 +0100251 psa_status_t psa_status;
252 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100253
Julian Hallf5728962021-06-24 09:40:23 +0100254 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100255
Julian Hallf5728962021-06-24 09:40:23 +0100256 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000257
Julian Hallf5728962021-06-24 09:40:23 +0100258 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
259 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
260 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000261
Julian Hallf5728962021-06-24 09:40:23 +0100262 call_req_set_opstatus(req, psa_status);
263 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100264
Julian Hallf5728962021-06-24 09:40:23 +0100265 psa_reset_key_attributes(&attributes);
266 free(key_buffer);
267 }
268 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100269
Julian Hallf5728962021-06-24 09:40:23 +0100270 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
271 }
272 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100273
Julian Hallf5728962021-06-24 09:40:23 +0100274 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100275}
276
Julian Hall0562ae02022-02-11 14:08:13 +0000277static rpc_status_t asymmetric_sign_handler(void *context, struct call_req* req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100278{
Julian Hallf5728962021-06-24 09:40:23 +0100279 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
280 struct call_param_buf *req_buf = call_req_get_req_buf(req);
281 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100282
Julian Hallf5728962021-06-24 09:40:23 +0100283 psa_key_id_t id;
284 psa_algorithm_t alg;
285 size_t hash_len = PSA_HASH_MAX_SIZE;
286 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100287
Julian Hallf5728962021-06-24 09:40:23 +0100288 if (serializer)
Julian Hall0562ae02022-02-11 14:08:13 +0000289 rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100290
Julian Hallf5728962021-06-24 09:40:23 +0100291 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100292
Julian Hallf5728962021-06-24 09:40:23 +0100293 psa_status_t psa_status;
294 size_t sig_len;
295 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100296
Julian Hall0562ae02022-02-11 14:08:13 +0000297 psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_SIGN_HASH) ?
298 psa_sign_hash(id, alg, hash_buffer, hash_len,
299 sig_buffer, sizeof(sig_buffer), &sig_len) :
300 psa_sign_message(id, alg, hash_buffer, hash_len,
301 sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100302
Julian Hallf5728962021-06-24 09:40:23 +0100303 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100304
Julian Hallf5728962021-06-24 09:40:23 +0100305 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
Julian Hall0562ae02022-02-11 14:08:13 +0000306 rpc_status = serializer->serialize_asymmetric_sign_resp(resp_buf, sig_buffer, sig_len);
Julian Hallf5728962021-06-24 09:40:23 +0100307 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100308
Julian Hallf5728962021-06-24 09:40:23 +0100309 call_req_set_opstatus(req, psa_status);
310 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100311
Julian Hallf5728962021-06-24 09:40:23 +0100312 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100313}
314
Julian Hall0562ae02022-02-11 14:08:13 +0000315static rpc_status_t asymmetric_verify_handler(void *context, struct call_req* req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100316{
Julian Hallf5728962021-06-24 09:40:23 +0100317 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
318 struct call_param_buf *req_buf = call_req_get_req_buf(req);
319 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100320
Julian Hallf5728962021-06-24 09:40:23 +0100321 psa_key_id_t id;
322 psa_algorithm_t alg;
323 size_t hash_len = PSA_HASH_MAX_SIZE;
324 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
325 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
326 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100327
Julian Hallf5728962021-06-24 09:40:23 +0100328 if (serializer)
Julian Hall0562ae02022-02-11 14:08:13 +0000329 rpc_status = serializer->deserialize_asymmetric_verify_req(req_buf, &id, &alg,
Julian Hallf5728962021-06-24 09:40:23 +0100330 hash_buffer, &hash_len,
331 sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100332
Julian Hallf5728962021-06-24 09:40:23 +0100333 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100334
Julian Hallf5728962021-06-24 09:40:23 +0100335 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100336
Julian Hall0562ae02022-02-11 14:08:13 +0000337 psa_status = (call_req_get_opcode(req) == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
338 psa_verify_hash(id, alg,
339 hash_buffer, hash_len,
340 sig_buffer, sig_len) :
341 psa_verify_message(id, alg,
342 hash_buffer, hash_len,
343 sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100344
Julian Hallf5728962021-06-24 09:40:23 +0100345 call_req_set_opstatus(req, psa_status);
346 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100347
Julian Hallf5728962021-06-24 09:40:23 +0100348 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100349}
350
351static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
352{
Julian Hallf5728962021-06-24 09:40:23 +0100353 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
354 struct call_param_buf *req_buf = call_req_get_req_buf(req);
355 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100356
Julian Hallf5728962021-06-24 09:40:23 +0100357 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100358
Julian Hallf5728962021-06-24 09:40:23 +0100359 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100360
Julian Hallf5728962021-06-24 09:40:23 +0100361 psa_key_id_t id;
362 psa_algorithm_t alg;
363 size_t ciphertext_len = max_param_size;
364 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
365 size_t salt_len = max_param_size;
366 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100367
Julian Hallf5728962021-06-24 09:40:23 +0100368 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100369
Julian Hallf5728962021-06-24 09:40:23 +0100370 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
371 &id, &alg,
372 ciphertext_buffer, &ciphertext_len,
373 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100374
Julian Hallf5728962021-06-24 09:40:23 +0100375 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100376
Julian Hallf5728962021-06-24 09:40:23 +0100377 psa_status_t psa_status;
378 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100379
Julian Hallf5728962021-06-24 09:40:23 +0100380 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100381
Julian Hallf5728962021-06-24 09:40:23 +0100382 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100383
Julian Hallf5728962021-06-24 09:40:23 +0100384 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
385 psa_get_key_type(&attributes),
386 psa_get_key_bits(&attributes),
387 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100388
Julian Hallf5728962021-06-24 09:40:23 +0100389 size_t plaintext_len;
390 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100391
Julian Hallf5728962021-06-24 09:40:23 +0100392 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100393
Julian Hallf5728962021-06-24 09:40:23 +0100394 /* Salt is an optional parameter */
395 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100396
Julian Hallf5728962021-06-24 09:40:23 +0100397 psa_status = psa_asymmetric_decrypt(id, alg,
398 ciphertext_buffer, ciphertext_len,
399 salt, salt_len,
400 plaintext_buffer, max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000401
Julian Hallf5728962021-06-24 09:40:23 +0100402 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000403
Julian Hallf5728962021-06-24 09:40:23 +0100404 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
405 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
406 plaintext_buffer, plaintext_len);
407 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000408
Julian Hallf5728962021-06-24 09:40:23 +0100409 free(plaintext_buffer);
410 }
411 else {
412 /* Failed to allocate ouptput buffer */
413 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
414 }
415 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100416
Julian Hallf5728962021-06-24 09:40:23 +0100417 call_req_set_opstatus(req, psa_status);
418 psa_reset_key_attributes(&attributes);
419 }
420 }
421 else {
422 /* Failed to allocate buffers */
423 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
424 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100425
Julian Hallf5728962021-06-24 09:40:23 +0100426 free(ciphertext_buffer);
427 free(salt_buffer);
428 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100429
Julian Hallf5728962021-06-24 09:40:23 +0100430 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100431}
432
433static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
434{
Julian Hallf5728962021-06-24 09:40:23 +0100435 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
436 struct call_param_buf *req_buf = call_req_get_req_buf(req);
437 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100438
Julian Hallf5728962021-06-24 09:40:23 +0100439 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100440
Julian Hallf5728962021-06-24 09:40:23 +0100441 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100442
Julian Hallf5728962021-06-24 09:40:23 +0100443 psa_key_id_t id;
444 psa_algorithm_t alg;
445 size_t plaintext_len = max_param_size;
446 uint8_t *plaintext_buffer = malloc(plaintext_len);
447 size_t salt_len = max_param_size;
448 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100449
Julian Hallf5728962021-06-24 09:40:23 +0100450 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100451
Julian Hallf5728962021-06-24 09:40:23 +0100452 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
453 &id, &alg,
454 plaintext_buffer, &plaintext_len,
455 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100456
Julian Hallf5728962021-06-24 09:40:23 +0100457 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100458
Julian Hallf5728962021-06-24 09:40:23 +0100459 psa_status_t psa_status;
460 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100461
Julian Hallf5728962021-06-24 09:40:23 +0100462 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100463
Julian Hallf5728962021-06-24 09:40:23 +0100464 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100465
Julian Hallf5728962021-06-24 09:40:23 +0100466 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
467 psa_get_key_type(&attributes),
468 psa_get_key_bits(&attributes),
469 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100470
Julian Hallf5728962021-06-24 09:40:23 +0100471 size_t ciphertext_len;
472 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100473
Julian Hallf5728962021-06-24 09:40:23 +0100474 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100475
Julian Hallf5728962021-06-24 09:40:23 +0100476 /* Salt is an optional parameter */
477 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100478
Julian Hallf5728962021-06-24 09:40:23 +0100479 psa_status = psa_asymmetric_encrypt(id, alg,
480 plaintext_buffer, plaintext_len,
481 salt, salt_len,
482 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000483
Julian Hallf5728962021-06-24 09:40:23 +0100484 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000485
Julian Hallf5728962021-06-24 09:40:23 +0100486 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
487 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
488 ciphertext_buffer, ciphertext_len);
489 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000490
Julian Hallf5728962021-06-24 09:40:23 +0100491 free(ciphertext_buffer);
492 }
493 else {
494 /* Failed to allocate ouptput buffer */
495 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
496 }
497 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100498
Julian Hallf5728962021-06-24 09:40:23 +0100499 call_req_set_opstatus(req, psa_status);
500 psa_reset_key_attributes(&attributes);
501 }
502 }
503 else {
504 /* Failed to allocate buffers */
505 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
506 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100507
Julian Hallf5728962021-06-24 09:40:23 +0100508 free(plaintext_buffer);
509 free(salt_buffer);
510 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100511
Julian Hallf5728962021-06-24 09:40:23 +0100512 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100513}
514
515static rpc_status_t generate_random_handler(void *context, struct call_req* req)
516{
Julian Hallf5728962021-06-24 09:40:23 +0100517 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
518 struct call_param_buf *req_buf = call_req_get_req_buf(req);
519 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100520
Julian Hallf5728962021-06-24 09:40:23 +0100521 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100522
Julian Hallf5728962021-06-24 09:40:23 +0100523 if (serializer)
524 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100525
Julian Hallf5728962021-06-24 09:40:23 +0100526 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100527
Julian Hallf5728962021-06-24 09:40:23 +0100528 psa_status_t psa_status;
529 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100530
Julian Hallf5728962021-06-24 09:40:23 +0100531 if (output_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100532
Julian Hallf5728962021-06-24 09:40:23 +0100533 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100534
Julian Hallf5728962021-06-24 09:40:23 +0100535 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100536
Julian Hallf5728962021-06-24 09:40:23 +0100537 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
538 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
539 output_buffer, output_size);
540 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100541
Julian Hallf5728962021-06-24 09:40:23 +0100542 call_req_set_opstatus(req, psa_status);
543 free(output_buffer);
544 }
545 else {
546 /* Failed to allocate output buffer */
547 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
548 }
549 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100550
Julian Hallf5728962021-06-24 09:40:23 +0100551 return rpc_status;
552}
553
Julian Hall8359a632021-07-08 15:10:30 +0100554static rpc_status_t copy_key_handler(void *context, struct call_req* req)
555{
556 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
557 struct call_param_buf *req_buf = call_req_get_req_buf(req);
558 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
559
560 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
561 psa_key_id_t source_key_id;
562
563 if (serializer)
564 rpc_status = serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
565
566 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
567
568 psa_key_id_t target_key_id;
569
570 psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
571
572 if (psa_status == PSA_SUCCESS) {
573
574 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
575 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
576 }
577
578 call_req_set_opstatus(req, psa_status);
579 }
580
581 psa_reset_key_attributes(&attributes);
582
583 return rpc_status;
584}
585
586static rpc_status_t purge_key_handler(void *context, struct call_req* req)
587{
588 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
589 struct call_param_buf *req_buf = call_req_get_req_buf(req);
590 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
591
592 psa_key_id_t id;
593
594 if (serializer)
595 rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
596
597 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
598
599 psa_status_t psa_status = psa_purge_key(id);
600 call_req_set_opstatus(req, psa_status);
601 }
602
603 return rpc_status;
604}
605
606static rpc_status_t get_key_attributes_handler(void *context, struct call_req* req)
607{
608 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
609 struct call_param_buf *req_buf = call_req_get_req_buf(req);
610 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
611
612 psa_key_id_t id;
613
614 if (serializer)
615 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
616
617 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
618
619 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
620
621 psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
622
623 if (psa_status == PSA_SUCCESS) {
624
625 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
626 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf, &attributes);
627 }
628
629 psa_reset_key_attributes(&attributes);
630 call_req_set_opstatus(req, psa_status);
631 }
632
633 return rpc_status;
634}