Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2025 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include "internal/libspdm_requester_lib.h"
8 :
9 : #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
10 :
11 16 : libspdm_return_t libspdm_get_encap_response_endpoint_info(void *spdm_context,
12 : size_t request_size,
13 : void *request,
14 : size_t *response_size,
15 : void *response)
16 : {
17 : uint32_t session_id;
18 : spdm_get_endpoint_info_request_t *spdm_request;
19 : size_t spdm_request_size;
20 : spdm_endpoint_info_response_t *spdm_response;
21 : size_t spdm_response_size;
22 : libspdm_return_t status;
23 : libspdm_context_t *context;
24 : size_t signature_size;
25 : uint32_t endpoint_info_size;
26 : uint8_t slot_id;
27 : libspdm_session_info_t *session_info;
28 : libspdm_session_state_t session_state;
29 : uint8_t *ptr;
30 : bool result;
31 :
32 16 : context = spdm_context;
33 16 : spdm_request = request;
34 :
35 : /* -=[Verify State Phase]=- */
36 16 : if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_13) {
37 1 : return libspdm_generate_encap_error_response(
38 : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
39 : SPDM_GET_ENDPOINT_INFO, response_size, response);
40 : }
41 :
42 15 : if (context->last_spdm_request_session_id_valid) {
43 1 : session_id = context->last_spdm_request_session_id;
44 1 : session_info = libspdm_get_session_info_via_session_id(context, session_id);
45 1 : if (session_info == NULL) {
46 0 : return libspdm_generate_encap_error_response(
47 : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
48 : response_size, response);
49 : }
50 1 : session_state = libspdm_secured_message_get_session_state(
51 : session_info->secured_message_context);
52 1 : if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
53 0 : return libspdm_generate_encap_error_response(
54 : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
55 : response_size, response);
56 : }
57 : } else {
58 14 : session_info = NULL;
59 : }
60 :
61 15 : if (!libspdm_is_capabilities_flag_supported(
62 : context, true,
63 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP, 0)) {
64 1 : return libspdm_generate_encap_error_response(
65 : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
66 : SPDM_GET_ENDPOINT_INFO, response_size, response);
67 : }
68 :
69 : /* -=[Validate Request Phase]=- */
70 14 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(context)) {
71 1 : return libspdm_generate_encap_error_response(
72 : context, SPDM_ERROR_CODE_VERSION_MISMATCH,
73 : 0, response_size, response);
74 : }
75 :
76 13 : if (spdm_request->header.param1 !=
77 : SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER) {
78 1 : return libspdm_generate_encap_error_response(
79 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
80 : 0, response_size, response);
81 : }
82 :
83 12 : if ((spdm_request->request_attributes &
84 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED) != 0) {
85 11 : if (context->connection_info.algorithm.req_pqc_asym_alg != 0) {
86 0 : signature_size = libspdm_get_req_pqc_asym_signature_size(
87 : context->connection_info.algorithm.req_pqc_asym_alg);
88 : } else {
89 11 : signature_size = libspdm_get_req_asym_signature_size(
90 11 : context->connection_info.algorithm.req_base_asym_alg);
91 : }
92 11 : if (request_size <
93 : sizeof(spdm_get_endpoint_info_request_t) +
94 : SPDM_NONCE_SIZE) {
95 1 : return libspdm_generate_encap_error_response(
96 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
97 : 0, response_size, response);
98 : }
99 10 : spdm_request_size = sizeof(spdm_get_endpoint_info_request_t) + SPDM_NONCE_SIZE;
100 : } else {
101 1 : if (request_size < sizeof(spdm_get_endpoint_info_request_t)) {
102 0 : return libspdm_generate_encap_error_response(
103 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
104 : 0, response_size, response);
105 : }
106 1 : spdm_request_size = sizeof(spdm_get_endpoint_info_request_t);
107 : }
108 :
109 11 : slot_id = 0;
110 11 : if ((spdm_request->request_attributes &
111 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED) != 0) {
112 10 : if (!libspdm_is_capabilities_flag_supported(
113 : context, false, 0,
114 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG)) {
115 1 : return libspdm_generate_encap_error_response(
116 : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
117 : SPDM_GET_ENDPOINT_INFO, response_size, response);
118 : }
119 :
120 9 : slot_id = spdm_request->header.param2 & SPDM_GET_ENDPOINT_INFO_REQUEST_SLOT_ID_MASK;
121 :
122 9 : if ((slot_id != 0xF) && (slot_id >= SPDM_MAX_SLOT_COUNT)) {
123 1 : return libspdm_generate_encap_error_response(
124 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
125 : 0, response_size, response);
126 : }
127 :
128 8 : if (slot_id != 0xF) {
129 6 : if (context->local_context.local_cert_chain_provision[slot_id] == NULL) {
130 2 : return libspdm_generate_encap_error_response(
131 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
132 : 0, response_size, response);
133 : }
134 : } else {
135 2 : if (context->local_context.local_public_key_provision == NULL) {
136 1 : return libspdm_generate_encap_error_response(
137 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
138 : 0, response_size, response);
139 : }
140 : }
141 :
142 5 : if (context->connection_info.multi_key_conn_req && slot_id != 0xF) {
143 0 : if ((context->local_context.local_key_usage_bit_mask[slot_id] &
144 : SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE) == 0) {
145 0 : return libspdm_generate_encap_error_response(
146 : context, SPDM_ERROR_CODE_INVALID_REQUEST,
147 : 0, response_size, response);
148 : }
149 : }
150 : }
151 :
152 : /* -=[Construct Response Phase]=- */
153 : /* response_size should be large enough to hold a ENDPOINT_INFO response without
154 : * EPInfo. */
155 6 : if ((spdm_request->request_attributes &
156 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED) != 0) {
157 5 : LIBSPDM_ASSERT(*response_size >= (sizeof(spdm_endpoint_info_response_t) +
158 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
159 : signature_size));
160 5 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) + SPDM_NONCE_SIZE +
161 : sizeof(uint32_t) + signature_size;
162 : } else {
163 1 : LIBSPDM_ASSERT(*response_size >= (sizeof(spdm_endpoint_info_response_t) +
164 : sizeof(uint32_t)));
165 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) + sizeof(uint32_t);
166 : }
167 :
168 6 : libspdm_zero_mem(response, *response_size);
169 6 : spdm_response = response;
170 :
171 6 : libspdm_reset_message_buffer_via_request_code(context, NULL,
172 6 : spdm_request->header.request_response_code);
173 :
174 6 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
175 6 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
176 6 : spdm_response->header.param1 = 0;
177 6 : spdm_response->header.param2 = slot_id;
178 6 : ptr = (uint8_t *)spdm_response + sizeof(spdm_endpoint_info_response_t);
179 :
180 6 : if ((spdm_request->request_attributes &
181 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED) != 0) {
182 5 : if (!libspdm_get_random_number(SPDM_NONCE_SIZE, ptr)) {
183 0 : libspdm_reset_message_encap_e(context, session_info);
184 0 : return libspdm_generate_encap_error_response(
185 : context, SPDM_ERROR_CODE_UNSPECIFIED,
186 : 0, response_size, response);
187 : }
188 5 : ptr += SPDM_NONCE_SIZE;
189 : }
190 6 : ptr += sizeof(uint32_t);
191 :
192 6 : endpoint_info_size = (uint32_t) (*response_size - spdm_response_size);
193 6 : status = libspdm_generate_device_endpoint_info(
194 6 : context, spdm_request->header.param1,
195 6 : spdm_request->request_attributes,
196 : &endpoint_info_size, ptr);
197 6 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
198 0 : return libspdm_generate_encap_error_response(
199 : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
200 : SPDM_GET_ENDPOINT_INFO, response_size, response);
201 : }
202 6 : libspdm_write_uint32(ptr - sizeof(uint32_t), endpoint_info_size);
203 6 : spdm_response_size += endpoint_info_size;
204 6 : *response_size = spdm_response_size;
205 6 : ptr += endpoint_info_size;
206 :
207 6 : if ((spdm_request->request_attributes &
208 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED) != 0) {
209 :
210 5 : status = libspdm_append_message_encap_e(context, session_info, spdm_request,
211 : spdm_request_size);
212 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
213 0 : libspdm_reset_message_e(context, session_info);
214 0 : return libspdm_generate_encap_error_response(
215 : context, SPDM_ERROR_CODE_UNSPECIFIED,
216 : 0, response_size, response);
217 : }
218 :
219 5 : status = libspdm_append_message_encap_e(context, session_info, spdm_response,
220 : spdm_response_size - signature_size);
221 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
222 0 : libspdm_reset_message_e(context, session_info);
223 0 : return libspdm_generate_encap_error_response(
224 : context, SPDM_ERROR_CODE_UNSPECIFIED,
225 : 0, response_size, response);
226 : }
227 :
228 5 : result = libspdm_generate_endpoint_info_signature(context, session_info, true, ptr);
229 :
230 5 : if (!result) {
231 0 : libspdm_reset_message_encap_e(context, session_info);
232 0 : return libspdm_generate_encap_error_response(
233 : context, SPDM_ERROR_CODE_UNSPECIFIED,
234 : 0, response_size, response);
235 : }
236 : }
237 :
238 6 : libspdm_reset_message_encap_e(context, session_info);
239 :
240 6 : return LIBSPDM_STATUS_SUCCESS;
241 : }
242 :
243 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (..) */
|