blob: f94b47eb73f4f67e66e056e5d22f94b73a4d4962 [file] [log] [blame]
Julian Hallc02fffb2020-11-23 18:22:06 +01001/*
Gabor Tothab7db212023-08-18 16:08:12 +02002 * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
Julian Hallc02fffb2020-11-23 18:22:06 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
Gabor Tothaf77b472024-04-05 11:19:37 +02006#include <protocols/common/efi/efi_status.h>
Imre Kis6d867d82023-07-04 13:29:33 +02007#include <protocols/rpc/common/packed-c/status.h>
8#include <protocols/service/crypto/packed-c/opcodes.h>
Balint Dobszaydc945e92024-01-15 16:07:21 +01009#include <service/crypto/backend/crypto_backend.h>
Imre Kis6d867d82023-07-04 13:29:33 +020010#include <service/crypto/provider/crypto_provider.h>
Gabor Tothaf77b472024-04-05 11:19:37 +020011#include <compiler.h>
Julian Hallc02fffb2020-11-23 18:22:06 +010012#include <stdint.h>
13#include <stdlib.h>
Gabor Tothaf77b472024-04-05 11:19:37 +020014#include <string.h>
Imre Kis6d867d82023-07-04 13:29:33 +020015
Balint Dobszaydc945e92024-01-15 16:07:21 +010016#include "crypto_partition.h"
Imre Kis6d867d82023-07-04 13:29:33 +020017#include "crypto_uuid.h"
Julian Hallc02fffb2020-11-23 18:22:06 +010018
Gabor Tothaf77b472024-04-05 11:19:37 +020019#if defined(MBEDTLS_PKCS7_C) && defined(MBEDTLS_X509_CRT_PARSE_C)
20#include "common/mbedtls/mbedtls_utils.h"
21#endif
22
Julian Hallc02fffb2020-11-23 18:22:06 +010023/* Service request handlers */
Imre Kis6d867d82023-07-04 13:29:33 +020024static rpc_status_t generate_key_handler(void *context, struct rpc_request *req);
25static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req);
26static rpc_status_t export_key_handler(void *context, struct rpc_request *req);
27static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req);
28static rpc_status_t import_key_handler(void *context, struct rpc_request *req);
29static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req);
30static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req);
31static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req);
32static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req);
33static rpc_status_t generate_random_handler(void *context, struct rpc_request *req);
34static rpc_status_t copy_key_handler(void *context, struct rpc_request *req);
35static rpc_status_t purge_key_handler(void *context, struct rpc_request *req);
36static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req);
Gabor Tothab7db212023-08-18 16:08:12 +020037static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req);
Gabor Tothaf77b472024-04-05 11:19:37 +020038static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req);
Julian Hallc02fffb2020-11-23 18:22:06 +010039
40/* Handler mapping table for service */
41static const struct service_handler handler_table[] = {
Gabor Tothaf77b472024-04-05 11:19:37 +020042 { TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler },
43 { TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler },
44 { TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler },
45 { TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler },
46 { TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler },
47 { TS_CRYPTO_OPCODE_SIGN_HASH, asymmetric_sign_handler },
48 { TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_handler },
49 { TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler },
50 { TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler },
51 { TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler },
52 { TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler },
53 { TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler },
54 { TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler },
55 { TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler },
56 { TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_handler },
57 { TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE, verify_pkcs7_signature_handler },
58 { TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT, get_uefi_priv_auth_var_fingerprint_handler },
Julian Hallc02fffb2020-11-23 18:22:06 +010059};
60
Imre Kis6d867d82023-07-04 13:29:33 +020061struct rpc_service_interface *
62crypto_provider_init(struct crypto_provider *context, unsigned int encoding,
63 const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010064{
Imre Kis6d867d82023-07-04 13:29:33 +020065 const struct rpc_uuid crypto_service_uuid[2] = {
66 { .uuid = TS_PSA_CRYPTO_SERVICE_UUID },
67 { .uuid = TS_PSA_CRYPTO_PROTOBUF_SERVICE_UUID },
68 };
Julian Hallc02fffb2020-11-23 18:22:06 +010069
Imre Kis6d867d82023-07-04 13:29:33 +020070 if (encoding >= TS_RPC_ENCODING_LIMIT)
71 return NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +010072
Imre Kis6d867d82023-07-04 13:29:33 +020073 context->serializer = serializer;
74
75 service_provider_init(&context->base_provider, context, &crypto_service_uuid[encoding],
76 handler_table,
77 sizeof(handler_table) / sizeof(struct service_handler));
Julian Hall3e614542021-07-29 11:47:47 +010078
Julian Hall9061e6c2021-06-29 14:24:20 +010079 return service_provider_get_rpc_interface(&context->base_provider);
Julian Hallc02fffb2020-11-23 18:22:06 +010080}
81
Julian Hall9061e6c2021-06-29 14:24:20 +010082void crypto_provider_deinit(struct crypto_provider *context)
Julian Hallc02fffb2020-11-23 18:22:06 +010083{
Imre Kis6d867d82023-07-04 13:29:33 +020084 (void)context;
Julian Hallc02fffb2020-11-23 18:22:06 +010085}
86
Julian Hall9061e6c2021-06-29 14:24:20 +010087void crypto_provider_register_serializer(struct crypto_provider *context,
Imre Kis6d867d82023-07-04 13:29:33 +020088 const struct crypto_provider_serializer *serializer)
Julian Hallc02fffb2020-11-23 18:22:06 +010089{
Imre Kis6d867d82023-07-04 13:29:33 +020090 context->serializer = serializer;
julhal01c3f4e9a2020-12-15 13:39:01 +000091}
92
Imre Kis6d867d82023-07-04 13:29:33 +020093void crypto_provider_extend(struct crypto_provider *context, struct service_provider *sub_provider)
Julian Hall13e76952021-07-13 12:17:09 +010094{
95 service_provider_extend(&context->base_provider, sub_provider);
96}
97
Imre Kis6d867d82023-07-04 13:29:33 +020098static const struct crypto_provider_serializer *get_crypto_serializer(void *context,
99 const struct rpc_request *req)
julhal01c3f4e9a2020-12-15 13:39:01 +0000100{
Imre Kis6d867d82023-07-04 13:29:33 +0200101 struct crypto_provider *this_instance = (struct crypto_provider *)context;
julhal01c3f4e9a2020-12-15 13:39:01 +0000102
Imre Kis6d867d82023-07-04 13:29:33 +0200103 return this_instance->serializer;
Julian Hallc02fffb2020-11-23 18:22:06 +0100104}
105
Imre Kis6d867d82023-07-04 13:29:33 +0200106static rpc_status_t generate_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100107{
Imre Kis6d867d82023-07-04 13:29:33 +0200108 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
109 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100110 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100111
Julian Hallf5728962021-06-24 09:40:23 +0100112 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100113
Julian Hallf5728962021-06-24 09:40:23 +0100114 if (serializer)
115 rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100116
Imre Kis6d867d82023-07-04 13:29:33 +0200117 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100118 psa_status_t psa_status;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100119 namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
Julian Hallc02fffb2020-11-23 18:22:06 +0100120
Balint Dobszaydc945e92024-01-15 16:07:21 +0100121 crypto_partition_bind_to_owner(&attributes, req->source_id);
122
123 psa_status = psa_generate_key(&attributes, &ns_key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100124
Julian Hallf5728962021-06-24 09:40:23 +0100125 if (psa_status == PSA_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100126 psa_key_id_t key_id = namespaced_key_id_get_key_id(ns_key_id);
Imre Kis6d867d82023-07-04 13:29:33 +0200127 struct rpc_buffer *resp_buf = &req->response;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100128 rpc_status = serializer->serialize_generate_key_resp(resp_buf, key_id);
Julian Hallf5728962021-06-24 09:40:23 +0100129 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100130
Imre Kis6d867d82023-07-04 13:29:33 +0200131 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100132 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100133
Julian Hallf5728962021-06-24 09:40:23 +0100134 psa_reset_key_attributes(&attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100135
Julian Hallf5728962021-06-24 09:40:23 +0100136 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100137}
138
Imre Kis6d867d82023-07-04 13:29:33 +0200139static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100140{
Imre Kis6d867d82023-07-04 13:29:33 +0200141 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
142 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100143 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100144
Balint Dobszaydc945e92024-01-15 16:07:21 +0100145 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +0100146
Julian Hallf5728962021-06-24 09:40:23 +0100147 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100148 rpc_status = serializer->deserialize_destroy_key_req(req_buf, &key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100149
Imre Kis6d867d82023-07-04 13:29:33 +0200150 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100151 psa_status_t psa_status;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100152 namespaced_key_id_t ns_key_id =
153 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100154
Balint Dobszaydc945e92024-01-15 16:07:21 +0100155 psa_status = psa_destroy_key(ns_key_id);
Imre Kis6d867d82023-07-04 13:29:33 +0200156 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100157 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100158
Julian Hallf5728962021-06-24 09:40:23 +0100159 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100160}
161
Imre Kis6d867d82023-07-04 13:29:33 +0200162static rpc_status_t export_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100163{
Imre Kis6d867d82023-07-04 13:29:33 +0200164 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
165 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100166 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100167
Balint Dobszaydc945e92024-01-15 16:07:21 +0100168 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +0100169
Julian Hallf5728962021-06-24 09:40:23 +0100170 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100171 rpc_status = serializer->deserialize_export_key_req(req_buf, &key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100172
Imre Kis6d867d82023-07-04 13:29:33 +0200173 if (rpc_status == RPC_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100174 namespaced_key_id_t ns_key_id =
175 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hall464021a2021-07-29 15:20:10 +0100176 size_t max_export_size = PSA_EXPORT_KEY_PAIR_MAX_SIZE;
177 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100178
Julian Hall464021a2021-07-29 15:20:10 +0100179 if (key_buffer) {
Julian Hall464021a2021-07-29 15:20:10 +0100180 size_t export_size;
Imre Kis6d867d82023-07-04 13:29:33 +0200181 psa_status_t psa_status =
Balint Dobszaydc945e92024-01-15 16:07:21 +0100182 psa_export_key(ns_key_id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100183
Julian Hall464021a2021-07-29 15:20:10 +0100184 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200185 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100186
Imre Kis6d867d82023-07-04 13:29:33 +0200187 rpc_status = serializer->serialize_export_key_resp(
188 resp_buf, key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100189 }
Julian Hallec81a502021-07-12 11:36:37 +0100190
Julian Hall464021a2021-07-29 15:20:10 +0100191 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200192 req->service_status = psa_status;
193 } else {
Julian Hall464021a2021-07-29 15:20:10 +0100194 /* Failed to allocate key buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200195 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hall464021a2021-07-29 15:20:10 +0100196 }
Julian Hallf5728962021-06-24 09:40:23 +0100197 }
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
Imre Kis6d867d82023-07-04 13:29:33 +0200202static rpc_status_t export_public_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100203{
Imre Kis6d867d82023-07-04 13:29:33 +0200204 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
205 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100206 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100207
Balint Dobszaydc945e92024-01-15 16:07:21 +0100208 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallc02fffb2020-11-23 18:22:06 +0100209
Julian Hallf5728962021-06-24 09:40:23 +0100210 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100211 rpc_status = serializer->deserialize_export_public_key_req(req_buf, &key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100212
Imre Kis6d867d82023-07-04 13:29:33 +0200213 if (rpc_status == RPC_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100214 namespaced_key_id_t ns_key_id =
215 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallec81a502021-07-12 11:36:37 +0100216 size_t max_export_size = PSA_EXPORT_PUBLIC_KEY_MAX_SIZE;
217 uint8_t *key_buffer = malloc(max_export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100218
Julian Hallec81a502021-07-12 11:36:37 +0100219 if (key_buffer) {
Julian Hallec81a502021-07-12 11:36:37 +0100220 size_t export_size;
Imre Kis6d867d82023-07-04 13:29:33 +0200221 psa_status_t psa_status = psa_export_public_key(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100222 ns_key_id, key_buffer, max_export_size, &export_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100223
Julian Hallec81a502021-07-12 11:36:37 +0100224 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200225 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100226
Imre Kis6d867d82023-07-04 13:29:33 +0200227 rpc_status = serializer->serialize_export_public_key_resp(
228 resp_buf, key_buffer, export_size);
Julian Hallf5728962021-06-24 09:40:23 +0100229 }
Julian Hallec81a502021-07-12 11:36:37 +0100230
231 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200232 req->service_status = psa_status;
233 } else {
Julian Hallec81a502021-07-12 11:36:37 +0100234 /* Failed to allocate key buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200235 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallec81a502021-07-12 11:36:37 +0100236 }
Julian Hallf5728962021-06-24 09:40:23 +0100237 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100238
Julian Hallf5728962021-06-24 09:40:23 +0100239 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100240}
241
Imre Kis6d867d82023-07-04 13:29:33 +0200242static rpc_status_t import_key_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100243{
Imre Kis6d867d82023-07-04 13:29:33 +0200244 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
245 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100246 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100247
Julian Hallf5728962021-06-24 09:40:23 +0100248 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100249 size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf);
250 uint8_t *key_buffer = malloc(key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100251
Julian Hallf5728962021-06-24 09:40:23 +0100252 if (key_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100253 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Imre Kis6d867d82023-07-04 13:29:33 +0200254 rpc_status = serializer->deserialize_import_key_req(
255 req_buf, &attributes, key_buffer, &key_data_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100256
Imre Kis6d867d82023-07-04 13:29:33 +0200257 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100258 psa_status_t psa_status;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100259 namespaced_key_id_t ns_key_id = NAMESPACED_KEY_ID_INIT;
260
261 crypto_partition_bind_to_owner(&attributes, req->source_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100262
Imre Kis6d867d82023-07-04 13:29:33 +0200263 psa_status =
Balint Dobszaydc945e92024-01-15 16:07:21 +0100264 psa_import_key(&attributes, key_buffer, key_data_len, &ns_key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100265
Julian Hallf5728962021-06-24 09:40:23 +0100266 if (psa_status == PSA_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100267 psa_key_id_t key_id =
268 namespaced_key_id_get_key_id(ns_key_id);
Imre Kis6d867d82023-07-04 13:29:33 +0200269 struct rpc_buffer *resp_buf = &req->response;
julhal01c3f4e9a2020-12-15 13:39:01 +0000270
Imre Kis6d867d82023-07-04 13:29:33 +0200271 rpc_status =
Balint Dobszaydc945e92024-01-15 16:07:21 +0100272 serializer->serialize_import_key_resp(resp_buf, key_id);
Julian Hallf5728962021-06-24 09:40:23 +0100273 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000274
Imre Kis6d867d82023-07-04 13:29:33 +0200275 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100276 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100277
Julian Hallf5728962021-06-24 09:40:23 +0100278 psa_reset_key_attributes(&attributes);
279 free(key_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200280 } else {
281 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100282 }
283 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100284
Julian Hallf5728962021-06-24 09:40:23 +0100285 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100286}
287
Imre Kis6d867d82023-07-04 13:29:33 +0200288static rpc_status_t asymmetric_sign_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100289{
Imre Kis6d867d82023-07-04 13:29:33 +0200290 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
291 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100292 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100293
Balint Dobszaydc945e92024-01-15 16:07:21 +0100294 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallf5728962021-06-24 09:40:23 +0100295 psa_algorithm_t alg;
296 size_t hash_len = PSA_HASH_MAX_SIZE;
297 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100298
Julian Hallf5728962021-06-24 09:40:23 +0100299 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100300 rpc_status = serializer->deserialize_asymmetric_sign_req(req_buf, &key_id, &alg,
Imre Kis6d867d82023-07-04 13:29:33 +0200301 hash_buffer, &hash_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100302
Imre Kis6d867d82023-07-04 13:29:33 +0200303 if (rpc_status == RPC_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100304 namespaced_key_id_t ns_key_id =
305 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallf5728962021-06-24 09:40:23 +0100306 psa_status_t psa_status;
307 size_t sig_len;
308 uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE];
Julian Hallc02fffb2020-11-23 18:22:06 +0100309
Imre Kis6d867d82023-07-04 13:29:33 +0200310 psa_status = (req->opcode == TS_CRYPTO_OPCODE_SIGN_HASH) ?
Balint Dobszaydc945e92024-01-15 16:07:21 +0100311 psa_sign_hash(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sizeof(sig_buffer), &sig_len) :
312 psa_sign_message(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sizeof(sig_buffer), &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100313
Julian Hallf5728962021-06-24 09:40:23 +0100314 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200315 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100316
Imre Kis6d867d82023-07-04 13:29:33 +0200317 rpc_status = serializer->serialize_asymmetric_sign_resp(
318 resp_buf, sig_buffer, sig_len);
Julian Hallf5728962021-06-24 09:40:23 +0100319 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100320
Imre Kis6d867d82023-07-04 13:29:33 +0200321 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100322 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100323
Julian Hallf5728962021-06-24 09:40:23 +0100324 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100325}
326
Imre Kis6d867d82023-07-04 13:29:33 +0200327static rpc_status_t asymmetric_verify_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100328{
Imre Kis6d867d82023-07-04 13:29:33 +0200329 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
330 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100331 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100332
Balint Dobszaydc945e92024-01-15 16:07:21 +0100333 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallf5728962021-06-24 09:40:23 +0100334 psa_algorithm_t alg;
335 size_t hash_len = PSA_HASH_MAX_SIZE;
336 uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
337 size_t sig_len = PSA_SIGNATURE_MAX_SIZE;
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 if (serializer)
Imre Kis6d867d82023-07-04 13:29:33 +0200341 rpc_status = serializer->deserialize_asymmetric_verify_req(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100342 req_buf, &key_id, &alg, hash_buffer, &hash_len, sig_buffer, &sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100343
Imre Kis6d867d82023-07-04 13:29:33 +0200344 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100345 psa_status_t psa_status;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100346 namespaced_key_id_t ns_key_id =
347 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100348
Imre Kis6d867d82023-07-04 13:29:33 +0200349 psa_status = (req->opcode == TS_CRYPTO_OPCODE_VERIFY_HASH) ?
Balint Dobszaydc945e92024-01-15 16:07:21 +0100350 psa_verify_hash(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sig_len) :
351 psa_verify_message(ns_key_id, alg, hash_buffer, hash_len, sig_buffer, sig_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100352
Imre Kis6d867d82023-07-04 13:29:33 +0200353 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100354 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100355
Julian Hallf5728962021-06-24 09:40:23 +0100356 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100357}
358
Imre Kis6d867d82023-07-04 13:29:33 +0200359static rpc_status_t asymmetric_decrypt_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100360{
Imre Kis6d867d82023-07-04 13:29:33 +0200361 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
362 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100363 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100364
Julian Hallf5728962021-06-24 09:40:23 +0100365 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100366 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100367
Balint Dobszaydc945e92024-01-15 16:07:21 +0100368 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallf5728962021-06-24 09:40:23 +0100369 psa_algorithm_t alg;
370 size_t ciphertext_len = max_param_size;
371 uint8_t *ciphertext_buffer = malloc(ciphertext_len);
372 size_t salt_len = max_param_size;
373 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100374
Julian Hallf5728962021-06-24 09:40:23 +0100375 if (ciphertext_buffer && salt_buffer) {
Imre Kis6d867d82023-07-04 13:29:33 +0200376 rpc_status = serializer->deserialize_asymmetric_decrypt_req(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100377 req_buf, &key_id, &alg, ciphertext_buffer, &ciphertext_len, salt_buffer,
Imre Kis6d867d82023-07-04 13:29:33 +0200378 &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100379
Imre Kis6d867d82023-07-04 13:29:33 +0200380 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100381 psa_status_t psa_status;
382 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100383 namespaced_key_id_t ns_key_id =
384 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100385
Balint Dobszaydc945e92024-01-15 16:07:21 +0100386 psa_status = psa_get_key_attributes(ns_key_id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100387
Julian Hallf5728962021-06-24 09:40:23 +0100388 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200389 size_t max_decrypt_size =
390 PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(
391 psa_get_key_type(&attributes),
392 psa_get_key_bits(&attributes), alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100393
Julian Hallf5728962021-06-24 09:40:23 +0100394 size_t plaintext_len;
395 uint8_t *plaintext_buffer = malloc(max_decrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100396
Julian Hallf5728962021-06-24 09:40:23 +0100397 if (plaintext_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100398 /* Salt is an optional parameter */
399 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100400
Imre Kis6d867d82023-07-04 13:29:33 +0200401 psa_status = psa_asymmetric_decrypt(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100402 ns_key_id, alg, ciphertext_buffer, ciphertext_len,
Imre Kis6d867d82023-07-04 13:29:33 +0200403 salt, salt_len, plaintext_buffer,
404 max_decrypt_size, &plaintext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000405
Julian Hallf5728962021-06-24 09:40:23 +0100406 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200407 struct rpc_buffer *resp_buf =
408 &req->response;
409 rpc_status = serializer->serialize_asymmetric_decrypt_resp(
410 resp_buf, plaintext_buffer, plaintext_len);
Julian Hallf5728962021-06-24 09:40:23 +0100411 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000412
Julian Hallf5728962021-06-24 09:40:23 +0100413 free(plaintext_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200414 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100415 /* Failed to allocate ouptput buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200416 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100417 }
418 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100419
Imre Kis6d867d82023-07-04 13:29:33 +0200420 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100421 psa_reset_key_attributes(&attributes);
422 }
Imre Kis6d867d82023-07-04 13:29:33 +0200423 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100424 /* Failed to allocate buffers */
Imre Kis6d867d82023-07-04 13:29:33 +0200425 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100426 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100427
Julian Hallf5728962021-06-24 09:40:23 +0100428 free(ciphertext_buffer);
429 free(salt_buffer);
430 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100431
Julian Hallf5728962021-06-24 09:40:23 +0100432 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100433}
434
Imre Kis6d867d82023-07-04 13:29:33 +0200435static rpc_status_t asymmetric_encrypt_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100436{
Imre Kis6d867d82023-07-04 13:29:33 +0200437 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
438 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100439 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100440
Julian Hallf5728962021-06-24 09:40:23 +0100441 if (serializer) {
Julian Hallf5728962021-06-24 09:40:23 +0100442 size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf);
Julian Hallc02fffb2020-11-23 18:22:06 +0100443
Balint Dobszaydc945e92024-01-15 16:07:21 +0100444 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hallf5728962021-06-24 09:40:23 +0100445 psa_algorithm_t alg;
446 size_t plaintext_len = max_param_size;
447 uint8_t *plaintext_buffer = malloc(plaintext_len);
448 size_t salt_len = max_param_size;
449 uint8_t *salt_buffer = malloc(salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100450
Julian Hallf5728962021-06-24 09:40:23 +0100451 if (plaintext_buffer && salt_buffer) {
Imre Kis6d867d82023-07-04 13:29:33 +0200452 rpc_status = serializer->deserialize_asymmetric_encrypt_req(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100453 req_buf, &key_id, &alg, plaintext_buffer, &plaintext_len, salt_buffer,
Imre Kis6d867d82023-07-04 13:29:33 +0200454 &salt_len);
Julian Hallc02fffb2020-11-23 18:22:06 +0100455
Imre Kis6d867d82023-07-04 13:29:33 +0200456 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100457 psa_status_t psa_status;
458 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100459 namespaced_key_id_t ns_key_id =
460 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hallc02fffb2020-11-23 18:22:06 +0100461
Balint Dobszaydc945e92024-01-15 16:07:21 +0100462 psa_status = psa_get_key_attributes(ns_key_id, &attributes);
Julian Hallc02fffb2020-11-23 18:22:06 +0100463
Julian Hallf5728962021-06-24 09:40:23 +0100464 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200465 size_t max_encrypt_size =
466 PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(
467 psa_get_key_type(&attributes),
468 psa_get_key_bits(&attributes), alg);
Julian Hallc02fffb2020-11-23 18:22:06 +0100469
Julian Hallf5728962021-06-24 09:40:23 +0100470 size_t ciphertext_len;
471 uint8_t *ciphertext_buffer = malloc(max_encrypt_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100472
Julian Hallf5728962021-06-24 09:40:23 +0100473 if (ciphertext_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100474 /* Salt is an optional parameter */
475 uint8_t *salt = (salt_len) ? salt_buffer : NULL;
Julian Hallf688a0b2021-04-09 11:58:30 +0100476
Imre Kis6d867d82023-07-04 13:29:33 +0200477 psa_status = psa_asymmetric_encrypt(
Balint Dobszaydc945e92024-01-15 16:07:21 +0100478 ns_key_id, alg, plaintext_buffer, plaintext_len,
Imre Kis6d867d82023-07-04 13:29:33 +0200479 salt, salt_len, ciphertext_buffer,
480 max_encrypt_size, &ciphertext_len);
julhal01c3f4e9a2020-12-15 13:39:01 +0000481
Julian Hallf5728962021-06-24 09:40:23 +0100482 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200483 struct rpc_buffer *resp_buf =
484 &req->response;
julhal01c3f4e9a2020-12-15 13:39:01 +0000485
Imre Kis6d867d82023-07-04 13:29:33 +0200486 rpc_status = serializer->serialize_asymmetric_encrypt_resp(
487 resp_buf, ciphertext_buffer, ciphertext_len);
Julian Hallf5728962021-06-24 09:40:23 +0100488 }
julhal01c3f4e9a2020-12-15 13:39:01 +0000489
Julian Hallf5728962021-06-24 09:40:23 +0100490 free(ciphertext_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200491 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100492 /* Failed to allocate ouptput buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200493 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100494 }
495 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100496
Imre Kis6d867d82023-07-04 13:29:33 +0200497 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100498 psa_reset_key_attributes(&attributes);
499 }
Imre Kis6d867d82023-07-04 13:29:33 +0200500 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100501 /* Failed to allocate buffers */
Imre Kis6d867d82023-07-04 13:29:33 +0200502 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100503 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100504
Julian Hallf5728962021-06-24 09:40:23 +0100505 free(plaintext_buffer);
506 free(salt_buffer);
507 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100508
Julian Hallf5728962021-06-24 09:40:23 +0100509 return rpc_status;
Julian Hallc02fffb2020-11-23 18:22:06 +0100510}
511
Imre Kis6d867d82023-07-04 13:29:33 +0200512static rpc_status_t generate_random_handler(void *context, struct rpc_request *req)
Julian Hallc02fffb2020-11-23 18:22:06 +0100513{
Imre Kis6d867d82023-07-04 13:29:33 +0200514 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
515 struct rpc_buffer *req_buf = &req->request;
Julian Hallf5728962021-06-24 09:40:23 +0100516 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
Julian Hallc02fffb2020-11-23 18:22:06 +0100517
Julian Hallf5728962021-06-24 09:40:23 +0100518 size_t output_size;
Julian Hallc02fffb2020-11-23 18:22:06 +0100519
Julian Hallf5728962021-06-24 09:40:23 +0100520 if (serializer)
521 rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100522
Imre Kis6d867d82023-07-04 13:29:33 +0200523 if (rpc_status == RPC_SUCCESS) {
Julian Hallf5728962021-06-24 09:40:23 +0100524 psa_status_t psa_status;
525 uint8_t *output_buffer = malloc(output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100526
Julian Hallf5728962021-06-24 09:40:23 +0100527 if (output_buffer) {
Julian Hallf5728962021-06-24 09:40:23 +0100528 psa_status = psa_generate_random(output_buffer, output_size);
Julian Hallc02fffb2020-11-23 18:22:06 +0100529
Julian Hallf5728962021-06-24 09:40:23 +0100530 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200531 struct rpc_buffer *resp_buf = &req->response;
Julian Hallc02fffb2020-11-23 18:22:06 +0100532
Imre Kis6d867d82023-07-04 13:29:33 +0200533 rpc_status = serializer->serialize_generate_random_resp(
534 resp_buf, output_buffer, output_size);
Julian Hallf5728962021-06-24 09:40:23 +0100535 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100536
Imre Kis6d867d82023-07-04 13:29:33 +0200537 req->service_status = psa_status;
Julian Hallf5728962021-06-24 09:40:23 +0100538 free(output_buffer);
Imre Kis6d867d82023-07-04 13:29:33 +0200539 } else {
Julian Hallf5728962021-06-24 09:40:23 +0100540 /* Failed to allocate output buffer */
Imre Kis6d867d82023-07-04 13:29:33 +0200541 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
Julian Hallf5728962021-06-24 09:40:23 +0100542 }
543 }
Julian Hallc02fffb2020-11-23 18:22:06 +0100544
Julian Hallf5728962021-06-24 09:40:23 +0100545 return rpc_status;
546}
547
Imre Kis6d867d82023-07-04 13:29:33 +0200548static rpc_status_t copy_key_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100549{
Imre Kis6d867d82023-07-04 13:29:33 +0200550 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
551 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100552 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
553
554 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100555 psa_key_id_t source_key_id = PSA_KEY_ID_NULL;
Julian Hall8359a632021-07-08 15:10:30 +0100556
557 if (serializer)
Imre Kis6d867d82023-07-04 13:29:33 +0200558 rpc_status =
559 serializer->deserialize_copy_key_req(req_buf, &attributes, &source_key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100560
Imre Kis6d867d82023-07-04 13:29:33 +0200561 if (rpc_status == RPC_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100562 namespaced_key_id_t target_ns_key_id = NAMESPACED_KEY_ID_INIT;
563 namespaced_key_id_t source_ns_key_id =
564 crypto_partition_get_namespaced_key_id(req->source_id, source_key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100565
Balint Dobszaydc945e92024-01-15 16:07:21 +0100566 crypto_partition_bind_to_owner(&attributes, req->source_id);
567
568 psa_status_t psa_status = psa_copy_key(source_ns_key_id, &attributes, &target_ns_key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100569
570 if (psa_status == PSA_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100571 psa_key_id_t target_key_id = namespaced_key_id_get_key_id(target_ns_key_id);
Imre Kis6d867d82023-07-04 13:29:33 +0200572 struct rpc_buffer *resp_buf = &req->response;
Julian Hall8359a632021-07-08 15:10:30 +0100573 rpc_status = serializer->serialize_copy_key_resp(resp_buf, target_key_id);
574 }
575
Imre Kis6d867d82023-07-04 13:29:33 +0200576 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100577 }
578
579 psa_reset_key_attributes(&attributes);
580
581 return rpc_status;
582}
583
Imre Kis6d867d82023-07-04 13:29:33 +0200584static rpc_status_t purge_key_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100585{
Imre Kis6d867d82023-07-04 13:29:33 +0200586 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
587 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100588 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
589
Balint Dobszaydc945e92024-01-15 16:07:21 +0100590 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hall8359a632021-07-08 15:10:30 +0100591
592 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100593 rpc_status = serializer->deserialize_purge_key_req(req_buf, &key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100594
Imre Kis6d867d82023-07-04 13:29:33 +0200595 if (rpc_status == RPC_SUCCESS) {
Balint Dobszaydc945e92024-01-15 16:07:21 +0100596 namespaced_key_id_t ns_key_id =
597 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
598 psa_status_t psa_status = psa_purge_key(ns_key_id);
Imre Kis6d867d82023-07-04 13:29:33 +0200599 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100600 }
601
602 return rpc_status;
603}
604
Imre Kis6d867d82023-07-04 13:29:33 +0200605static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req)
Julian Hall8359a632021-07-08 15:10:30 +0100606{
Imre Kis6d867d82023-07-04 13:29:33 +0200607 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
608 struct rpc_buffer *req_buf = &req->request;
Julian Hall8359a632021-07-08 15:10:30 +0100609 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
610
Balint Dobszaydc945e92024-01-15 16:07:21 +0100611 psa_key_id_t key_id = PSA_KEY_ID_NULL;
Julian Hall8359a632021-07-08 15:10:30 +0100612
613 if (serializer)
Balint Dobszaydc945e92024-01-15 16:07:21 +0100614 rpc_status = serializer->deserialize_get_key_attributes_req(req_buf, &key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100615
Imre Kis6d867d82023-07-04 13:29:33 +0200616 if (rpc_status == RPC_SUCCESS) {
Julian Hall8359a632021-07-08 15:10:30 +0100617 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
Balint Dobszaydc945e92024-01-15 16:07:21 +0100618 namespaced_key_id_t ns_key_id =
619 crypto_partition_get_namespaced_key_id(req->source_id, key_id);
Julian Hall8359a632021-07-08 15:10:30 +0100620
Balint Dobszaydc945e92024-01-15 16:07:21 +0100621 psa_status_t psa_status = psa_get_key_attributes(ns_key_id, &attributes);
Julian Hall8359a632021-07-08 15:10:30 +0100622
623 if (psa_status == PSA_SUCCESS) {
Imre Kis6d867d82023-07-04 13:29:33 +0200624 struct rpc_buffer *resp_buf = &req->response;
Julian Hall8359a632021-07-08 15:10:30 +0100625
Imre Kis6d867d82023-07-04 13:29:33 +0200626 rpc_status = serializer->serialize_get_key_attributes_resp(resp_buf,
627 &attributes);
Julian Hall8359a632021-07-08 15:10:30 +0100628 }
629
630 psa_reset_key_attributes(&attributes);
Imre Kis6d867d82023-07-04 13:29:33 +0200631 req->service_status = psa_status;
Julian Hall8359a632021-07-08 15:10:30 +0100632 }
633
634 return rpc_status;
635}
Gabor Tothab7db212023-08-18 16:08:12 +0200636
Balint Dobszay77183322024-01-25 16:17:16 +0100637#if defined(MBEDTLS_PKCS7_C) && defined(MBEDTLS_X509_CRT_PARSE_C)
Gabor Tothab7db212023-08-18 16:08:12 +0200638static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req)
639{
640 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
641 struct rpc_buffer *req_buf = &req->request;
642 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
643
644 int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
645
646 uint8_t *signature_cert = NULL;
647 uint64_t signature_cert_len = 0;
648 uint8_t *hash = NULL;
649 uint64_t hash_len = 0;
650 uint8_t *public_key_cert = NULL;
651 uint64_t public_key_cert_len = 0;
652
653 if (serializer) {
654 /* First collect the lengths of the fields */
655 rpc_status = serializer->deserialize_verify_pkcs7_signature_req(
656 req_buf, NULL, &signature_cert_len, NULL, &hash_len, NULL,
657 &public_key_cert_len);
658
659 if (rpc_status == RPC_SUCCESS) {
660 /* Allocate the needed space and get the data */
661 signature_cert = (uint8_t *)malloc(signature_cert_len);
662 hash = (uint8_t *)malloc(hash_len);
663 public_key_cert = (uint8_t *)malloc(public_key_cert_len);
664
665 if (signature_cert && hash && public_key_cert) {
666 rpc_status = serializer->deserialize_verify_pkcs7_signature_req(
667 req_buf, signature_cert, &signature_cert_len, hash,
668 &hash_len, public_key_cert, &public_key_cert_len);
669 } else {
670 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
671 }
672 }
673 }
674
675 if (rpc_status == RPC_SUCCESS) {
Gabor Tothaf77b472024-04-05 11:19:37 +0200676 /* Parse the PKCS#7 DER encoded signature block */
677 mbedtls_pkcs7 pkcs7_structure;
Gabor Tothab7db212023-08-18 16:08:12 +0200678
Gabor Tothaf77b472024-04-05 11:19:37 +0200679 mbedtls_pkcs7_init(&pkcs7_structure);
Gabor Tothab7db212023-08-18 16:08:12 +0200680
Gabor Tothaf77b472024-04-05 11:19:37 +0200681 mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
682 signature_cert_len);
Gabor Tothab7db212023-08-18 16:08:12 +0200683
Gabor Tothaf77b472024-04-05 11:19:37 +0200684 if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
Gabor Tothab7db212023-08-18 16:08:12 +0200685
Gabor Tothaf77b472024-04-05 11:19:37 +0200686 /*
687 * If a separate public key is provided, verify the signature with it,
688 * else use the key from the pkcs7 signature structure, because it is
689 * a self-signed certificate.
690 */
691 if(public_key_cert_len) {
692 /* Parse the public key certificate */
693 mbedtls_x509_crt signer_certificate;
Gabor Tothab7db212023-08-18 16:08:12 +0200694
Gabor Tothaf77b472024-04-05 11:19:37 +0200695 mbedtls_x509_crt_init(&signer_certificate);
Gabor Tothab7db212023-08-18 16:08:12 +0200696
Gabor Tothaf77b472024-04-05 11:19:37 +0200697 mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
698 public_key_cert_len);
699
700 if (mbedtls_status == 0) {
701 /* Verify hash against signed hash */
702 mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
703 &pkcs7_structure, &signer_certificate, hash, hash_len);
704 }
705
706 mbedtls_x509_crt_free(&signer_certificate);
707 } else {
Gabor Tothab7db212023-08-18 16:08:12 +0200708 mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
Gabor Tothaf77b472024-04-05 11:19:37 +0200709 &pkcs7_structure, &pkcs7_structure.private_signed_data.private_certs, hash, hash_len);
Gabor Tothab7db212023-08-18 16:08:12 +0200710 }
Gabor Tothab7db212023-08-18 16:08:12 +0200711 }
712
Gabor Tothaf77b472024-04-05 11:19:37 +0200713 mbedtls_pkcs7_free(&pkcs7_structure);
Gabor Tothab7db212023-08-18 16:08:12 +0200714 }
715
716 free(signature_cert);
717 free(hash);
718 free(public_key_cert);
719
720 /* Provide the result of the verification */
721 req->service_status = mbedtls_status;
722
723 return rpc_status;
724}
Gabor Tothaf77b472024-04-05 11:19:37 +0200725
726static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
727{
728 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
729 struct rpc_buffer *req_buf = &req->request;
730 const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
731
732 int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
733
734 uint8_t *signature_cert = NULL;
735 uint64_t signature_cert_len = 0;
736
737 if (serializer) {
738 /* First collect the lengths of the field */
739 rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
740 req_buf, NULL, &signature_cert_len);
741
742 if (rpc_status == RPC_SUCCESS) {
743 /* Allocate the needed space and get the data */
744 signature_cert = (uint8_t *)malloc(signature_cert_len);
745
746 if (signature_cert) {
747 rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
748 req_buf, signature_cert, &signature_cert_len);
749 } else {
750 rpc_status = RPC_ERROR_RESOURCE_FAILURE;
751 }
752 }
753 }
754
755 if (rpc_status == RPC_SUCCESS) {
756 /* Parse the PKCS#7 DER encoded signature block */
757 mbedtls_pkcs7 pkcs7_structure;
758
759 mbedtls_pkcs7_init(&pkcs7_structure);
760
761 mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
762 signature_cert_len);
763
764 if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
765
766 uint8_t output_buffer[PSA_HASH_MAX_SIZE] = { 0 };
767 size_t __maybe_unused output_size = 0;
768 const mbedtls_asn1_buf *signerCertCN = NULL;
769 const mbedtls_x509_crt *topLevelCert = &pkcs7_structure.private_signed_data.private_certs;
770 const mbedtls_x509_buf *toplevelCertTbs = NULL;
771 struct rpc_buffer *resp_buf = &req->response;;
772 psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
773
774 /* Find common name field of the signing certificate, which is the first in the chain */
775 signerCertCN = findCommonName(&topLevelCert->subject);
776 if (!signerCertCN) {
777 mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
778 goto end;
779 }
780
781 /* Get the TopLevel certificate which is the last in the chain */
782 while(topLevelCert->next)
783 topLevelCert = topLevelCert->next;
784 toplevelCertTbs = &topLevelCert->tbs;
785
786 /* Hash the data to create the fingerprint */
787 op = psa_hash_operation_init();
788
789 if (psa_hash_setup(&op, PSA_ALG_SHA_256) != PSA_SUCCESS) {
790 mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
791 goto end;
792 }
793
794 if (psa_hash_update(&op, signerCertCN->p, signerCertCN->len)) {
795 psa_hash_abort(&op);
796 mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
797 goto end;
798 }
799
800 if (psa_hash_update(&op, toplevelCertTbs->p, toplevelCertTbs->len)) {
801 psa_hash_abort(&op);
802 mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
803 goto end;
804 }
805
806 if (psa_hash_finish(&op, (uint8_t*)&output_buffer, PSA_HASH_MAX_SIZE, &output_size)) {
807 psa_hash_abort(&op);
808 mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
809 goto end;
810 }
811
812 /* Clear the remaining part of the buffer for consistency */
813 memset(&output_buffer[output_size], 0, PSA_HASH_MAX_SIZE - output_size);
814
815 rpc_status = serializer->serialize_get_uefi_priv_auth_var_fingerprint_resp(
816 resp_buf, (uint8_t*)&output_buffer);
817 }
818
819end:
820 mbedtls_pkcs7_free(&pkcs7_structure);
821 }
822
823 free(signature_cert);
824
825 /* Provide the result of the verification */
826 req->service_status = (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) ? EFI_SUCCESS : EFI_COMPROMISED_DATA;
827
828 return rpc_status;
829}
Balint Dobszay77183322024-01-25 16:17:16 +0100830#else
831static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req)
832{
833 (void)context;
834 (void)req;
835
836 return RPC_ERROR_INTERNAL;
837}
Gabor Tothaf77b472024-04-05 11:19:37 +0200838
839static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
840{
841 (void)context;
842 (void)req;
843
844 return RPC_ERROR_INTERNAL;
845}
Balint Dobszay77183322024-01-25 16:17:16 +0100846#endif