blob: 9669ed60691a1483d4521538f64c37ca3d719537 [file] [log] [blame]
Julian Hall700aa362021-05-13 15:30:39 +01001/*
2 * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <stdlib.h>
7#include <string.h>
8#include <protocols/service/attestation/packed-c/opcodes.h>
9#include <protocols/rpc/common/packed-c/status.h>
10#include <service/attestation/key_mngr/attest_key_mngr.h>
11#include <service/attestation/reporter/attest_report.h>
12#include <psa/initial_attestation.h>
13#include "attest_provider.h"
14
15/* Service request handlers */
16static rpc_status_t get_token_handler(void *context, struct call_req* req);
17static rpc_status_t get_token_size_handler(void *context, struct call_req* req);
Julian Hall482fd2f2021-05-17 16:34:48 +010018static rpc_status_t export_iak_public_key_handler(void *context, struct call_req* req);
19static rpc_status_t import_iak_handler(void *context, struct call_req* req);
Julian Hall700aa362021-05-13 15:30:39 +010020
21/* Handler mapping table for service */
22static const struct service_handler handler_table[] = {
Julian Hall482fd2f2021-05-17 16:34:48 +010023 {TS_ATTESTATION_OPCODE_GET_TOKEN, get_token_handler},
24 {TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, get_token_size_handler},
25 {TS_ATTESTATION_OPCODE_EXPORT_IAK_PUBLIC_KEY, export_iak_public_key_handler},
26 {TS_ATTESTATION_OPCODE_IMPORT_IAK, import_iak_handler}
Julian Hall700aa362021-05-13 15:30:39 +010027};
28
29struct rpc_interface *attest_provider_init(struct attest_provider *context, psa_key_id_t iak_id)
30{
31 struct rpc_interface *rpc_interface = NULL;
32
33 if (context) {
34
35 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
36 context->serializers[encoding] = NULL;
37
38 service_provider_init(&context->base_provider, context,
39 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
40
41 attest_key_mngr_init(iak_id);
42
43 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
44 }
45
46 return rpc_interface;
47}
48
49void attest_provider_deinit(struct attest_provider *context)
50{
51 (void)context;
52 attest_key_mngr_deinit();
53}
54
55void attest_provider_register_serializer(struct attest_provider *context,
56 unsigned int encoding, const struct attest_provider_serializer *serializer)
57{
58 if (encoding < TS_RPC_ENCODING_LIMIT)
59 context->serializers[encoding] = serializer;
60}
61
62static const struct attest_provider_serializer *get_attest_serializer(
63 struct attest_provider *context, const struct call_req *req)
64{
65 const struct attest_provider_serializer *serializer = NULL;
66 unsigned int encoding = call_req_get_encoding(req);
67
68 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding];
69
70 return serializer;
71}
72
73static rpc_status_t get_token_handler(void *context, struct call_req* req)
74{
75 struct attest_provider *this_instance = (struct attest_provider*)context;
76 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
77
78 uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
79 size_t challenge_len = sizeof(challenge);
80
81 struct call_param_buf *req_buf = call_req_get_req_buf(req);
82 const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
83
84 if (serializer)
85 rpc_status = serializer->deserialize_get_token_req(req_buf, challenge, &challenge_len);
86
87 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
88
89 psa_key_handle_t iak_handle;
90 int opstatus = attest_key_mngr_get_iak_handle(&iak_handle);
91
92 if (opstatus == PSA_SUCCESS) {
93
94 const uint8_t *token = NULL;
95 size_t token_size = 0;
96
97 opstatus = attest_report_create(iak_handle,
98 (int32_t)call_req_get_caller_id(req),
99 challenge, challenge_len,
100 &token, &token_size);
101
102 if (opstatus == PSA_SUCCESS) {
103
104 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
105 rpc_status = serializer->serialize_get_token_resp(resp_buf, token, token_size);
106 }
107
108 attest_report_destroy(token);
109 }
110
111 call_req_set_opstatus(req, opstatus);
112 }
113
114 return rpc_status;
115}
116
117static rpc_status_t get_token_size_handler(void *context, struct call_req* req)
118{
119 struct attest_provider *this_instance = (struct attest_provider*)context;
120 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
121
122 uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
123 size_t challenge_len = sizeof(challenge);
124
125 struct call_param_buf *req_buf = call_req_get_req_buf(req);
126 const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
127
128 memset(challenge, 0, sizeof(challenge));
129
130 if (serializer)
131 rpc_status = serializer->deserialize_get_token_size_req(req_buf, &challenge_len);
132
133 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
134
135 psa_key_handle_t iak_handle;
136 int opstatus = attest_key_mngr_get_iak_handle(&iak_handle);
137
138 if (opstatus == PSA_SUCCESS) {
139
140 const uint8_t *token = NULL;
141 size_t token_size = 0;
142
143 opstatus = attest_report_create(iak_handle,
144 (int32_t)call_req_get_caller_id(req),
145 challenge, challenge_len,
146 &token, &token_size);
147
148 if (opstatus == PSA_SUCCESS) {
149
150 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
151 rpc_status = serializer->serialize_get_token_size_resp(resp_buf, token_size);
152 }
153
154 attest_report_destroy(token);
155 }
156
157 call_req_set_opstatus(req, opstatus);
158 }
159
160 return rpc_status;
161}
Julian Hall482fd2f2021-05-17 16:34:48 +0100162
163static rpc_status_t export_iak_public_key_handler(void *context, struct call_req* req)
164{
165 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
166 struct call_param_buf *req_buf = call_req_get_req_buf(req);
167 const struct attest_provider_serializer *serializer = get_attest_serializer(context, req);
168
169 if (serializer) {
170
Julian Hall04464912021-05-18 15:32:49 +0100171 size_t max_key_size = attest_key_mngr_max_iak_export_size();
Julian Hall482fd2f2021-05-17 16:34:48 +0100172
173 uint8_t *key_buffer = malloc(max_key_size);
174
175 if (key_buffer) {
176
177 int opstatus;
178 size_t export_size;
179 opstatus =
180 attest_key_mngr_export_iak_public_key(key_buffer, max_key_size, &export_size);
181
182 if (opstatus == PSA_SUCCESS) {
183
184 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
185 rpc_status =
186 serializer->serialize_export_iak_public_key_resp(resp_buf,
187 key_buffer, export_size);
188 }
189
190 free(key_buffer);
191 call_req_set_opstatus(req, opstatus);
192 }
193 else {
194 /* Failed to allocate key buffer */
195 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
196 }
197 }
198
199 return rpc_status;
200}
201
202static rpc_status_t import_iak_handler(void *context, struct call_req* req)
203{
204 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
205 struct call_param_buf *req_buf = call_req_get_req_buf(req);
206 const struct attest_provider_serializer *serializer = get_attest_serializer(context, req);
207
208 if (serializer) {
209
Julian Hall04464912021-05-18 15:32:49 +0100210 size_t key_data_len = attest_key_mngr_max_iak_import_size();
Julian Hall482fd2f2021-05-17 16:34:48 +0100211 uint8_t *key_buffer = malloc(key_data_len);
212
213 if (key_buffer) {
214
215 rpc_status =
216 serializer->deserialize_import_iak_req(req_buf, key_buffer, &key_data_len);
217
218 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
219
220 int opstatus;
221 opstatus = attest_key_mngr_import_iak(key_buffer, key_data_len);
222 call_req_set_opstatus(req, opstatus);
223 }
224
225 free(key_buffer);
226 }
227 else {
228
229 rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE;
230 }
231 }
232
233 return rpc_status;
234}