blob: 1e127176146c7592830c495ea70488688d4c253b [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);
18
19/* Handler mapping table for service */
20static const struct service_handler handler_table[] = {
21 {TS_ATTESTATION_OPCODE_GET_TOKEN, get_token_handler},
22 {TS_ATTESTATION_OPCODE_GET_TOKEN_SIZE, get_token_size_handler}
23};
24
25struct rpc_interface *attest_provider_init(struct attest_provider *context, psa_key_id_t iak_id)
26{
27 struct rpc_interface *rpc_interface = NULL;
28
29 if (context) {
30
31 for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
32 context->serializers[encoding] = NULL;
33
34 service_provider_init(&context->base_provider, context,
35 handler_table, sizeof(handler_table)/sizeof(struct service_handler));
36
37 attest_key_mngr_init(iak_id);
38
39 rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
40 }
41
42 return rpc_interface;
43}
44
45void attest_provider_deinit(struct attest_provider *context)
46{
47 (void)context;
48 attest_key_mngr_deinit();
49}
50
51void attest_provider_register_serializer(struct attest_provider *context,
52 unsigned int encoding, const struct attest_provider_serializer *serializer)
53{
54 if (encoding < TS_RPC_ENCODING_LIMIT)
55 context->serializers[encoding] = serializer;
56}
57
58static const struct attest_provider_serializer *get_attest_serializer(
59 struct attest_provider *context, const struct call_req *req)
60{
61 const struct attest_provider_serializer *serializer = NULL;
62 unsigned int encoding = call_req_get_encoding(req);
63
64 if (encoding < TS_RPC_ENCODING_LIMIT) serializer = context->serializers[encoding];
65
66 return serializer;
67}
68
69static rpc_status_t get_token_handler(void *context, struct call_req* req)
70{
71 struct attest_provider *this_instance = (struct attest_provider*)context;
72 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
73
74 uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
75 size_t challenge_len = sizeof(challenge);
76
77 struct call_param_buf *req_buf = call_req_get_req_buf(req);
78 const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
79
80 if (serializer)
81 rpc_status = serializer->deserialize_get_token_req(req_buf, challenge, &challenge_len);
82
83 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
84
85 psa_key_handle_t iak_handle;
86 int opstatus = attest_key_mngr_get_iak_handle(&iak_handle);
87
88 if (opstatus == PSA_SUCCESS) {
89
90 const uint8_t *token = NULL;
91 size_t token_size = 0;
92
93 opstatus = attest_report_create(iak_handle,
94 (int32_t)call_req_get_caller_id(req),
95 challenge, challenge_len,
96 &token, &token_size);
97
98 if (opstatus == PSA_SUCCESS) {
99
100 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
101 rpc_status = serializer->serialize_get_token_resp(resp_buf, token, token_size);
102 }
103
104 attest_report_destroy(token);
105 }
106
107 call_req_set_opstatus(req, opstatus);
108 }
109
110 return rpc_status;
111}
112
113static rpc_status_t get_token_size_handler(void *context, struct call_req* req)
114{
115 struct attest_provider *this_instance = (struct attest_provider*)context;
116 rpc_status_t rpc_status = TS_RPC_ERROR_SERIALIZATION_NOT_SUPPORTED;
117
118 uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64];
119 size_t challenge_len = sizeof(challenge);
120
121 struct call_param_buf *req_buf = call_req_get_req_buf(req);
122 const struct attest_provider_serializer *serializer = get_attest_serializer(this_instance, req);
123
124 memset(challenge, 0, sizeof(challenge));
125
126 if (serializer)
127 rpc_status = serializer->deserialize_get_token_size_req(req_buf, &challenge_len);
128
129 if (rpc_status == TS_RPC_CALL_ACCEPTED) {
130
131 psa_key_handle_t iak_handle;
132 int opstatus = attest_key_mngr_get_iak_handle(&iak_handle);
133
134 if (opstatus == PSA_SUCCESS) {
135
136 const uint8_t *token = NULL;
137 size_t token_size = 0;
138
139 opstatus = attest_report_create(iak_handle,
140 (int32_t)call_req_get_caller_id(req),
141 challenge, challenge_len,
142 &token, &token_size);
143
144 if (opstatus == PSA_SUCCESS) {
145
146 struct call_param_buf *resp_buf = call_req_get_resp_buf(req);
147 rpc_status = serializer->serialize_get_token_size_resp(resp_buf, token_size);
148 }
149
150 attest_report_destroy(token);
151 }
152
153 call_req_set_opstatus(req, opstatus);
154 }
155
156 return rpc_status;
157}