Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2021-2026 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
10 : :
11 : 90 : void libspdm_register_get_encap_response_func(void *spdm_context,
12 : : const libspdm_get_encap_response_func
13 : : get_encap_response_func)
14 : : {
15 : : libspdm_context_t *context;
16 : :
17 : 90 : context = spdm_context;
18 : 90 : context->get_encap_response_func = (void *)get_encap_response_func;
19 : 90 : }
20 : :
21 : : /**
22 : : * Return the GET_ENCAP_RESPONSE function via request code.
23 : : *
24 : : * @param request_response_code The SPDM request code.
25 : : *
26 : : * @return GET_ENCAP_RESPONSE function according to the request code.
27 : : **/
28 : : static libspdm_get_encap_response_func
29 : 54 : libspdm_get_encap_response_func_via_request_code(uint8_t request_response_code)
30 : : {
31 : : typedef struct {
32 : : uint8_t request_response_code;
33 : : libspdm_get_encap_response_func get_encap_response_func;
34 : : } libspdm_get_encap_response_struct_t;
35 : :
36 : : size_t index;
37 : :
38 : 54 : const libspdm_get_encap_response_struct_t get_encap_response_struct[] = {
39 : : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
40 : : { SPDM_GET_DIGESTS, libspdm_get_encap_response_digest },
41 : : { SPDM_GET_CERTIFICATE, libspdm_get_encap_response_certificate },
42 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
43 : :
44 : : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
45 : : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
46 : : { SPDM_CHALLENGE, libspdm_get_encap_response_challenge_auth },
47 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
48 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
49 : :
50 : : #if ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP))
51 : : { SPDM_KEY_UPDATE, libspdm_get_encap_response_key_update },
52 : : #endif /* ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)) */
53 : :
54 : : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
55 : : { SPDM_SEND_EVENT, libspdm_get_encap_response_event_ack },
56 : : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
57 : :
58 : : #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
59 : : { SPDM_GET_SUPPORTED_EVENT_TYPES, libspdm_get_encap_supported_event_types },
60 : : { SPDM_SUBSCRIBE_EVENT_TYPES, libspdm_get_encap_subscribe_event_types_ack },
61 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
62 : :
63 : : #if LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP
64 : : { SPDM_GET_ENDPOINT_INFO, libspdm_get_encap_response_endpoint_info },
65 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */
66 : : };
67 : :
68 [ + + ]: 348 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(get_encap_response_struct); index++) {
69 [ + + ]: 314 : if (request_response_code == get_encap_response_struct[index].request_response_code) {
70 : 20 : return get_encap_response_struct[index].get_encap_response_func;
71 : : }
72 : : }
73 : 34 : return NULL;
74 : : }
75 : :
76 : : /**
77 : : * This function processes encapsulated request.
78 : : *
79 : : * @param spdm_context A pointer to the SPDM context.
80 : : * @param encap_request_size Size, in bytes, of the request data buffer.
81 : : * @param encap_request A pointer to a destination buffer to store the request.
82 : : * @param encap_response_size Size, in bytes, of the response data buffer.
83 : : * @param encap_response A pointer to a destination buffer to store the response.
84 : : **/
85 : 54 : static libspdm_return_t libspdm_process_encapsulated_request(libspdm_context_t *spdm_context,
86 : : libspdm_session_info_t *session_info,
87 : : size_t encap_request_size,
88 : : void *encap_request,
89 : : size_t *encap_response_size,
90 : : void *encap_response)
91 : : {
92 : : libspdm_get_encap_response_func get_encap_response_func;
93 : : spdm_message_header_t *spdm_requester;
94 : :
95 : 54 : spdm_requester = encap_request;
96 [ - + ]: 54 : if (encap_request_size < sizeof(spdm_message_header_t)) {
97 : 0 : return libspdm_generate_encap_error_response(
98 : : spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
99 : 0 : spdm_requester->request_response_code,
100 : : encap_response_size, encap_response);
101 : : }
102 : :
103 : 54 : libspdm_reset_message_buffer_via_encap_request_code(
104 : 54 : spdm_context, session_info, spdm_requester->request_response_code);
105 : :
106 : 54 : get_encap_response_func = libspdm_get_encap_response_func_via_request_code(
107 : 54 : spdm_requester->request_response_code);
108 [ + + ]: 54 : if (get_encap_response_func == NULL) {
109 : 34 : get_encap_response_func =
110 : 34 : (libspdm_get_encap_response_func)spdm_context->get_encap_response_func;
111 : : }
112 [ + + ]: 54 : if (get_encap_response_func != NULL) {
113 : 26 : return get_encap_response_func(
114 : : spdm_context, encap_request_size, encap_request,
115 : : encap_response_size, encap_response);
116 : : } else {
117 : 28 : return libspdm_generate_encap_error_response(
118 : : spdm_context, SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
119 : : 0, encap_response_size, encap_response);
120 : : }
121 : : }
122 : :
123 : 80 : libspdm_return_t libspdm_encapsulated_request(libspdm_context_t *spdm_context,
124 : : const uint32_t *session_id,
125 : : uint8_t mut_auth_requested,
126 : : uint8_t *req_slot_id_param)
127 : : {
128 : : libspdm_return_t status;
129 : : uint8_t *spdm_request;
130 : : size_t spdm_request_size;
131 : : spdm_get_encapsulated_request_request_t
132 : : *spdm_get_encapsulated_request_request;
133 : : spdm_deliver_encapsulated_response_request_t
134 : : *spdm_deliver_encapsulated_response_request;
135 : : uint8_t *spdm_response;
136 : : size_t spdm_response_size;
137 : : spdm_encapsulated_request_response_t *libspdm_encapsulated_request_response;
138 : : spdm_encapsulated_response_ack_response_t
139 : : *spdm_encapsulated_response_ack_response;
140 : : libspdm_session_info_t *session_info;
141 : : uint8_t request_id;
142 : : void *encapsulated_request;
143 : : size_t encapsulated_request_size;
144 : : void *encapsulated_response;
145 : : size_t encapsulated_response_size;
146 : : size_t ack_header_size;
147 : :
148 : : uint8_t *message;
149 : : size_t message_size;
150 : : size_t transport_header_size;
151 : :
152 : : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
153 : : spdm_get_digest_request_t *get_digests;
154 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
155 : :
156 [ + + ]: 80 : if (!libspdm_is_encap_supported(spdm_context)) {
157 : 2 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
158 : : }
159 : :
160 [ + + ]: 78 : if (session_id != NULL) {
161 : 10 : session_info = libspdm_get_session_info_via_session_id(spdm_context, *session_id);
162 [ - + ]: 10 : if (session_info == NULL) {
163 : 0 : LIBSPDM_ASSERT(false);
164 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
165 : : }
166 : 10 : LIBSPDM_ASSERT((mut_auth_requested == 0) ||
167 : : (mut_auth_requested ==
168 : : SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) ||
169 : : (mut_auth_requested ==
170 : : SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS));
171 : : } else {
172 : 68 : session_info = NULL;
173 : 68 : LIBSPDM_ASSERT(mut_auth_requested == 0);
174 : : }
175 : :
176 : :
177 : : /* Cache */
178 : 78 : libspdm_reset_message_mut_b(spdm_context);
179 : 78 : libspdm_reset_message_mut_c(spdm_context);
180 : :
181 [ + + ]: 78 : if (session_id == NULL) {
182 : 68 : spdm_context->last_spdm_request_session_id_valid = false;
183 : 68 : spdm_context->last_spdm_request_session_id = 0;
184 : : } else {
185 : 10 : spdm_context->last_spdm_request_session_id_valid = true;
186 : 10 : spdm_context->last_spdm_request_session_id = *session_id;
187 : : }
188 : :
189 [ + + ]: 78 : if (mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS) {
190 : : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
191 : 2 : get_digests = (void *)spdm_context->last_spdm_request;
192 : 2 : get_digests->header.spdm_version = libspdm_get_connection_version (spdm_context);
193 : 2 : get_digests->header.request_response_code = SPDM_GET_DIGESTS;
194 : 2 : get_digests->header.param1 = 0;
195 : 2 : get_digests->header.param2 = 0;
196 : 2 : spdm_context->last_spdm_request_size = sizeof(spdm_get_digest_request_t);
197 : 2 : encapsulated_request = (void *)spdm_context->last_spdm_request;
198 : 2 : encapsulated_request_size = spdm_context->last_spdm_request_size;
199 : 2 : request_id = 0;
200 : : #else /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
201 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
202 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
203 : : } else {
204 : 76 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
205 : 76 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
206 [ + + ]: 76 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
207 : 2 : return status;
208 : : }
209 : 74 : LIBSPDM_ASSERT (message_size >= transport_header_size +
210 : : spdm_context->local_context.capability.transport_tail_size);
211 : 74 : spdm_request = (void *)(message + transport_header_size);
212 : 74 : spdm_request_size = message_size - transport_header_size -
213 : 74 : spdm_context->local_context.capability.transport_tail_size;
214 : :
215 : 74 : spdm_context->crypto_request = true;
216 : 74 : spdm_get_encapsulated_request_request = (void *)spdm_request;
217 : 74 : spdm_get_encapsulated_request_request->header.spdm_version =
218 : 74 : libspdm_get_connection_version (spdm_context);
219 : : spdm_get_encapsulated_request_request->header
220 : 74 : .request_response_code = SPDM_GET_ENCAPSULATED_REQUEST;
221 : 74 : spdm_get_encapsulated_request_request->header.param1 = 0;
222 : 74 : spdm_get_encapsulated_request_request->header.param2 = 0;
223 : 74 : spdm_request_size = sizeof(spdm_get_encapsulated_request_request_t);
224 : 74 : libspdm_reset_message_buffer_via_request_code
225 : : (spdm_context, NULL,
226 : 74 : spdm_get_encapsulated_request_request->header.request_response_code);
227 : 74 : status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size,
228 : : spdm_request);
229 [ + + ]: 74 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
230 : 2 : libspdm_release_sender_buffer (spdm_context);
231 : 2 : return status;
232 : : }
233 : 72 : libspdm_release_sender_buffer (spdm_context);
234 : 72 : spdm_get_encapsulated_request_request = (void *)spdm_context->last_spdm_request;
235 : :
236 : : /* receive */
237 : :
238 : 72 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
239 [ + + ]: 72 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
240 : 2 : return status;
241 : : }
242 : 70 : LIBSPDM_ASSERT (message_size >= transport_header_size);
243 : 70 : spdm_response = (void *)(message);
244 : 70 : spdm_response_size = message_size;
245 : :
246 : 70 : status = libspdm_receive_spdm_response(
247 : : spdm_context, session_id, &spdm_response_size,
248 : : (void **)&spdm_response);
249 : 70 : libspdm_encapsulated_request_response = (void *)spdm_response;
250 [ + + ]: 70 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
251 : 2 : libspdm_release_receiver_buffer (spdm_context);
252 : 2 : return status;
253 : : }
254 [ - + ]: 68 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
255 : 0 : libspdm_release_receiver_buffer (spdm_context);
256 : 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
257 : : }
258 [ + + ]: 68 : if (libspdm_encapsulated_request_response->header.request_response_code == SPDM_ERROR) {
259 : 8 : const uint8_t error_code = libspdm_encapsulated_request_response->header.param1;
260 : :
261 [ + - ]: 8 : if (mut_auth_requested == 0) {
262 : : /* Responder can send NoPendingRequests or UnexpectedRequest if it has no
263 : : * encapsulated request for the Requester. */
264 [ + + + + ]: 8 : if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
265 : : (error_code == SPDM_ERROR_CODE_NO_PENDING_REQUESTS)) {
266 : 2 : libspdm_release_receiver_buffer (spdm_context);
267 : 2 : return LIBSPDM_STATUS_SUCCESS;
268 : : }
269 [ + + + + ]: 6 : if ((libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) &&
270 : : (error_code == SPDM_ERROR_CODE_UNEXPECTED_REQUEST)) {
271 : 2 : libspdm_release_receiver_buffer (spdm_context);
272 : 2 : return LIBSPDM_STATUS_SUCCESS;
273 : : }
274 : : }
275 : 4 : status = libspdm_handle_error_response_main(
276 : : spdm_context, session_id,
277 : : &spdm_response_size, (void **)&spdm_response,
278 : : SPDM_GET_ENCAPSULATED_REQUEST, SPDM_ENCAPSULATED_REQUEST);
279 [ + + ]: 4 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
280 : 2 : libspdm_release_receiver_buffer (spdm_context);
281 : 2 : return status;
282 : : }
283 : 2 : libspdm_encapsulated_request_response = (void *)spdm_response;
284 : : }
285 : 62 : if (libspdm_encapsulated_request_response->header.spdm_version !=
286 [ + + ]: 62 : spdm_get_encapsulated_request_request->header.spdm_version) {
287 : 6 : libspdm_release_receiver_buffer (spdm_context);
288 : 6 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
289 : : }
290 : :
291 [ + + ]: 56 : if (libspdm_encapsulated_request_response->header.request_response_code !=
292 : : SPDM_ENCAPSULATED_REQUEST) {
293 : 2 : libspdm_release_receiver_buffer (spdm_context);
294 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
295 : : }
296 [ + + ]: 54 : if (spdm_response_size <= sizeof(spdm_encapsulated_request_response_t)) {
297 : 2 : libspdm_release_receiver_buffer (spdm_context);
298 : 2 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
299 : : }
300 : :
301 : 52 : request_id = libspdm_encapsulated_request_response->header.param1;
302 : :
303 : 52 : encapsulated_request = (void *)(libspdm_encapsulated_request_response + 1);
304 : 52 : encapsulated_request_size =
305 : 52 : spdm_response_size - sizeof(spdm_encapsulated_request_response_t);
306 : :
307 : 52 : libspdm_copy_mem (spdm_context->last_spdm_request,
308 : 52 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
309 : : encapsulated_request,
310 : : encapsulated_request_size);
311 : 52 : spdm_context->last_spdm_request_size = encapsulated_request_size;
312 : 52 : encapsulated_request = (void *)spdm_context->last_spdm_request;
313 : :
314 : 52 : libspdm_release_receiver_buffer (spdm_context);
315 : : }
316 : :
317 : : while (true) {
318 : : /* Process request. */
319 : 56 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
320 : 56 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
321 [ + + ]: 56 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
322 : 2 : return status;
323 : : }
324 : 54 : LIBSPDM_ASSERT (message_size >= transport_header_size +
325 : : spdm_context->local_context.capability.transport_tail_size);
326 : 54 : spdm_request = (void *)(message + transport_header_size);
327 : 54 : spdm_request_size = message_size - transport_header_size -
328 : 54 : spdm_context->local_context.capability.transport_tail_size;
329 : :
330 : 54 : spdm_context->crypto_request = true;
331 : 54 : spdm_deliver_encapsulated_response_request = (void *)spdm_request;
332 : 54 : spdm_deliver_encapsulated_response_request->header.spdm_version =
333 : 54 : libspdm_get_connection_version (spdm_context);
334 : 54 : spdm_deliver_encapsulated_response_request->header.request_response_code =
335 : : SPDM_DELIVER_ENCAPSULATED_RESPONSE;
336 : 54 : spdm_deliver_encapsulated_response_request->header.param1 = request_id;
337 : 54 : spdm_deliver_encapsulated_response_request->header.param2 = 0;
338 : 54 : encapsulated_response = (void *)(spdm_deliver_encapsulated_response_request + 1);
339 : 54 : encapsulated_response_size =
340 : 54 : spdm_request_size - sizeof(spdm_deliver_encapsulated_response_request_t);
341 : :
342 : 54 : status = libspdm_process_encapsulated_request(
343 : : spdm_context, session_info, encapsulated_request_size,
344 : : encapsulated_request, &encapsulated_response_size,
345 : : encapsulated_response);
346 [ + + ]: 54 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
347 : 2 : libspdm_release_sender_buffer (spdm_context);
348 : 2 : return status;
349 : : }
350 : :
351 : 52 : spdm_request_size =
352 : 52 : sizeof(spdm_deliver_encapsulated_response_request_t) + encapsulated_response_size;
353 : 52 : status = libspdm_send_spdm_request(
354 : : spdm_context, session_id, spdm_request_size,
355 : : spdm_request);
356 [ + + ]: 52 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
357 : 2 : libspdm_release_sender_buffer (spdm_context);
358 : 2 : return status;
359 : : }
360 : 50 : libspdm_release_sender_buffer (spdm_context);
361 : 50 : spdm_deliver_encapsulated_response_request = (void *)spdm_context->last_spdm_request;
362 : :
363 : : /* Receive. */
364 : 50 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
365 [ + + ]: 50 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
366 : 2 : return status;
367 : : }
368 : 48 : LIBSPDM_ASSERT (message_size >= transport_header_size);
369 : 48 : spdm_response = (void *)(message);
370 : 48 : spdm_response_size = message_size;
371 : :
372 : 48 : status = libspdm_receive_spdm_response(
373 : : spdm_context, session_id, &spdm_response_size,
374 : : (void **)&spdm_response);
375 : 48 : spdm_encapsulated_response_ack_response = (void *)spdm_response;
376 [ + + ]: 48 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
377 : 2 : libspdm_release_receiver_buffer (spdm_context);
378 : 2 : return status;
379 : : }
380 [ - + ]: 46 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
381 : 0 : libspdm_release_receiver_buffer (spdm_context);
382 : 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
383 : : }
384 [ + + ]: 46 : if (spdm_encapsulated_response_ack_response->header.request_response_code == SPDM_ERROR) {
385 : 4 : status = libspdm_handle_error_response_main(
386 : : spdm_context, session_id,
387 : : &spdm_response_size, (void **)&spdm_response,
388 : : SPDM_DELIVER_ENCAPSULATED_RESPONSE,
389 : : SPDM_ENCAPSULATED_RESPONSE_ACK);
390 [ + + ]: 4 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
391 : 2 : libspdm_release_receiver_buffer (spdm_context);
392 : 2 : return status;
393 : : }
394 : 2 : spdm_encapsulated_response_ack_response = (void *)spdm_response;
395 [ + + ]: 42 : } else if (spdm_encapsulated_response_ack_response->header.request_response_code !=
396 : : SPDM_ENCAPSULATED_RESPONSE_ACK) {
397 : 2 : libspdm_release_receiver_buffer (spdm_context);
398 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
399 : : }
400 : 42 : if (spdm_encapsulated_response_ack_response->header.spdm_version !=
401 [ + + ]: 42 : spdm_deliver_encapsulated_response_request->header.spdm_version) {
402 : 2 : libspdm_release_receiver_buffer (spdm_context);
403 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
404 : : }
405 [ + + ]: 40 : if (spdm_encapsulated_response_ack_response->header.spdm_version >=
406 : : SPDM_MESSAGE_VERSION_12) {
407 : 28 : ack_header_size = sizeof(spdm_encapsulated_response_ack_response_t);
408 : : } else {
409 : 12 : ack_header_size = sizeof(spdm_message_header_t);
410 : : }
411 [ + + ]: 40 : if (spdm_response_size < ack_header_size) {
412 : 2 : libspdm_release_receiver_buffer (spdm_context);
413 : 2 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
414 : : }
415 : :
416 [ + + ]: 38 : if (spdm_encapsulated_response_ack_response->header.spdm_version >=
417 : : SPDM_MESSAGE_VERSION_12) {
418 : 26 : if (spdm_encapsulated_response_ack_response->ack_request_id !=
419 [ + + ]: 26 : spdm_deliver_encapsulated_response_request->header.param1) {
420 : 2 : libspdm_release_receiver_buffer (spdm_context);
421 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
422 : : }
423 : : }
424 : :
425 [ + + + + ]: 36 : switch (spdm_encapsulated_response_ack_response->header.param2) {
426 : 18 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_ABSENT:
427 : 18 : libspdm_release_receiver_buffer (spdm_context);
428 : 18 : return LIBSPDM_STATUS_SUCCESS;
429 : 2 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_PRESENT:
430 : 2 : break;
431 : 14 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_REQ_SLOT_NUMBER:
432 [ + + ]: 14 : if (spdm_response_size >= ack_header_size + sizeof(uint8_t)) {
433 [ + + + - ]: 12 : if ((req_slot_id_param != NULL) && (*req_slot_id_param == 0)) {
434 : 10 : *req_slot_id_param =
435 : 10 : *((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
436 : : /* 0xFF or 0xF slot is not allowed. */
437 [ + + ]: 10 : if (*req_slot_id_param >= SPDM_MAX_SLOT_COUNT) {
438 : 2 : libspdm_release_receiver_buffer (spdm_context);
439 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
440 : : }
441 : : /* The Responder shall not designate a slot that is not provisioned. */
442 : 8 : if (spdm_context->local_context.local_cert_chain_provision[
443 [ + + ]: 8 : *req_slot_id_param] == NULL) {
444 : 4 : libspdm_release_receiver_buffer (spdm_context);
445 : 4 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
446 : : }
447 : :
448 [ + + ]: 4 : if ((spdm_encapsulated_response_ack_response->header.spdm_version >=
449 : 2 : SPDM_MESSAGE_VERSION_13) &&
450 [ - + ]: 2 : spdm_context->connection_info.multi_key_conn_req) {
451 : 0 : if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param
452 [ # # ]: 0 : ] & SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
453 : 0 : libspdm_release_receiver_buffer (spdm_context);
454 : 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
455 : : }
456 : : }
457 : : }
458 : 6 : libspdm_release_receiver_buffer (spdm_context);
459 : 6 : return LIBSPDM_STATUS_SUCCESS;
460 : : } else {
461 : 2 : libspdm_release_receiver_buffer (spdm_context);
462 : 2 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
463 : : }
464 : : break;
465 : 2 : default:
466 : 2 : libspdm_release_receiver_buffer (spdm_context);
467 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
468 : : }
469 : 2 : request_id = spdm_encapsulated_response_ack_response->header.param1;
470 : :
471 : 2 : encapsulated_request =
472 : : ((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
473 : 2 : encapsulated_request_size = spdm_response_size - ack_header_size;
474 : :
475 : 2 : libspdm_copy_mem (spdm_context->last_spdm_request,
476 : 2 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
477 : : encapsulated_request,
478 : : encapsulated_request_size);
479 : 2 : spdm_context->last_spdm_request_size = encapsulated_request_size;
480 : 2 : encapsulated_request = (void *)spdm_context->last_spdm_request;
481 : :
482 : 2 : libspdm_release_receiver_buffer (spdm_context);
483 : : }
484 : :
485 : : return LIBSPDM_STATUS_SUCCESS;
486 : : }
487 : :
488 : 42 : libspdm_return_t libspdm_send_receive_encap_request(void *spdm_context, const uint32_t *session_id)
489 : : {
490 : 42 : return libspdm_encapsulated_request(spdm_context, session_id, 0, NULL);
491 : : }
492 : :
493 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
|