blob: d1798d7e9191db8f6bc1d7ea51d58061567238fb [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 */
Imre Kis6d867d82023-07-04 13:29:33 +02006#include <protocols/rpc/common/packed-c/status.h>
7#include <protocols/service/crypto/packed-c/opcodes.h>
8#include <psa/crypto.h>
9#include <service/crypto/provider/crypto_provider.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010010#include <stdint.h>
11#include <stdlib.h>
Imre Kis6d867d82023-07-04 13:29:33 +020012
13#include "crypto_uuid.h"
Julian Hallc02fffb2020-11-23 18:22:06 +010014
15/* Service request handlers */
Imre Kis6d867d82023-07-04 13:29:33 +020016static rpc_status_t generate_key_handler(void *context, struct rpc_request *req);
17static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req);
18static rpc_status_t export_key_handler(void *context, struct rpc_request *req);
19static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req);
20static rpc_status_t import_key_handler(void *context, struct rpc_request *req);
21static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req);
22static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req);
23static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req);
24static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req);
25static rpc_status_t generate_random_handler(void *context, struct rpc_request *req);
26static rpc_status_t copy_key_handler(void *context, struct rpc_request *req);
27static rpc_status_t purge_key_handler(void *context, struct rpc_request *req);
28static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req);
Julian Hallc02fffb2020-11-23 18:22:06 +010029
30/* Handler mapping table for service */
31static const struct service_handler handler_table[] = {
Imre Kis6d867d82023-07-04 13:29:33 +020032 { 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, asymmetric_sign_handler },
38 { TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_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_COPY_KEY, copy_key_handler },
43 { TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler },
44 { TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler },
45 { TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler },
46 { TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_handler },
Julian Hallc02fffb2020-11-23 18:22:06 +010047};
48
Imre Kis6d867d82023-07-04 13:29:33 +020049struct rpc_service_interface *
50crypto_provider_init(struct crypto_provider *context, unsigned int encoding,
51 const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010052{
Imre Kis6d867d82023-07-04 13:29:33 +020053 const struct rpc_uuid crypto_service_uuid[2] = {
54 { .uuid = TS_PSA_CRYPTO_SERVICE_UUID },
55 { .uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID },
56 };
Julian Hallc02fffb2020-11-23 18:22:06 +010057
Imre Kis6d867d82023-07-04 13:29:33 +020058 if (encoding >= TS_RPC_ENCODING_LIMIT)
59 return NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010060
Imre Kis6d867d82023-07-04 13:29:33 +020061 context->serializer = serializer;
62
63 service_provider_init(&context->base_provider, context, &crypto_service_uuid[encoding],
64 handler_table,
65 sizeof(handler_table) / sizeof(struct service_handler));
Julian Hall3e614542021-07-29 11:47:47 +010066
Julian Hall9061e6c2021-06-29 14:24:20 +010067 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010068}
69
Julian Hall9061e6c2021-06-29 14:24:20 +010070void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010071{
Imre Kis6d867d82023-07-04 13:29:33 +020072 (void)context;
Julian Hallc02fffb2020-11-23 18:22:06 +010073}
74
Julian Hall9061e6c2021-06-29 14:24:20 +010075void crypto_provider_register_serializer(struct crypto_provider *context,
Imre Kis6d867d82023-07-04 13:29:33 +020076 const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010077{
Imre Kis6d867d82023-07-04 13:29:33 +020078 context->serializer = serializer;
julhal01c3f4e9a2020-12-15 13:39:01 +000079}
80
Imre Kis6d867d82023-07-04 13:29:33 +020081void crypto_provider_extend(struct crypto_provider *context, struct service_provider *sub_provider)
Julian Hall13e76952021-07-13 12:17:09 +010082{
83 service_provider_extend(&context->base_provider, sub_provider);
84}
85
Imre Kis6d867d82023-07-04 13:29:33 +020086static const struct crypto_provider_serializer *get_crypto_serializer(void *context,
87 const struct rpc_request *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000088{
Imre Kis6d867d82023-07-04 13:29:33 +020089 struct crypto_provider *this_instance = (struct crypto_provider *)context;
julhal01c3f4e9a2020-12-15 13:39:01 +000090
Imre Kis6d867d82023-07-04 13:29:33 +020091 return this_instance->serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +010092}
93
Imre Kis6d867d82023-07-04 13:29:33 +020094static rpc_status_t generate_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +010095{
Imre Kis6d867d82023-07-04 13:29:33 +020096 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
97 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +010098 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
Imre Kis6d867d82023-07-04 13:29:33 +0200105 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100106 psa_status_t psa_status;
107 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100108
Julian Hallf5728962021-06-24 09:40:23 +0100109 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100110
Julian Hallf5728962021-06-24 09:40:23 +0100111 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200112 struct rpc_buffer *resp_buf = &req->response;
Julian Hallf5728962021-06-24 09:40:23 +0100113 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
114 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100115
Imre Kis6d867d82023-07-04 13:29:33 +0200116 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100117 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100118
Julian Hallf5728962021-06-24 09:40:23 +0100119 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100120
Julian Hallf5728962021-06-24 09:40:23 +0100121 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100122}
123
Imre Kis6d867d82023-07-04 13:29:33 +0200124static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100125{
Imre Kis6d867d82023-07-04 13:29:33 +0200126 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
127 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100128 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100129
Julian Hallf5728962021-06-24 09:40:23 +0100130 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100131
Julian Hallf5728962021-06-24 09:40:23 +0100132 if (serializer)
133 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100134
Imre Kis6d867d82023-07-04 13:29:33 +0200135 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100136 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100137
Julian Hallf5728962021-06-24 09:40:23 +0100138 psa_status = psa_destroy_key(id);
Imre Kis6d867d82023-07-04 13:29:33 +0200139 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100140 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100141
Julian Hallf5728962021-06-24 09:40:23 +0100142 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100143}
144
Imre Kis6d867d82023-07-04 13:29:33 +0200145static rpc_status_t export_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100146{
Imre Kis6d867d82023-07-04 13:29:33 +0200147 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
148 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100149 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100150
Julian Hallf5728962021-06-24 09:40:23 +0100151 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100152
Julian Hallf5728962021-06-24 09:40:23 +0100153 if (serializer)
154 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100155
Imre Kis6d867d82023-07-04 13:29:33 +0200156 if (rpc_status == RPC_SUCCESS) {
Julian Hall464021a2021-07-29 15:20:10 +0100157 size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
158 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100159
Julian Hall464021a2021-07-29 15:20:10 +0100160 if (key_buffer) {
Julian Hall464021a2021-07-29 15:20:10 +0100161 size_t export_size;
Imre Kis6d867d82023-07-04 13:29:33 +0200162 psa_status_t psa_status =
163 psa_export_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100164
Julian Hall464021a2021-07-29 15:20:10 +0100165 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200166 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
Imre Kis6d867d82023-07-04 13:29:33 +0200168 rpc_status = serializer->serialize_export_key_resp(
169 resp_buf, key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100170 }
Julian Hallec81a502021-07-12 11:36:37 +0100171
Julian Hall464021a2021-07-29 15:20:10 +0100172 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200173 req->service_status = psa_status;
174 } else {
Julian Hall464021a2021-07-29 15:20:10 +0100175 /* Failed to allocate key buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200176 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hall464021a2021-07-29 15:20:10 +0100177 }
Julian Hallf5728962021-06-24 09:40:23 +0100178 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100179
Julian Hallf5728962021-06-24 09:40:23 +0100180 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100181}
182
Imre Kis6d867d82023-07-04 13:29:33 +0200183static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100184{
Imre Kis6d867d82023-07-04 13:29:33 +0200185 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
186 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100187 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100188
Julian Hallf5728962021-06-24 09:40:23 +0100189 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100190
Julian Hallf5728962021-06-24 09:40:23 +0100191 if (serializer)
192 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100193
Imre Kis6d867d82023-07-04 13:29:33 +0200194 if (rpc_status == RPC_SUCCESS) {
Julian Hallec81a502021-07-12 11:36:37 +0100195 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
196 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100197
Julian Hallec81a502021-07-12 11:36:37 +0100198 if (key_buffer) {
Julian Hallec81a502021-07-12 11:36:37 +0100199 size_t export_size;
Imre Kis6d867d82023-07-04 13:29:33 +0200200 psa_status_t psa_status = psa_export_public_key(
201 id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100202
Julian Hallec81a502021-07-12 11:36:37 +0100203 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200204 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100205
Imre Kis6d867d82023-07-04 13:29:33 +0200206 rpc_status = serializer->serialize_export_public_key_resp(
207 resp_buf, key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100208 }
Julian Hallec81a502021-07-12 11:36:37 +0100209
210 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200211 req->service_status = psa_status;
212 } else {
Julian Hallec81a502021-07-12 11:36:37 +0100213 /* Failed to allocate key buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200214 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallec81a502021-07-12 11:36:37 +0100215 }
Julian Hallf5728962021-06-24 09:40:23 +0100216 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100217
Julian Hallf5728962021-06-24 09:40:23 +0100218 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100219}
220
Imre Kis6d867d82023-07-04 13:29:33 +0200221static rpc_status_t import_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100222{
Imre Kis6d867d82023-07-04 13:29:33 +0200223 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
224 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100225 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100226
Julian Hallf5728962021-06-24 09:40:23 +0100227 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100228 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
229 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100230
Julian Hallf5728962021-06-24 09:40:23 +0100231 if (key_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100232 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Imre Kis6d867d82023-07-04 13:29:33 +0200233 rpc_status = serializer->deserialize_import_key_req(
234 req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100235
Imre Kis6d867d82023-07-04 13:29:33 +0200236 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100237 psa_status_t psa_status;
238 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100239
Imre Kis6d867d82023-07-04 13:29:33 +0200240 psa_status =
241 psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100242
Julian Hallf5728962021-06-24 09:40:23 +0100243 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200244 struct rpc_buffer *resp_buf = &req->response;
julhal01c3f4e9a2020-12-15 13:39:01 +0000245
Imre Kis6d867d82023-07-04 13:29:33 +0200246 rpc_status =
247 serializer->serialize_import_key_resp(resp_buf, id);
Julian Hallf5728962021-06-24 09:40:23 +0100248 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000249
Imre Kis6d867d82023-07-04 13:29:33 +0200250 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100251 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100252
Julian Hallf5728962021-06-24 09:40:23 +0100253 psa_reset_key_attributes(&attributes);
254 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200255 } else {
256 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100257 }
258 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100259
Julian Hallf5728962021-06-24 09:40:23 +0100260 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100261}
262
Imre Kis6d867d82023-07-04 13:29:33 +0200263static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100264{
Imre Kis6d867d82023-07-04 13:29:33 +0200265 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
266 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100267 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100268
Julian Hallf5728962021-06-24 09:40:23 +0100269 psa_key_id_t id;
270 psa_algorithm_t alg;
271 size_t hash_len = PSA_HASH_MAX_SIZE;
272 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100273
Julian Hallf5728962021-06-24 09:40:23 +0100274 if (serializer)
Imre Kis6d867d82023-07-04 13:29:33 +0200275 rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &id, &alg,
276 hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100277
Imre Kis6d867d82023-07-04 13:29:33 +0200278 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100279 psa_status_t psa_status;
280 size_t sig_len;
281 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100282
Imre Kis6d867d82023-07-04 13:29:33 +0200283 psa_status = (req->opcode == TS_CRYPTO_OPCODE_SIGN_HASH) ?
284 psa_sign_hash(id, alg, hash_buffer, hash_len, sig_buffer,
285 sizeof(sig_buffer), &sig_len) :
286 psa_sign_message(id, alg, hash_buffer, hash_len, sig_buffer,
287 sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100288
Julian Hallf5728962021-06-24 09:40:23 +0100289 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200290 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100291
Imre Kis6d867d82023-07-04 13:29:33 +0200292 rpc_status = serializer->serialize_asymmetric_sign_resp(
293 resp_buf, sig_buffer, sig_len);
Julian Hallf5728962021-06-24 09:40:23 +0100294 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100295
Imre Kis6d867d82023-07-04 13:29:33 +0200296 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100297 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100298
Julian Hallf5728962021-06-24 09:40:23 +0100299 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100300}
301
Imre Kis6d867d82023-07-04 13:29:33 +0200302static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100303{
Imre Kis6d867d82023-07-04 13:29:33 +0200304 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
305 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100306 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100307
Julian Hallf5728962021-06-24 09:40:23 +0100308 psa_key_id_t id;
309 psa_algorithm_t alg;
310 size_t hash_len = PSA_HASH_MAX_SIZE;
311 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
312 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
313 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100314
Julian Hallf5728962021-06-24 09:40:23 +0100315 if (serializer)
Imre Kis6d867d82023-07-04 13:29:33 +0200316 rpc_status = serializer->deserialize_asymmetric_verify_req(
317 req_buf, &id, &alg, hash_buffer, &hash_len, sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100318
Imre Kis6d867d82023-07-04 13:29:33 +0200319 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100320 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100321
Imre Kis6d867d82023-07-04 13:29:33 +0200322 psa_status = (req->opcode == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
323 psa_verify_hash(id, alg, hash_buffer, hash_len, sig_buffer,
324 sig_len) :
325 psa_verify_message(id, alg, hash_buffer, hash_len, sig_buffer,
326 sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100327
Imre Kis6d867d82023-07-04 13:29:33 +0200328 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100329 }
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
Imre Kis6d867d82023-07-04 13:29:33 +0200334static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100335{
Imre Kis6d867d82023-07-04 13:29:33 +0200336 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
337 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100338 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 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100341 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100342
Julian Hallf5728962021-06-24 09:40:23 +0100343 psa_key_id_t id;
344 psa_algorithm_t alg;
345 size_t ciphertext_len = max_param_size;
346 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
347 size_t salt_len = max_param_size;
348 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100349
Julian Hallf5728962021-06-24 09:40:23 +0100350 if (ciphertext_buffer && salt_buffer) {
Imre Kis6d867d82023-07-04 13:29:33 +0200351 rpc_status = serializer->deserialize_asymmetric_decrypt_req(
352 req_buf, &id, &alg, ciphertext_buffer, &ciphertext_len, salt_buffer,
353 &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100354
Imre Kis6d867d82023-07-04 13:29:33 +0200355 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100356 psa_status_t psa_status;
357 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100358
Julian Hallf5728962021-06-24 09:40:23 +0100359 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100360
Julian Hallf5728962021-06-24 09:40:23 +0100361 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200362 size_t max_decrypt_size =
363 PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
364 psa_get_key_type(&attributes),
365 psa_get_key_bits(&attributes), alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100366
Julian Hallf5728962021-06-24 09:40:23 +0100367 size_t plaintext_len;
368 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100369
Julian Hallf5728962021-06-24 09:40:23 +0100370 if (plaintext_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100371 /* Salt is an optional parameter */
372 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100373
Imre Kis6d867d82023-07-04 13:29:33 +0200374 psa_status = psa_asymmetric_decrypt(
375 id, alg, ciphertext_buffer, ciphertext_len,
376 salt, salt_len, plaintext_buffer,
377 max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000378
Julian Hallf5728962021-06-24 09:40:23 +0100379 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200380 struct rpc_buffer *resp_buf =
381 &req->response;
382 rpc_status = serializer->serialize_asymmetric_decrypt_resp(
383 resp_buf, plaintext_buffer, plaintext_len);
Julian Hallf5728962021-06-24 09:40:23 +0100384 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000385
Julian Hallf5728962021-06-24 09:40:23 +0100386 free(plaintext_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200387 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100388 /* Failed to allocate ouptput buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200389 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100390 }
391 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100392
Imre Kis6d867d82023-07-04 13:29:33 +0200393 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100394 psa_reset_key_attributes(&attributes);
395 }
Imre Kis6d867d82023-07-04 13:29:33 +0200396 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100397 /* Failed to allocate buffers */
Imre Kis6d867d82023-07-04 13:29:33 +0200398 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100399 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100400
Julian Hallf5728962021-06-24 09:40:23 +0100401 free(ciphertext_buffer);
402 free(salt_buffer);
403 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100404
Julian Hallf5728962021-06-24 09:40:23 +0100405 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100406}
407
Imre Kis6d867d82023-07-04 13:29:33 +0200408static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100409{
Imre Kis6d867d82023-07-04 13:29:33 +0200410 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
411 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100412 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100413
Julian Hallf5728962021-06-24 09:40:23 +0100414 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100415 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100416
Julian Hallf5728962021-06-24 09:40:23 +0100417 psa_key_id_t id;
418 psa_algorithm_t alg;
419 size_t plaintext_len = max_param_size;
420 uint8_t *plaintext_buffer = malloc(plaintext_len);
421 size_t salt_len = max_param_size;
422 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100423
Julian Hallf5728962021-06-24 09:40:23 +0100424 if (plaintext_buffer && salt_buffer) {
Imre Kis6d867d82023-07-04 13:29:33 +0200425 rpc_status = serializer->deserialize_asymmetric_encrypt_req(
426 req_buf, &id, &alg, plaintext_buffer, &plaintext_len, salt_buffer,
427 &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100428
Imre Kis6d867d82023-07-04 13:29:33 +0200429 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100430 psa_status_t psa_status;
431 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100432
Julian Hallf5728962021-06-24 09:40:23 +0100433 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100434
Julian Hallf5728962021-06-24 09:40:23 +0100435 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200436 size_t max_encrypt_size =
437 PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
438 psa_get_key_type(&attributes),
439 psa_get_key_bits(&attributes), alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100440
Julian Hallf5728962021-06-24 09:40:23 +0100441 size_t ciphertext_len;
442 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100443
Julian Hallf5728962021-06-24 09:40:23 +0100444 if (ciphertext_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100445 /* Salt is an optional parameter */
446 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100447
Imre Kis6d867d82023-07-04 13:29:33 +0200448 psa_status = psa_asymmetric_encrypt(
449 id, alg, plaintext_buffer, plaintext_len,
450 salt, salt_len, ciphertext_buffer,
451 max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000452
Julian Hallf5728962021-06-24 09:40:23 +0100453 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200454 struct rpc_buffer *resp_buf =
455 &req->response;
julhal01c3f4e9a2020-12-15 13:39:01 +0000456
Imre Kis6d867d82023-07-04 13:29:33 +0200457 rpc_status = serializer->serialize_asymmetric_encrypt_resp(
458 resp_buf, ciphertext_buffer, ciphertext_len);
Julian Hallf5728962021-06-24 09:40:23 +0100459 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000460
Julian Hallf5728962021-06-24 09:40:23 +0100461 free(ciphertext_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200462 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100463 /* Failed to allocate ouptput buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200464 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100465 }
466 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100467
Imre Kis6d867d82023-07-04 13:29:33 +0200468 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100469 psa_reset_key_attributes(&attributes);
470 }
Imre Kis6d867d82023-07-04 13:29:33 +0200471 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100472 /* Failed to allocate buffers */
Imre Kis6d867d82023-07-04 13:29:33 +0200473 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100474 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100475
Julian Hallf5728962021-06-24 09:40:23 +0100476 free(plaintext_buffer);
477 free(salt_buffer);
478 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100479
Julian Hallf5728962021-06-24 09:40:23 +0100480 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100481}
482
Imre Kis6d867d82023-07-04 13:29:33 +0200483static rpc_status_t generate_random_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100484{
Imre Kis6d867d82023-07-04 13:29:33 +0200485 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
486 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100487 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100488
Julian Hallf5728962021-06-24 09:40:23 +0100489 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100490
Julian Hallf5728962021-06-24 09:40:23 +0100491 if (serializer)
492 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100493
Imre Kis6d867d82023-07-04 13:29:33 +0200494 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100495 psa_status_t psa_status;
496 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100497
Julian Hallf5728962021-06-24 09:40:23 +0100498 if (output_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100499 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100500
Julian Hallf5728962021-06-24 09:40:23 +0100501 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200502 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100503
Imre Kis6d867d82023-07-04 13:29:33 +0200504 rpc_status = serializer->serialize_generate_random_resp(
505 resp_buf, output_buffer, output_size);
Julian Hallf5728962021-06-24 09:40:23 +0100506 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100507
Imre Kis6d867d82023-07-04 13:29:33 +0200508 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100509 free(output_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200510 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100511 /* Failed to allocate output buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200512 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100513 }
514 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100515
Julian Hallf5728962021-06-24 09:40:23 +0100516 return rpc_status;
517}
518
Imre Kis6d867d82023-07-04 13:29:33 +0200519static rpc_status_t copy_key_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100520{
Imre Kis6d867d82023-07-04 13:29:33 +0200521 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
522 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100523 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
524
525 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
526 psa_key_id_t source_key_id;
527
528 if (serializer)
Imre Kis6d867d82023-07-04 13:29:33 +0200529 rpc_status =
530 serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100531
Imre Kis6d867d82023-07-04 13:29:33 +0200532 if (rpc_status == RPC_SUCCESS) {
Julian Hall8359a632021-07-08 15:10:30 +0100533 psa_key_id_t target_key_id;
534
535 psa_status_t psa_status = psa_copy_key(source_key_id, &attributes, &target_key_id);
536
537 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200538 struct rpc_buffer *resp_buf = &req->response;
Julian Hall8359a632021-07-08 15:10:30 +0100539 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
540 }
541
Imre Kis6d867d82023-07-04 13:29:33 +0200542 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100543 }
544
545 psa_reset_key_attributes(&attributes);
546
547 return rpc_status;
548}
549
Imre Kis6d867d82023-07-04 13:29:33 +0200550static rpc_status_t purge_key_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100551{
Imre Kis6d867d82023-07-04 13:29:33 +0200552 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
553 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100554 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
555
556 psa_key_id_t id;
557
558 if (serializer)
559 rpc_status = serializer->deserialize_purge_key_req(req_buf, &id);
560
Imre Kis6d867d82023-07-04 13:29:33 +0200561 if (rpc_status == RPC_SUCCESS) {
Julian Hall8359a632021-07-08 15:10:30 +0100562 psa_status_t psa_status = psa_purge_key(id);
Imre Kis6d867d82023-07-04 13:29:33 +0200563 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100564 }
565
566 return rpc_status;
567}
568
Imre Kis6d867d82023-07-04 13:29:33 +0200569static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100570{
Imre Kis6d867d82023-07-04 13:29:33 +0200571 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
572 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100573 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
574
575 psa_key_id_t id;
576
577 if (serializer)
578 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &id);
579
Imre Kis6d867d82023-07-04 13:29:33 +0200580 if (rpc_status == RPC_SUCCESS) {
Julian Hall8359a632021-07-08 15:10:30 +0100581 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
582
583 psa_status_t psa_status = psa_get_key_attributes(id, &attributes);
584
585 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200586 struct rpc_buffer *resp_buf = &req->response;
Julian Hall8359a632021-07-08 15:10:30 +0100587
Imre Kis6d867d82023-07-04 13:29:33 +0200588 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf,
589 &attributes);
Julian Hall8359a632021-07-08 15:10:30 +0100590 }
591
592 psa_reset_key_attributes(&attributes);
Imre Kis6d867d82023-07-04 13:29:33 +0200593 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100594 }
595
596 return rpc_status;
597}