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 : 39 : 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 : 39 : context = spdm_context;
18 : 39 : context->get_encap_response_func = (void *)get_encap_response_func;
19 : 39 : }
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 : 21 : 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 : 21 : 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 [ + + ]: 136 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(get_encap_response_struct); index++) {
69 [ + + ]: 123 : if (request_response_code == get_encap_response_struct[index].request_response_code) {
70 : 8 : return get_encap_response_struct[index].get_encap_response_func;
71 : : }
72 : : }
73 : 13 : 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 : 21 : 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 : 21 : spdm_requester = encap_request;
96 [ - + ]: 21 : 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 : 21 : libspdm_reset_message_buffer_via_encap_request_code(
104 : 21 : spdm_context, session_info, spdm_requester->request_response_code);
105 : :
106 : 21 : get_encap_response_func = libspdm_get_encap_response_func_via_request_code(
107 : 21 : spdm_requester->request_response_code);
108 [ + + ]: 21 : if (get_encap_response_func == NULL) {
109 : 13 : get_encap_response_func =
110 : 13 : (libspdm_get_encap_response_func)spdm_context->get_encap_response_func;
111 : : }
112 [ + + ]: 21 : if (get_encap_response_func != NULL) {
113 : 11 : return get_encap_response_func(
114 : : spdm_context, encap_request_size, encap_request,
115 : : encap_response_size, encap_response);
116 : : } else {
117 : 10 : 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 : 33 : 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 [ + + ]: 33 : if (!libspdm_is_encap_supported(spdm_context)) {
157 : 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
158 : : }
159 : :
160 [ + + ]: 32 : if (session_id != NULL) {
161 : 2 : session_info = libspdm_get_session_info_via_session_id(spdm_context, *session_id);
162 [ - + ]: 2 : if (session_info == NULL) {
163 : 0 : LIBSPDM_ASSERT(false);
164 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
165 : : }
166 [ - + - - : 2 : 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 : 30 : session_info = NULL;
173 [ - + ]: 30 : LIBSPDM_ASSERT(mut_auth_requested == 0);
174 : : }
175 : :
176 : :
177 : : /* Cache */
178 : 32 : libspdm_reset_message_mut_b(spdm_context);
179 : 32 : libspdm_reset_message_mut_c(spdm_context);
180 : :
181 [ + + ]: 32 : if (session_id == NULL) {
182 : 30 : spdm_context->last_spdm_request_session_id_valid = false;
183 : 30 : spdm_context->last_spdm_request_session_id = 0;
184 : : } else {
185 : 2 : spdm_context->last_spdm_request_session_id_valid = true;
186 : 2 : spdm_context->last_spdm_request_session_id = *session_id;
187 : : }
188 : :
189 [ - + ]: 32 : if (mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS) {
190 : : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
191 : 0 : get_digests = (void *)spdm_context->last_spdm_request;
192 : 0 : get_digests->header.spdm_version = libspdm_get_connection_version (spdm_context);
193 : 0 : get_digests->header.request_response_code = SPDM_GET_DIGESTS;
194 : 0 : get_digests->header.param1 = 0;
195 : 0 : get_digests->header.param2 = 0;
196 : 0 : spdm_context->last_spdm_request_size = sizeof(spdm_get_digest_request_t);
197 : 0 : encapsulated_request = (void *)spdm_context->last_spdm_request;
198 : 0 : encapsulated_request_size = spdm_context->last_spdm_request_size;
199 : 0 : 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 : 32 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
205 : 32 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
206 [ + + ]: 32 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
207 : 1 : return status;
208 : : }
209 [ - + ]: 31 : LIBSPDM_ASSERT (message_size >= transport_header_size +
210 : : spdm_context->local_context.capability.transport_tail_size);
211 : 31 : spdm_request = (void *)(message + transport_header_size);
212 : 31 : spdm_request_size = message_size - transport_header_size -
213 : 31 : spdm_context->local_context.capability.transport_tail_size;
214 : :
215 : 31 : spdm_context->crypto_request = true;
216 : 31 : spdm_get_encapsulated_request_request = (void *)spdm_request;
217 : 31 : spdm_get_encapsulated_request_request->header.spdm_version =
218 : 31 : libspdm_get_connection_version (spdm_context);
219 : : spdm_get_encapsulated_request_request->header
220 : 31 : .request_response_code = SPDM_GET_ENCAPSULATED_REQUEST;
221 : 31 : spdm_get_encapsulated_request_request->header.param1 = 0;
222 : 31 : spdm_get_encapsulated_request_request->header.param2 = 0;
223 : 31 : spdm_request_size = sizeof(spdm_get_encapsulated_request_request_t);
224 : 31 : libspdm_reset_message_buffer_via_request_code
225 : : (spdm_context, NULL,
226 : 31 : spdm_get_encapsulated_request_request->header.request_response_code);
227 : 31 : status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size,
228 : : spdm_request);
229 [ + + ]: 31 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
230 : 1 : libspdm_release_sender_buffer (spdm_context);
231 : 1 : return status;
232 : : }
233 : 30 : libspdm_release_sender_buffer (spdm_context);
234 : 30 : spdm_get_encapsulated_request_request = (void *)spdm_context->last_spdm_request;
235 : :
236 : : /* receive */
237 : :
238 : 30 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
239 [ + + ]: 30 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
240 : 1 : return status;
241 : : }
242 [ - + ]: 29 : LIBSPDM_ASSERT (message_size >= transport_header_size);
243 : 29 : spdm_response = (void *)(message);
244 : 29 : spdm_response_size = message_size;
245 : :
246 : 29 : status = libspdm_receive_spdm_response(
247 : : spdm_context, session_id, &spdm_response_size,
248 : : (void **)&spdm_response);
249 : 29 : libspdm_encapsulated_request_response = (void *)spdm_response;
250 [ + + ]: 29 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
251 : 1 : libspdm_release_receiver_buffer (spdm_context);
252 : 1 : return status;
253 : : }
254 [ + + ]: 28 : if (libspdm_encapsulated_request_response->header.request_response_code == SPDM_ERROR) {
255 : 3 : const uint8_t error_code = libspdm_encapsulated_request_response->header.param1;
256 : :
257 : 3 : libspdm_release_receiver_buffer(spdm_context);
258 : :
259 [ - + ]: 3 : if (spdm_response_size < sizeof(spdm_error_response_t)) {
260 : 0 : libspdm_release_receiver_buffer (spdm_context);
261 : 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
262 : : }
263 : :
264 [ + - ]: 3 : if (mut_auth_requested == 0) {
265 : : /* Responder can send NoPendingRequests or UnexpectedRequest if it has no
266 : : * encapsulated request for the Requester. */
267 [ + + + - ]: 3 : if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
268 : : (error_code == SPDM_ERROR_CODE_NO_PENDING_REQUESTS)) {
269 : :
270 : 1 : return LIBSPDM_STATUS_SUCCESS;
271 : : }
272 [ + - + + ]: 2 : if ((libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) &&
273 : : (error_code == SPDM_ERROR_CODE_UNEXPECTED_REQUEST)) {
274 : 1 : return LIBSPDM_STATUS_SUCCESS;
275 : : }
276 : : }
277 : 1 : status = libspdm_handle_error_response_main(
278 : : spdm_context, session_id,
279 : : &spdm_response_size, (void **)&spdm_response,
280 : : SPDM_GET_ENCAPSULATED_REQUEST, SPDM_ENCAPSULATED_REQUEST);
281 : 1 : return status;
282 : : }
283 : 25 : if (libspdm_encapsulated_request_response->header.spdm_version !=
284 [ + + ]: 25 : spdm_get_encapsulated_request_request->header.spdm_version) {
285 : 2 : libspdm_release_receiver_buffer (spdm_context);
286 : 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
287 : : }
288 : :
289 [ + + ]: 23 : if (libspdm_encapsulated_request_response->header.request_response_code !=
290 : : SPDM_ENCAPSULATED_REQUEST) {
291 : 1 : libspdm_release_receiver_buffer (spdm_context);
292 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
293 : : }
294 [ + + ]: 22 : if (spdm_response_size <= sizeof(spdm_encapsulated_request_response_t)) {
295 : 1 : libspdm_release_receiver_buffer (spdm_context);
296 : 1 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
297 : : }
298 : :
299 : 21 : request_id = libspdm_encapsulated_request_response->header.param1;
300 : :
301 : 21 : encapsulated_request = (void *)(libspdm_encapsulated_request_response + 1);
302 : 21 : encapsulated_request_size =
303 : 21 : spdm_response_size - sizeof(spdm_encapsulated_request_response_t);
304 : :
305 : 21 : libspdm_copy_mem (spdm_context->last_spdm_request,
306 : 21 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
307 : : encapsulated_request,
308 : : encapsulated_request_size);
309 : 21 : spdm_context->last_spdm_request_size = encapsulated_request_size;
310 : 21 : encapsulated_request = (void *)spdm_context->last_spdm_request;
311 : :
312 : 21 : libspdm_release_receiver_buffer (spdm_context);
313 : : }
314 : :
315 : : while (true) {
316 : : /* Process request. */
317 : 22 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
318 : 22 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
319 [ + + ]: 22 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
320 : 1 : return status;
321 : : }
322 [ - + ]: 21 : LIBSPDM_ASSERT (message_size >= transport_header_size +
323 : : spdm_context->local_context.capability.transport_tail_size);
324 : 21 : spdm_request = (void *)(message + transport_header_size);
325 : 21 : spdm_request_size = message_size - transport_header_size -
326 : 21 : spdm_context->local_context.capability.transport_tail_size;
327 : :
328 : 21 : spdm_context->crypto_request = true;
329 : 21 : spdm_deliver_encapsulated_response_request = (void *)spdm_request;
330 : 21 : spdm_deliver_encapsulated_response_request->header.spdm_version =
331 : 21 : libspdm_get_connection_version (spdm_context);
332 : 21 : spdm_deliver_encapsulated_response_request->header.request_response_code =
333 : : SPDM_DELIVER_ENCAPSULATED_RESPONSE;
334 : 21 : spdm_deliver_encapsulated_response_request->header.param1 = request_id;
335 : 21 : spdm_deliver_encapsulated_response_request->header.param2 = 0;
336 : 21 : encapsulated_response = (void *)(spdm_deliver_encapsulated_response_request + 1);
337 : 21 : encapsulated_response_size =
338 : 21 : spdm_request_size - sizeof(spdm_deliver_encapsulated_response_request_t);
339 : :
340 : 21 : status = libspdm_process_encapsulated_request(
341 : : spdm_context, session_info, encapsulated_request_size,
342 : : encapsulated_request, &encapsulated_response_size,
343 : : encapsulated_response);
344 [ + + ]: 21 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
345 : 1 : libspdm_release_sender_buffer (spdm_context);
346 : 1 : return status;
347 : : }
348 : :
349 : 20 : spdm_request_size =
350 : 20 : sizeof(spdm_deliver_encapsulated_response_request_t) + encapsulated_response_size;
351 : 20 : status = libspdm_send_spdm_request(
352 : : spdm_context, session_id, spdm_request_size,
353 : : spdm_request);
354 [ + + ]: 20 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
355 : 1 : libspdm_release_sender_buffer (spdm_context);
356 : 1 : return status;
357 : : }
358 : 19 : libspdm_release_sender_buffer (spdm_context);
359 : 19 : spdm_deliver_encapsulated_response_request = (void *)spdm_context->last_spdm_request;
360 : :
361 : : /* Receive. */
362 : 19 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
363 [ + + ]: 19 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
364 : 1 : return status;
365 : : }
366 [ - + ]: 18 : LIBSPDM_ASSERT (message_size >= transport_header_size);
367 : 18 : spdm_response = (void *)(message);
368 : 18 : spdm_response_size = message_size;
369 : :
370 : 18 : status = libspdm_receive_spdm_response(
371 : : spdm_context, session_id, &spdm_response_size,
372 : : (void **)&spdm_response);
373 : 18 : spdm_encapsulated_response_ack_response = (void *)spdm_response;
374 [ + + ]: 18 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
375 : 1 : libspdm_release_receiver_buffer (spdm_context);
376 : 1 : return status;
377 : : }
378 [ + + ]: 17 : if (spdm_encapsulated_response_ack_response->header.request_response_code == SPDM_ERROR) {
379 : 1 : libspdm_release_receiver_buffer(spdm_context);
380 : :
381 [ - + ]: 1 : if (spdm_response_size < sizeof(spdm_error_response_t)) {
382 : 0 : libspdm_release_receiver_buffer (spdm_context);
383 : 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
384 : : }
385 : :
386 : 1 : status = libspdm_handle_error_response_main(
387 : : spdm_context, session_id,
388 : : &spdm_response_size, (void **)&spdm_response,
389 : : SPDM_DELIVER_ENCAPSULATED_RESPONSE,
390 : : SPDM_ENCAPSULATED_RESPONSE_ACK);
391 : 1 : return status;
392 [ + + ]: 16 : } else if (spdm_encapsulated_response_ack_response->header.request_response_code !=
393 : : SPDM_ENCAPSULATED_RESPONSE_ACK) {
394 : 1 : libspdm_release_receiver_buffer (spdm_context);
395 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
396 : : }
397 : 15 : if (spdm_encapsulated_response_ack_response->header.spdm_version !=
398 [ + + ]: 15 : spdm_deliver_encapsulated_response_request->header.spdm_version) {
399 : 1 : libspdm_release_receiver_buffer (spdm_context);
400 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
401 : : }
402 [ + + ]: 14 : if (spdm_encapsulated_response_ack_response->header.spdm_version >=
403 : : SPDM_MESSAGE_VERSION_12) {
404 : 8 : ack_header_size = sizeof(spdm_encapsulated_response_ack_response_t);
405 : : } else {
406 : 6 : ack_header_size = sizeof(spdm_message_header_t);
407 : : }
408 [ + + ]: 14 : if (spdm_response_size < ack_header_size) {
409 : 1 : libspdm_release_receiver_buffer (spdm_context);
410 : 1 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
411 : : }
412 : :
413 [ + + ]: 13 : if (spdm_encapsulated_response_ack_response->header.spdm_version >=
414 : : SPDM_MESSAGE_VERSION_12) {
415 : 7 : if (spdm_encapsulated_response_ack_response->ack_request_id !=
416 [ + + ]: 7 : spdm_deliver_encapsulated_response_request->header.param1) {
417 : 1 : libspdm_release_receiver_buffer (spdm_context);
418 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
419 : : }
420 : : }
421 : :
422 [ + + + + ]: 12 : switch (spdm_encapsulated_response_ack_response->header.param2) {
423 : 6 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_ABSENT:
424 : 6 : libspdm_release_receiver_buffer (spdm_context);
425 : 6 : return LIBSPDM_STATUS_SUCCESS;
426 : 1 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_PRESENT:
427 : 1 : break;
428 : 4 : case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_REQ_SLOT_NUMBER:
429 [ + + ]: 4 : if (spdm_response_size >= ack_header_size + sizeof(uint8_t)) {
430 [ + + + - ]: 3 : if ((req_slot_id_param != NULL) && (*req_slot_id_param == 0)) {
431 : 2 : *req_slot_id_param =
432 : 2 : *((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
433 : : /* 0xFF or 0xF slot is not allowed. */
434 [ + + ]: 2 : if (*req_slot_id_param >= SPDM_MAX_SLOT_COUNT) {
435 : 1 : libspdm_release_receiver_buffer (spdm_context);
436 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
437 : : }
438 : :
439 [ + - ]: 1 : if ((spdm_encapsulated_response_ack_response->header.spdm_version >=
440 : 1 : SPDM_MESSAGE_VERSION_13) &&
441 [ + - ]: 1 : spdm_context->connection_info.multi_key_conn_req) {
442 : 1 : if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param
443 [ + - ]: 1 : ] & SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
444 : 1 : libspdm_release_receiver_buffer (spdm_context);
445 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
446 : : }
447 : : }
448 : : }
449 : 1 : libspdm_release_receiver_buffer (spdm_context);
450 : 1 : return LIBSPDM_STATUS_SUCCESS;
451 : : } else {
452 : 1 : libspdm_release_receiver_buffer (spdm_context);
453 : 1 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
454 : : }
455 : : break;
456 : 1 : default:
457 : 1 : libspdm_release_receiver_buffer (spdm_context);
458 : 1 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
459 : : }
460 : 1 : request_id = spdm_encapsulated_response_ack_response->header.param1;
461 : :
462 : 1 : encapsulated_request =
463 : : ((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
464 : 1 : encapsulated_request_size = spdm_response_size - ack_header_size;
465 : :
466 : 1 : libspdm_copy_mem (spdm_context->last_spdm_request,
467 : 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
468 : : encapsulated_request,
469 : : encapsulated_request_size);
470 : 1 : spdm_context->last_spdm_request_size = encapsulated_request_size;
471 : 1 : encapsulated_request = (void *)spdm_context->last_spdm_request;
472 : :
473 : 1 : libspdm_release_receiver_buffer (spdm_context);
474 : : }
475 : :
476 : : return LIBSPDM_STATUS_SUCCESS;
477 : : }
478 : :
479 : 17 : libspdm_return_t libspdm_send_receive_encap_request(void *spdm_context, const uint32_t *session_id)
480 : : {
481 : 17 : return libspdm_encapsulated_request(spdm_context, session_id, 0, NULL);
482 : : }
483 : :
484 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
|