blob: 292c180471e56320f0e2f456b80cb6b92c2d9bd3 [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>
9#include <service/crypto/provider/mbedcrypto/crypto_provider.h>
julhal012c18fbf2021-02-01 08:29:28 +000010#include <service/crypto/provider/mbedcrypto/trng_adapter/trng_adapter.h>
julhal011260f102021-02-15 17:34:08 +000011#include <service/secure_storage/frontend/psa/its/its_frontend.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010012#include <protocols/rpc/common/packed-c/status.h>
13#include <psa/crypto.h>
14
15/* Service request handlers */
16static rpc_status_t nop_handler(void *context, struct call_req* req);
17static rpc_status_t generate_key_handler(void *context, struct call_req* req);
18static rpc_status_t destroy_key_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010019static rpc_status_t export_key_handler(void *context, struct call_req* req);
20static rpc_status_t export_public_key_handler(void *context, struct call_req* req);
21static rpc_status_t import_key_handler(void *context, struct call_req* req);
22static rpc_status_t sign_hash_handler(void *context, struct call_req* req);
23static rpc_status_t verify_hash_handler(void *context, struct call_req* req);
24static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req);
25static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req);
26static rpc_status_t generate_random_handler(void *context, struct call_req* req);
Julian Hallf5728962021-06-24 09:40:23 +010027static rpc_status_t hash_setup_handler(void *context, struct call_req* req);
28static rpc_status_t hash_update_handler(void *context, struct call_req* req);
29static rpc_status_t hash_finish_handler(void *context, struct call_req* req);
Julian Hallc02fffb2020-11-23 18:22:06 +010030
31/* Handler mapping table for service */
32static const struct service_handler handler_table[] = {
Julian Hallf5728962021-06-24 09:40:23 +010033 {TS_CRYPTO_OPCODE_NOP, nop_handler},
34 {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler},
35 {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler},
36 {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler},
37 {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler},
38 {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler},
39 {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler},
40 {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler},
41 {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler},
42 {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler},
43 {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler},
44 {TS_CRYPTO_OPCODE_HASH_SETUP, hash_setup_handler},
45 {TS_CRYPTO_OPCODE_HASH_UPDATE, hash_update_handler},
46 {TS_CRYPTO_OPCODE_HASH_FINISH, hash_finish_handler}
Julian Hallc02fffb2020-11-23 18:22:06 +010047};
48
julhal01c3f4e9a2020-12-15 13:39:01 +000049struct rpc_interface *mbed_crypto_provider_init(struct mbed_crypto_provider *context,
Julian Hallf5728962021-06-24 09:40:23 +010050 struct storage_backend *storage_backend,
51 int trng_instance)
Julian Hallc02fffb2020-11-23 18:22:06 +010052{
Julian Hallf5728962021-06-24 09:40:23 +010053 struct rpc_interface *rpc_interface = NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010054
Julian Hallf5728962021-06-24 09:40:23 +010055 crypto_context_pool_init(&context->context_pool);
56 trng_adapter_init(trng_instance);
julhal01ffa98d82021-01-20 13:51:58 +000057
Julian Hallf5728962021-06-24 09:40:23 +010058 /*
59 * A storage provider is required for persistent key storage. As this
60 * is a mandatory feature of the crypto service, insist on a storage
61 * provider being available.
62 */
63 if (context && storage_backend) {
Julian Hallc02fffb2020-11-23 18:22:06 +010064
Julian Hallf5728962021-06-24 09:40:23 +010065 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
66 context->serializers[encoding] = NULL;
julhal01c3f4e9a2020-12-15 13:39:01 +000067
Julian Hallf5728962021-06-24 09:40:23 +010068 service_provider_init(&context->base_provider, context,
69 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
Julian Hallc02fffb2020-11-23 18:22:06 +010070
Julian Hallf5728962021-06-24 09:40:23 +010071 if ((psa_its_frontend_init(storage_backend) == PSA_SUCCESS) &&
72 (psa_crypto_init() == PSA_SUCCESS)) {
julhal011260f102021-02-15 17:34:08 +000073
Julian Hallf5728962021-06-24 09:40:23 +010074 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
75 }
76 }
Julian Hallc02fffb2020-11-23 18:22:06 +010077
Julian Hallf5728962021-06-24 09:40:23 +010078 return rpc_interface;
Julian Hallc02fffb2020-11-23 18:22:06 +010079}
80
81void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context)
82{
Julian Hallf5728962021-06-24 09:40:23 +010083 trng_adapter_deinit();
84 crypto_context_pool_deinit(&context->context_pool);
Julian Hallc02fffb2020-11-23 18:22:06 +010085}
86
julhal01c3f4e9a2020-12-15 13:39:01 +000087void mbed_crypto_provider_register_serializer(struct mbed_crypto_provider *context,
Julian Hallf5728962021-06-24 09:40:23 +010088 unsigned int encoding, const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010089{
Julian Hallf5728962021-06-24 09:40:23 +010090 if (encoding < TS_RPC_ENCODING_LIMIT)
91 context->serializers[encoding] = serializer;
julhal01c3f4e9a2020-12-15 13:39:01 +000092}
93
94static const struct crypto_provider_serializer* get_crypto_serializer(void *context,
Julian Hallf5728962021-06-24 09:40:23 +010095 const struct call_req *req)
julhal01c3f4e9a2020-12-15 13:39:01 +000096{
Julian Hallf5728962021-06-24 09:40:23 +010097 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
98 const struct crypto_provider_serializer* serializer = NULL;
99 unsigned int encoding = call_req_get_encoding(req);
julhal01c3f4e9a2020-12-15 13:39:01 +0000100
Julian Hallf5728962021-06-24 09:40:23 +0100101 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = this_instance->serializers[encoding];
julhal01c3f4e9a2020-12-15 13:39:01 +0000102
Julian Hallf5728962021-06-24 09:40:23 +0100103 return serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +0100104}
105
106static rpc_status_t nop_handler(void *context, struct call_req* req)
107{
Julian Hallf5728962021-06-24 09:40:23 +0100108 /* Responds to a request by returning success */
109 rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED;
110 psa_status_t psa_status = PSA_SUCCESS;
Julian Hallc02fffb2020-11-23 18:22:06 +0100111
Julian Hallf5728962021-06-24 09:40:23 +0100112 (void)context;
113 call_req_set_opstatus(req, psa_status);
Julian Hallc02fffb2020-11-23 18:22:06 +0100114
Julian Hallf5728962021-06-24 09:40:23 +0100115 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100116}
117
118static rpc_status_t generate_key_handler(void *context, struct call_req* req)
119{
Julian Hallf5728962021-06-24 09:40:23 +0100120 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
121 struct call_param_buf *req_buf = call_req_get_req_buf(req);
122 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100123
Julian Hallf5728962021-06-24 09:40:23 +0100124 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100125
Julian Hallf5728962021-06-24 09:40:23 +0100126 if (serializer)
127 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100128
Julian Hallf5728962021-06-24 09:40:23 +0100129 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100130
Julian Hallf5728962021-06-24 09:40:23 +0100131 psa_status_t psa_status;
132 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100133
Julian Hallf5728962021-06-24 09:40:23 +0100134 psa_status = psa_generate_key(&attributes, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100135
Julian Hallf5728962021-06-24 09:40:23 +0100136 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100137
Julian Hallf5728962021-06-24 09:40:23 +0100138 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
139 rpc_status = serializer->serialize_generate_key_resp(resp_buf, id);
140 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100141
Julian Hallf5728962021-06-24 09:40:23 +0100142 call_req_set_opstatus(req, psa_status);
143 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100144
Julian Hallf5728962021-06-24 09:40:23 +0100145 psa_reset_key_attributes(&attributes);
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 destroy_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_destroy_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;
Julian Hallc02fffb2020-11-23 18:22:06 +0100164
Julian Hallf5728962021-06-24 09:40:23 +0100165 psa_status = psa_destroy_key(id);
166 call_req_set_opstatus(req, psa_status);
167 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100168
Julian Hallf5728962021-06-24 09:40:23 +0100169 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100170}
171
172static rpc_status_t export_key_handler(void *context, struct call_req* req)
173{
Julian Hallf5728962021-06-24 09:40:23 +0100174 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
175 struct call_param_buf *req_buf = call_req_get_req_buf(req);
176 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100177
Julian Hallf5728962021-06-24 09:40:23 +0100178 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100179
Julian Hallf5728962021-06-24 09:40:23 +0100180 if (serializer)
181 rpc_status = serializer->deserialize_export_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100182
Julian Hallf5728962021-06-24 09:40:23 +0100183 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100184
Julian Hallf5728962021-06-24 09:40:23 +0100185 psa_status_t psa_status;
186 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100187
Julian Hallf5728962021-06-24 09:40:23 +0100188 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100189
Julian Hallf5728962021-06-24 09:40:23 +0100190 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100191
Julian Hallf5728962021-06-24 09:40:23 +0100192 size_t max_export_size = PSA_EXPORT_KEY_OUTPUT_SIZE(
193 psa_get_key_type(&attributes),
194 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100195
Julian Hallf5728962021-06-24 09:40:23 +0100196 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100197
Julian Hallf5728962021-06-24 09:40:23 +0100198 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100199
Julian Hallf5728962021-06-24 09:40:23 +0100200 size_t export_size;
201 psa_status = psa_export_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100202
Julian Hallf5728962021-06-24 09:40:23 +0100203 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100204
Julian Hallf5728962021-06-24 09:40:23 +0100205 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
206 rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size);
207 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100208
Julian Hallf5728962021-06-24 09:40:23 +0100209 free(key_buffer);
210 }
211 else {
212 /* Failed to allocate key buffer */
213 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
214 }
215 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100216
Julian Hallf5728962021-06-24 09:40:23 +0100217 call_req_set_opstatus(req, psa_status);
218 psa_reset_key_attributes(&attributes);
219 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100220
Julian Hallf5728962021-06-24 09:40:23 +0100221 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100222}
223
224static rpc_status_t export_public_key_handler(void *context, struct call_req* req)
225{
Julian Hallf5728962021-06-24 09:40:23 +0100226 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
227 struct call_param_buf *req_buf = call_req_get_req_buf(req);
228 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100229
Julian Hallf5728962021-06-24 09:40:23 +0100230 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100231
Julian Hallf5728962021-06-24 09:40:23 +0100232 if (serializer)
233 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100234
Julian Hallf5728962021-06-24 09:40:23 +0100235 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100236
Julian Hallf5728962021-06-24 09:40:23 +0100237 psa_status_t psa_status;
238 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100239
Julian Hallf5728962021-06-24 09:40:23 +0100240 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100241
Julian Hallf5728962021-06-24 09:40:23 +0100242 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100243
Julian Hallf5728962021-06-24 09:40:23 +0100244 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(
245 PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)),
246 psa_get_key_bits(&attributes));
Julian Hallc02fffb2020-11-23 18:22:06 +0100247
Julian Hallf5728962021-06-24 09:40:23 +0100248 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100249
Julian Hallf5728962021-06-24 09:40:23 +0100250 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100251
Julian Hallf5728962021-06-24 09:40:23 +0100252 size_t export_size;
253 psa_status = psa_export_public_key(id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100254
Julian Hallf5728962021-06-24 09:40:23 +0100255 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100256
Julian Hallf5728962021-06-24 09:40:23 +0100257 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
258 rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size);
259 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100260
Julian Hallf5728962021-06-24 09:40:23 +0100261 free(key_buffer);
262 }
263 else {
264 /* Failed to allocate key buffer */
265 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
266 }
267 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100268
Julian Hallf5728962021-06-24 09:40:23 +0100269 call_req_set_opstatus(req, psa_status);
270 psa_reset_key_attributes(&attributes);
271 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100272
Julian Hallf5728962021-06-24 09:40:23 +0100273 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100274}
275
276static rpc_status_t import_key_handler(void *context, struct call_req* req)
277{
Julian Hallf5728962021-06-24 09:40:23 +0100278 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
279 struct call_param_buf *req_buf = call_req_get_req_buf(req);
280 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100281
Julian Hallf5728962021-06-24 09:40:23 +0100282 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100283
Julian Hallf5728962021-06-24 09:40:23 +0100284 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
285 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100286
Julian Hallf5728962021-06-24 09:40:23 +0100287 if (key_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100288
Julian Hallf5728962021-06-24 09:40:23 +0100289 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
290 rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100291
Julian Hallf5728962021-06-24 09:40:23 +0100292 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100293
Julian Hallf5728962021-06-24 09:40:23 +0100294 psa_status_t psa_status;
295 psa_key_id_t id;
Julian Hallc02fffb2020-11-23 18:22:06 +0100296
Julian Hallf5728962021-06-24 09:40:23 +0100297 psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100298
Julian Hallf5728962021-06-24 09:40:23 +0100299 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000300
Julian Hallf5728962021-06-24 09:40:23 +0100301 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
302 rpc_status = serializer->serialize_import_key_resp(resp_buf, id);
303 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000304
Julian Hallf5728962021-06-24 09:40:23 +0100305 call_req_set_opstatus(req, psa_status);
306 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100307
Julian Hallf5728962021-06-24 09:40:23 +0100308 psa_reset_key_attributes(&attributes);
309 free(key_buffer);
310 }
311 else {
Julian Hallc02fffb2020-11-23 18:22:06 +0100312
Julian Hallf5728962021-06-24 09:40:23 +0100313 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
314 }
315 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100316
Julian Hallf5728962021-06-24 09:40:23 +0100317 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100318}
319
320static rpc_status_t sign_hash_handler(void *context, struct call_req* req)
321{
Julian Hallf5728962021-06-24 09:40:23 +0100322 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
323 struct call_param_buf *req_buf = call_req_get_req_buf(req);
324 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100325
Julian Hallf5728962021-06-24 09:40:23 +0100326 psa_key_id_t id;
327 psa_algorithm_t alg;
328 size_t hash_len = PSA_HASH_MAX_SIZE;
329 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100330
Julian Hallf5728962021-06-24 09:40:23 +0100331 if (serializer)
332 rpc_status = serializer->deserialize_sign_hash_req(req_buf, &id, &alg, hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100333
Julian Hallf5728962021-06-24 09:40:23 +0100334 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100335
Julian Hallf5728962021-06-24 09:40:23 +0100336 psa_status_t psa_status;
337 size_t sig_len;
338 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100339
Julian Hallf5728962021-06-24 09:40:23 +0100340 psa_status = psa_sign_hash(id, alg,
341 hash_buffer, hash_len,
342 sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100343
Julian Hallf5728962021-06-24 09:40:23 +0100344 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100345
Julian Hallf5728962021-06-24 09:40:23 +0100346 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
347 rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len);
348 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100349
Julian Hallf5728962021-06-24 09:40:23 +0100350 call_req_set_opstatus(req, psa_status);
351 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100352
Julian Hallf5728962021-06-24 09:40:23 +0100353 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100354}
355
356static rpc_status_t verify_hash_handler(void *context, struct call_req* req)
357{
Julian Hallf5728962021-06-24 09:40:23 +0100358 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
359 struct call_param_buf *req_buf = call_req_get_req_buf(req);
360 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100361
Julian Hallf5728962021-06-24 09:40:23 +0100362 psa_key_id_t id;
363 psa_algorithm_t alg;
364 size_t hash_len = PSA_HASH_MAX_SIZE;
365 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
366 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
367 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100368
Julian Hallf5728962021-06-24 09:40:23 +0100369 if (serializer)
370 rpc_status = serializer->deserialize_verify_hash_req(req_buf, &id, &alg,
371 hash_buffer, &hash_len,
372 sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100373
Julian Hallf5728962021-06-24 09:40:23 +0100374 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100375
Julian Hallf5728962021-06-24 09:40:23 +0100376 psa_status_t psa_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100377
Julian Hallf5728962021-06-24 09:40:23 +0100378 psa_status = psa_verify_hash(id, alg,
379 hash_buffer, hash_len,
380 sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100381
Julian Hallf5728962021-06-24 09:40:23 +0100382 call_req_set_opstatus(req, psa_status);
383 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100384
Julian Hallf5728962021-06-24 09:40:23 +0100385 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100386}
387
388static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req)
389{
Julian Hallf5728962021-06-24 09:40:23 +0100390 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
391 struct call_param_buf *req_buf = call_req_get_req_buf(req);
392 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100393
Julian Hallf5728962021-06-24 09:40:23 +0100394 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100395
Julian Hallf5728962021-06-24 09:40:23 +0100396 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100397
Julian Hallf5728962021-06-24 09:40:23 +0100398 psa_key_id_t id;
399 psa_algorithm_t alg;
400 size_t ciphertext_len = max_param_size;
401 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
402 size_t salt_len = max_param_size;
403 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100404
Julian Hallf5728962021-06-24 09:40:23 +0100405 if (ciphertext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100406
Julian Hallf5728962021-06-24 09:40:23 +0100407 rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf,
408 &id, &alg,
409 ciphertext_buffer, &ciphertext_len,
410 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100411
Julian Hallf5728962021-06-24 09:40:23 +0100412 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100413
Julian Hallf5728962021-06-24 09:40:23 +0100414 psa_status_t psa_status;
415 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100416
Julian Hallf5728962021-06-24 09:40:23 +0100417 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100418
Julian Hallf5728962021-06-24 09:40:23 +0100419 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100420
Julian Hallf5728962021-06-24 09:40:23 +0100421 size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
422 psa_get_key_type(&attributes),
423 psa_get_key_bits(&attributes),
424 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100425
Julian Hallf5728962021-06-24 09:40:23 +0100426 size_t plaintext_len;
427 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100428
Julian Hallf5728962021-06-24 09:40:23 +0100429 if (plaintext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100430
Julian Hallf5728962021-06-24 09:40:23 +0100431 /* Salt is an optional parameter */
432 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100433
Julian Hallf5728962021-06-24 09:40:23 +0100434 psa_status = psa_asymmetric_decrypt(id, alg,
435 ciphertext_buffer, ciphertext_len,
436 salt, salt_len,
437 plaintext_buffer, max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000438
Julian Hallf5728962021-06-24 09:40:23 +0100439 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000440
Julian Hallf5728962021-06-24 09:40:23 +0100441 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
442 rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf,
443 plaintext_buffer, plaintext_len);
444 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000445
Julian Hallf5728962021-06-24 09:40:23 +0100446 free(plaintext_buffer);
447 }
448 else {
449 /* Failed to allocate ouptput buffer */
450 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
451 }
452 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100453
Julian Hallf5728962021-06-24 09:40:23 +0100454 call_req_set_opstatus(req, psa_status);
455 psa_reset_key_attributes(&attributes);
456 }
457 }
458 else {
459 /* Failed to allocate buffers */
460 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
461 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100462
Julian Hallf5728962021-06-24 09:40:23 +0100463 free(ciphertext_buffer);
464 free(salt_buffer);
465 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100466
Julian Hallf5728962021-06-24 09:40:23 +0100467 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100468}
469
470static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req)
471{
Julian Hallf5728962021-06-24 09:40:23 +0100472 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
473 struct call_param_buf *req_buf = call_req_get_req_buf(req);
474 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100475
Julian Hallf5728962021-06-24 09:40:23 +0100476 if (serializer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100477
Julian Hallf5728962021-06-24 09:40:23 +0100478 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100479
Julian Hallf5728962021-06-24 09:40:23 +0100480 psa_key_id_t id;
481 psa_algorithm_t alg;
482 size_t plaintext_len = max_param_size;
483 uint8_t *plaintext_buffer = malloc(plaintext_len);
484 size_t salt_len = max_param_size;
485 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100486
Julian Hallf5728962021-06-24 09:40:23 +0100487 if (plaintext_buffer && salt_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100488
Julian Hallf5728962021-06-24 09:40:23 +0100489 rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf,
490 &id, &alg,
491 plaintext_buffer, &plaintext_len,
492 salt_buffer, &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100493
Julian Hallf5728962021-06-24 09:40:23 +0100494 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100495
Julian Hallf5728962021-06-24 09:40:23 +0100496 psa_status_t psa_status;
497 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100498
Julian Hallf5728962021-06-24 09:40:23 +0100499 psa_status = psa_get_key_attributes(id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100500
Julian Hallf5728962021-06-24 09:40:23 +0100501 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100502
Julian Hallf5728962021-06-24 09:40:23 +0100503 size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
504 psa_get_key_type(&attributes),
505 psa_get_key_bits(&attributes),
506 alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100507
Julian Hallf5728962021-06-24 09:40:23 +0100508 size_t ciphertext_len;
509 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100510
Julian Hallf5728962021-06-24 09:40:23 +0100511 if (ciphertext_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100512
Julian Hallf5728962021-06-24 09:40:23 +0100513 /* Salt is an optional parameter */
514 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100515
Julian Hallf5728962021-06-24 09:40:23 +0100516 psa_status = psa_asymmetric_encrypt(id, alg,
517 plaintext_buffer, plaintext_len,
518 salt, salt_len,
519 ciphertext_buffer, max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000520
Julian Hallf5728962021-06-24 09:40:23 +0100521 if (psa_status == PSA_SUCCESS) {
julhal01c3f4e9a2020-12-15 13:39:01 +0000522
Julian Hallf5728962021-06-24 09:40:23 +0100523 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
524 rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf,
525 ciphertext_buffer, ciphertext_len);
526 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000527
Julian Hallf5728962021-06-24 09:40:23 +0100528 free(ciphertext_buffer);
529 }
530 else {
531 /* Failed to allocate ouptput buffer */
532 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
533 }
534 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100535
Julian Hallf5728962021-06-24 09:40:23 +0100536 call_req_set_opstatus(req, psa_status);
537 psa_reset_key_attributes(&attributes);
538 }
539 }
540 else {
541 /* Failed to allocate buffers */
542 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
543 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100544
Julian Hallf5728962021-06-24 09:40:23 +0100545 free(plaintext_buffer);
546 free(salt_buffer);
547 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100548
Julian Hallf5728962021-06-24 09:40:23 +0100549 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100550}
551
552static rpc_status_t generate_random_handler(void *context, struct call_req* req)
553{
Julian Hallf5728962021-06-24 09:40:23 +0100554 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
555 struct call_param_buf *req_buf = call_req_get_req_buf(req);
556 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100557
Julian Hallf5728962021-06-24 09:40:23 +0100558 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100559
Julian Hallf5728962021-06-24 09:40:23 +0100560 if (serializer)
561 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100562
Julian Hallf5728962021-06-24 09:40:23 +0100563 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100564
Julian Hallf5728962021-06-24 09:40:23 +0100565 psa_status_t psa_status;
566 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100567
Julian Hallf5728962021-06-24 09:40:23 +0100568 if (output_buffer) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100569
Julian Hallf5728962021-06-24 09:40:23 +0100570 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100571
Julian Hallf5728962021-06-24 09:40:23 +0100572 if (psa_status == PSA_SUCCESS) {
Julian Hallc02fffb2020-11-23 18:22:06 +0100573
Julian Hallf5728962021-06-24 09:40:23 +0100574 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
575 rpc_status = serializer->serialize_generate_random_resp(resp_buf,
576 output_buffer, output_size);
577 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100578
Julian Hallf5728962021-06-24 09:40:23 +0100579 call_req_set_opstatus(req, psa_status);
580 free(output_buffer);
581 }
582 else {
583 /* Failed to allocate output buffer */
584 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
585 }
586 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100587
Julian Hallf5728962021-06-24 09:40:23 +0100588 return rpc_status;
589}
590
591static rpc_status_t hash_setup_handler(void *context, struct call_req* req)
592{
593 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
594 struct call_param_buf *req_buf = call_req_get_req_buf(req);
595 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
596 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
597
598 psa_algorithm_t alg;
599
600 if (serializer)
601 rpc_status = serializer->deserialize_hash_setup_req(req_buf, &alg);
602
603 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
604
605 uint32_t op_handle;
606
607 struct crypto_context *crypto_context =
608 crypto_context_pool_alloc(&this_instance->context_pool,
609 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
610 &op_handle);
611
612 if (crypto_context) {
613
614 psa_status_t psa_status;
615
616 crypto_context->op.hash = psa_hash_operation_init();
617 psa_status = psa_hash_setup(&crypto_context->op.hash, alg);
618
619 if (psa_status == PSA_SUCCESS) {
620
621 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
622 rpc_status = serializer->serialize_hash_setup_resp(resp_buf, op_handle);
623 }
624
625 if ((psa_status != PSA_SUCCESS) || (rpc_status != TS_RPC_CALL_ACCEPTED)) {
626
627 crypto_context_pool_free(&this_instance->context_pool, crypto_context);
628 }
629
630 call_req_set_opstatus(req, psa_status);
631 }
632 else {
633 /* Failed to allocate crypto context for transaction */
634 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
635 }
636 }
637
638 return rpc_status;
639}
640
641static rpc_status_t hash_update_handler(void *context, struct call_req* req)
642{
643 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
644 struct call_param_buf *req_buf = call_req_get_req_buf(req);
645 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
646 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
647
648 uint32_t op_handle;
649 const uint8_t *data;
650 size_t data_len;
651
652 if (serializer)
653 rpc_status = serializer->deserialize_hash_update_req(req_buf, &op_handle, &data, &data_len);
654
655 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
656
657 struct crypto_context *crypto_context =
658 crypto_context_pool_find(&this_instance->context_pool,
659 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
660 op_handle);
661
662 if (crypto_context) {
663
664 psa_status_t psa_status = psa_hash_update(&crypto_context->op.hash, data, data_len);
665 call_req_set_opstatus(req, psa_status);
666 }
667 else {
668 /* Requested context doesn't exist */
669 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
670 }
671 }
672
673 return rpc_status;
674}
675
676static rpc_status_t hash_finish_handler(void *context, struct call_req* req)
677{
678 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
679 struct call_param_buf *req_buf = call_req_get_req_buf(req);
680 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
681 struct mbed_crypto_provider *this_instance = (struct mbed_crypto_provider*)context;
682
683 uint32_t op_handle;
684
685 if (serializer)
686 rpc_status = serializer->deserialize_hash_finish_req(req_buf, &op_handle);
687
688 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
689
690 struct crypto_context *crypto_context =
691 crypto_context_pool_find(&this_instance->context_pool,
692 CRYPTO_CONTEXT_OP_ID_HASH, call_req_get_caller_id(req),
693 op_handle);
694
695 if (crypto_context) {
696
697 psa_status_t psa_status;
698 size_t hash_len;
699 uint8_t hash[PSA_HASH_MAX_SIZE];
700
701 psa_status = psa_hash_finish(&crypto_context->op.hash, hash, sizeof(hash), &hash_len);
702
703 if (psa_status == PSA_SUCCESS) {
704
705 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
706 rpc_status = serializer->serialize_hash_finish_resp(resp_buf, hash, hash_len);
707 }
708
709 crypto_context_pool_free(&this_instance->context_pool, crypto_context);
710
711 call_req_set_opstatus(req, psa_status);
712 }
713 else {
714 /* Requested context doesn't exist */
715 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
716 }
717 }
718
719 return rpc_status;
julhal01c3f4e9a2020-12-15 13:39:01 +0000720}