blob: 3dc2a4195ed5edd1450f9d7211381189881fd277 [file] [log] [blame]
Julian Hallc02fffb2020-11-23 18:22:06 +01001/*
julhal01c3f4e9a2020-12-15 13:39:01 +00002 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
Julian Hallc02fffb2020-11-23 18:22:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <stdint.h>
7#include <stdlib.h>
8#include <protocols/service/crypto/packed-c/opcodes.h>
Julian Hall9061e6c2021-06-29 14:24:20 +01009#include <service/crypto/provider/crypto_provider.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010010#include <protocols/rpc/common/packed-c/status.h>
11#include <psa/crypto.h>
12
13/* Service request handlers */
14static rpc_status_t nop_handler(void *context, struct call_req* req);
15static rpc_status_t generate_key_handler(void *context, struct call_req* req);
16static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010017static rpc_status_t export_key_handler(void *context, struct call_req* req);
18static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
19static rpc_status_t import_key_handler(void *context, struct call_req* req);
20static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
21static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
22static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
23static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
24static rpc_status_t generate_random_handler(void *context, struct call_req* req);
Julian Hallf5728962021-06-24 09:40:23 +010025static rpc_status_t hash_setup_handler(void *context, struct call_req* req);
26static rpc_status_t hash_update_handler(void *context, struct call_req* req);
27static rpc_status_t hash_finish_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010028
29/* Handler mapping table for service */
30static const struct service_handler handler_table[] = {
Julian Hallf5728962021-06-24 09:40:23 +010031 {TS_CRYPTO_OPCODE_NOP, nop_handler},
32 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
33 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
34 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
35 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
36 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
37 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
38 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
39 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
40 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
41 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler},
42 {TS_CRYPTO_OPCODE_HASH_SETUP, hash_setup_handler},
43 {TS_CRYPTO_OPCODE_HASH_UPDATE, hash_update_handler},
44 {TS_CRYPTO_OPCODE_HASH_FINISH, hash_finish_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 Hallf5728962021-06-24 09:40:23 +010049 crypto_context_pool_init(&context->context_pool);
julhal01ffa98d82021-01-20 13:51:58 +000050
Julian Hall9061e6c2021-06-29 14:24:20 +010051 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
52 context->serializers[encoding] = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010053
Julian Hall9061e6c2021-06-29 14:24:20 +010054 service_provider_init(&context->base_provider, context,
Julian Hallf5728962021-06-24 09:40:23 +010055 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
Julian Hallc02fffb2020-11-23 18:22:06 +010056
Julian Hall9061e6c2021-06-29 14:24:20 +010057 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010058}
59
Julian Hall9061e6c2021-06-29 14:24:20 +010060void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010061{
Julian Hallf5728962021-06-24 09:40:23 +010062 crypto_context_pool_deinit(&context->context_pool);
Julian Hallc02fffb2020-11-23 18:22:06 +010063}
64
Julian Hall9061e6c2021-06-29 14:24:20 +010065void crypto_provider_register_serializer(struct crypto_provider *context,
66 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010067{
Julian Hallf5728962021-06-24 09:40:23 +010068 if (encoding < TS_RPC_ENCODING_LIMIT)
69 context->serializers[encoding] = serializer;
julhal01c3f4e9a2020-12-15 13:39:01 +000070}
71
72static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
Julian Hallf5728962021-06-24 09:40:23 +010073 const struct call_req *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000074{
Julian Hall9061e6c2021-06-29 14:24:20 +010075 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +010076 const struct crypto_provider_serializer* serializer = NULL;
77 unsigned int encoding = call_req_get_encoding(req);
julhal01c3f4e9a2020-12-15 13:39:01 +000078
Julian Hallf5728962021-06-24 09:40:23 +010079 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
julhal01c3f4e9a2020-12-15 13:39:01 +000080
Julian Hallf5728962021-06-24 09:40:23 +010081 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010082}
83
84static rpc_status_t nop_handler(void *context, struct call_req* req)
85{
Julian Hallf5728962021-06-24 09:40:23 +010086 /* Responds to a request by returning success */
87 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
88 psa_status_t psa_status = PSA_SUCCESS;
Julian Hallc02fffb2020-11-23 18:22:06 +010089
Julian Hallf5728962021-06-24 09:40:23 +010090 (void)context;
91 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +010092
Julian Hallf5728962021-06-24 09:40:23 +010093 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +010094}
95
96static 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 Hallf5728962021-06-24 09:40:23 +0100163 psa_status_t psa_status;
164 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100165
Julian Hallf5728962021-06-24 09:40:23 +0100166 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
Julian Hallf5728962021-06-24 09:40:23 +0100168 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100169
Julian Hallf5728962021-06-24 09:40:23 +0100170 size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
171 psa_get_key_type(&attributes),
172 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100173
Julian Hallf5728962021-06-24 09:40:23 +0100174 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100175
Julian Hallf5728962021-06-24 09:40:23 +0100176 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100177
Julian Hallf5728962021-06-24 09:40:23 +0100178 size_t export_size;
179 psa_status = psa_export_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100180
Julian Hallf5728962021-06-24 09:40:23 +0100181 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100182
Julian Hallf5728962021-06-24 09:40:23 +0100183 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
184 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
185 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100186
Julian Hallf5728962021-06-24 09:40:23 +0100187 free(key_buffer);
188 }
189 else {
190 /* Failed to allocate key buffer */
191 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
192 }
193 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100194
Julian Hallf5728962021-06-24 09:40:23 +0100195 call_req_set_opstatus(req, psa_status);
196 psa_reset_key_attributes(&attributes);
197 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100198
Julian Hallf5728962021-06-24 09:40:23 +0100199 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100200}
201
202static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
203{
Julian Hallf5728962021-06-24 09:40:23 +0100204 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
205 struct call_param_buf *req_buf = call_req_get_req_buf(req);
206 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100207
Julian Hallf5728962021-06-24 09:40:23 +0100208 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100209
Julian Hallf5728962021-06-24 09:40:23 +0100210 if (serializer)
211 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100212
Julian Hallf5728962021-06-24 09:40:23 +0100213 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100214
Julian Hallf5728962021-06-24 09:40:23 +0100215 psa_status_t psa_status;
216 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100217
Julian Hallf5728962021-06-24 09:40:23 +0100218 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100219
Julian Hallf5728962021-06-24 09:40:23 +0100220 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100221
Julian Hallf5728962021-06-24 09:40:23 +0100222 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
223 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
224 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100225
Julian Hallf5728962021-06-24 09:40:23 +0100226 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100227
Julian Hallf5728962021-06-24 09:40:23 +0100228 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100229
Julian Hallf5728962021-06-24 09:40:23 +0100230 size_t export_size;
231 psa_status = psa_export_public_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100232
Julian Hallf5728962021-06-24 09:40:23 +0100233 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100234
Julian Hallf5728962021-06-24 09:40:23 +0100235 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
236 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
237 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100238
Julian Hallf5728962021-06-24 09:40:23 +0100239 free(key_buffer);
240 }
241 else {
242 /* Failed to allocate key buffer */
243 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
244 }
245 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100246
Julian Hallf5728962021-06-24 09:40:23 +0100247 call_req_set_opstatus(req, psa_status);
248 psa_reset_key_attributes(&attributes);
249 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100250
Julian Hallf5728962021-06-24 09:40:23 +0100251 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100252}
253
254static rpc_status_t import_key_handler(void *context, struct call_req* req)
255{
Julian Hallf5728962021-06-24 09:40:23 +0100256 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
257 struct call_param_buf *req_buf = call_req_get_req_buf(req);
258 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100259
Julian Hallf5728962021-06-24 09:40:23 +0100260 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100261
Julian Hallf5728962021-06-24 09:40:23 +0100262 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
263 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100264
Julian Hallf5728962021-06-24 09:40:23 +0100265 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100266
Julian Hallf5728962021-06-24 09:40:23 +0100267 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
268 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, 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
569static rpc_status_t hash_setup_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);
Julian Hall9061e6c2021-06-29 14:24:20 +0100574 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +0100575
576 psa_algorithm_t alg;
577
578 if (serializer)
579 rpc_status = serializer->deserialize_hash_setup_req(req_buf, &alg);
580
581 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
582
583 uint32_t op_handle;
584
585 struct crypto_context *crypto_context =
586 crypto_context_pool_alloc(&this_instance->context_pool,
587 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
588 &op_handle);
589
590 if (crypto_context) {
591
592 psa_status_t psa_status;
593
594 crypto_context->op.hash = psa_hash_operation_init();
595 psa_status = psa_hash_setup(&crypto_context->op.hash, alg);
596
597 if (psa_status == PSA_SUCCESS) {
598
599 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
600 rpc_status = serializer->serialize_hash_setup_resp(resp_buf, op_handle);
601 }
602
603 if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
604
605 crypto_context_pool_free(&this_instance->context_pool, crypto_context);
606 }
607
608 call_req_set_opstatus(req, psa_status);
609 }
610 else {
611 /* Failed to allocate crypto context for transaction */
612 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
613 }
614 }
615
616 return rpc_status;
617}
618
619static rpc_status_t hash_update_handler(void *context, struct call_req* req)
620{
621 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
622 struct call_param_buf *req_buf = call_req_get_req_buf(req);
623 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hall9061e6c2021-06-29 14:24:20 +0100624 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +0100625
626 uint32_t op_handle;
627 const uint8_t *data;
628 size_t data_len;
629
630 if (serializer)
631 rpc_status = serializer->deserialize_hash_update_req(req_buf, &op_handle, &data, &data_len);
632
633 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
634
635 struct crypto_context *crypto_context =
636 crypto_context_pool_find(&this_instance->context_pool,
637 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
638 op_handle);
639
640 if (crypto_context) {
641
642 psa_status_t psa_status = psa_hash_update(&crypto_context->op.hash, data, data_len);
643 call_req_set_opstatus(req, psa_status);
644 }
645 else {
646 /* Requested context doesn't exist */
647 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
648 }
649 }
650
651 return rpc_status;
652}
653
654static rpc_status_t hash_finish_handler(void *context, struct call_req* req)
655{
656 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
657 struct call_param_buf *req_buf = call_req_get_req_buf(req);
658 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hall9061e6c2021-06-29 14:24:20 +0100659 struct crypto_provider *this_instance = (struct crypto_provider*)context;
Julian Hallf5728962021-06-24 09:40:23 +0100660
661 uint32_t op_handle;
662
663 if (serializer)
664 rpc_status = serializer->deserialize_hash_finish_req(req_buf, &op_handle);
665
666 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
667
668 struct crypto_context *crypto_context =
669 crypto_context_pool_find(&this_instance->context_pool,
670 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
671 op_handle);
672
673 if (crypto_context) {
674
675 psa_status_t psa_status;
676 size_t hash_len;
677 uint8_t hash[PSA_HASH_MAX_SIZE];
678
679 psa_status = psa_hash_finish(&crypto_context->op.hash, hash, sizeof(hash), &hash_len);
680
681 if (psa_status == PSA_SUCCESS) {
682
683 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
684 rpc_status = serializer->serialize_hash_finish_resp(resp_buf, hash, hash_len);
685 }
686
687 crypto_context_pool_free(&this_instance->context_pool, crypto_context);
688
689 call_req_set_opstatus(req, psa_status);
690 }
691 else {
692 /* Requested context doesn't exist */
693 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
694 }
695 }
696
697 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000698}