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_RESPOND_IF_READY_SUPPORT
10 : /**
11 : * This function sends RESPOND_IF_READY and receives an expected SPDM response.
12 : *
13 : * @param spdm_context A pointer to the SPDM context.
14 : * @param response_size The size of the response.
15 : * On input, it means the size in bytes of response data buffer.
16 : * On output, it means the size in bytes of copied response data
17 : * buffer if LIBSPDM_STATUS_SUCCESS is returned.
18 : * @param response The SPDM response message.
19 : * @param expected_response_code Indicate the expected response code.
20 : **/
21 29 : static libspdm_return_t libspdm_requester_respond_if_ready(libspdm_context_t *spdm_context,
22 : const uint32_t *session_id,
23 : size_t *response_size,
24 : void **response,
25 : uint8_t expected_response_code)
26 : {
27 : libspdm_return_t status;
28 : spdm_response_if_ready_request_t *spdm_request;
29 : size_t spdm_request_size;
30 : spdm_message_header_t *spdm_response;
31 : uint8_t *message;
32 : size_t message_size;
33 : size_t transport_header_size;
34 :
35 : /* the response might be in response buffer in normal SPDM message
36 : * or it is in scratch buffer in case of secure SPDM message
37 : * the response buffer is in acquired state, so we release it*/
38 29 : libspdm_release_receiver_buffer (spdm_context);
39 :
40 : /* now we can get sender buffer */
41 29 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
42 29 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
43 29 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
44 0 : return status;
45 : }
46 29 : LIBSPDM_ASSERT (message_size >= transport_header_size +
47 : spdm_context->local_context.capability.transport_tail_size);
48 29 : spdm_request = (void *)(message + transport_header_size);
49 29 : spdm_request_size = message_size - transport_header_size -
50 29 : spdm_context->local_context.capability.transport_tail_size;
51 :
52 29 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_response_if_ready_request_t));
53 29 : spdm_context->crypto_request = true;
54 29 : spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
55 29 : spdm_request->header.request_response_code = SPDM_RESPOND_IF_READY;
56 29 : spdm_request->header.param1 = spdm_context->error_data.request_code;
57 29 : spdm_request->header.param2 = spdm_context->error_data.token;
58 29 : spdm_request_size = sizeof(spdm_response_if_ready_request_t);
59 29 : status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size, spdm_request);
60 29 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
61 0 : libspdm_release_sender_buffer (spdm_context);
62 : /* need acquire response buffer, so that the caller can release it */
63 0 : status = libspdm_acquire_receiver_buffer (spdm_context, response_size, response);
64 0 : return status;
65 : }
66 29 : libspdm_release_sender_buffer (spdm_context);
67 29 : spdm_request = (void *)spdm_context->last_spdm_request;
68 :
69 : /* receive
70 : * do not release response buffer in case of error, because caller will release it*/
71 :
72 29 : status = libspdm_acquire_receiver_buffer (spdm_context, response_size, response);
73 29 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
74 0 : return status;
75 : }
76 29 : LIBSPDM_ASSERT (*response_size >= transport_header_size);
77 :
78 29 : status = libspdm_receive_spdm_response(spdm_context, session_id,
79 : response_size, response);
80 29 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
81 0 : return status;
82 : }
83 29 : spdm_response = (void *)(*response);
84 29 : if (*response_size < sizeof(spdm_message_header_t)) {
85 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
86 : }
87 29 : if (spdm_response->spdm_version != spdm_request->header.spdm_version) {
88 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
89 : }
90 29 : if (spdm_response->request_response_code == SPDM_ERROR) {
91 16 : status = libspdm_handle_simple_error_response(spdm_context, spdm_response->param1);
92 16 : return status;
93 : }
94 13 : if (spdm_response->request_response_code != expected_response_code) {
95 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
96 : }
97 :
98 13 : return LIBSPDM_STATUS_SUCCESS;
99 : }
100 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
101 :
102 428 : libspdm_return_t libspdm_handle_simple_error_response(libspdm_context_t *spdm_context,
103 : uint8_t error_code)
104 : {
105 : spdm_set_certificate_request_t *last_spdm_request;
106 :
107 428 : if (error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
108 18 : return LIBSPDM_STATUS_NOT_READY_PEER;
109 : }
110 :
111 410 : if (error_code == SPDM_ERROR_CODE_BUSY) {
112 44 : return LIBSPDM_STATUS_BUSY_PEER;
113 : }
114 :
115 366 : last_spdm_request = (void *)spdm_context->last_spdm_request;
116 366 : if ((last_spdm_request->header.request_response_code == SPDM_SET_CERTIFICATE) ||
117 365 : (last_spdm_request->header.request_response_code == SPDM_GET_CSR)) {
118 :
119 4 : if (error_code == SPDM_ERROR_CODE_RESET_REQUIRED) {
120 4 : if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
121 2 : !libspdm_is_capabilities_flag_supported(
122 : spdm_context, true, 0,
123 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP)) {
124 1 : return LIBSPDM_STATUS_ERROR_PEER;
125 : }
126 : /* CERT_INSTALL_RESET_CAP for a 1.2 Responder is not checked because it was not defined
127 : * in SPDM 1.2.0. */
128 3 : return LIBSPDM_STATUS_RESET_REQUIRED_PEER;
129 : }
130 : }
131 :
132 362 : if (last_spdm_request->header.request_response_code == SPDM_SET_KEY_PAIR_INFO) {
133 1 : if (error_code == SPDM_ERROR_CODE_RESET_REQUIRED) {
134 1 : if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_14) &&
135 1 : !libspdm_is_capabilities_flag_supported(
136 : spdm_context, true, 0,
137 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_RESET_CAP)) {
138 0 : return LIBSPDM_STATUS_ERROR_PEER;
139 : }
140 1 : return LIBSPDM_STATUS_RESET_REQUIRED_PEER;
141 : }
142 : }
143 :
144 361 : if (error_code == SPDM_ERROR_CODE_REQUEST_RESYNCH) {
145 23 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
146 23 : return LIBSPDM_STATUS_RESYNCH_PEER;
147 : }
148 :
149 338 : return LIBSPDM_STATUS_ERROR_PEER;
150 : }
151 :
152 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
153 : /**
154 : * This function handles RESPONSE_NOT_READY error code.
155 : *
156 : * @param spdm_context A pointer to the SPDM context.
157 : * @param response_size The size of the response.
158 : * On input, it means the size in bytes of response data buffer.
159 : * On output, it means the size in bytes of copied response data
160 : * buffer if LIBSPDM_STATUS_SUCCESS is returned.
161 : * @param response The SPDM response message.
162 : * @param original_request_code Indicate the original request code.
163 : * @param expected_response_code Indicate the expected response code.
164 : **/
165 29 : static libspdm_return_t libspdm_handle_response_not_ready(libspdm_context_t *spdm_context,
166 : const uint32_t *session_id,
167 : size_t *response_size,
168 : void **response,
169 : uint8_t original_request_code,
170 : uint8_t expected_response_code)
171 : {
172 : spdm_error_response_t *spdm_response;
173 : spdm_error_data_response_not_ready_t *extend_error_data;
174 :
175 29 : if (*response_size < sizeof(spdm_error_response_t) +
176 : sizeof(spdm_error_data_response_not_ready_t)) {
177 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
178 : }
179 :
180 29 : spdm_response = *response;
181 29 : extend_error_data = (spdm_error_data_response_not_ready_t *)(spdm_response + 1);
182 29 : LIBSPDM_ASSERT(spdm_response->header.request_response_code == SPDM_ERROR);
183 29 : LIBSPDM_ASSERT(spdm_response->header.param1 == SPDM_ERROR_CODE_RESPONSE_NOT_READY);
184 :
185 29 : if (extend_error_data->request_code != original_request_code) {
186 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
187 : }
188 29 : if (extend_error_data->rd_tm <= 1) {
189 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
190 : }
191 29 : if (extend_error_data->rd_exponent > LIBSPDM_MAX_RDT_EXPONENT) {
192 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
193 : }
194 :
195 29 : spdm_context->error_data.rd_exponent = extend_error_data->rd_exponent;
196 29 : spdm_context->error_data.request_code = extend_error_data->request_code;
197 29 : spdm_context->error_data.token = extend_error_data->token;
198 29 : spdm_context->error_data.rd_tm = extend_error_data->rd_tm;
199 :
200 29 : libspdm_sleep((uint64_t)1 << extend_error_data->rd_exponent);
201 :
202 29 : return libspdm_requester_respond_if_ready(spdm_context, session_id,
203 : response_size, response,
204 : expected_response_code);
205 : }
206 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
207 :
208 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
209 11 : libspdm_return_t libspdm_handle_error_large_response(
210 : libspdm_context_t *spdm_context,
211 : const uint32_t *session_id,
212 : size_t *inout_response_size,
213 : void *inout_response,
214 : size_t response_capacity,
215 : bool response_from_chunk)
216 : {
217 : libspdm_return_t status;
218 : uint8_t chunk_handle;
219 : spdm_error_response_t* error_response;
220 : spdm_error_data_large_response_t* extend_error_data;
221 :
222 : spdm_chunk_get_request_t* spdm_request;
223 : spdm_chunk_get_request_14_t* spdm_request_14;
224 : size_t spdm_request_size;
225 : spdm_chunk_response_response_t* spdm_response;
226 : spdm_chunk_response_response_14_t* spdm_response_14;
227 : uint8_t* message;
228 : size_t message_size;
229 : size_t transport_header_size;
230 :
231 : uint8_t* scratch_buffer;
232 : size_t scratch_buffer_size;
233 : uint32_t chunk_seq_no;
234 : uint8_t* chunk_ptr;
235 : uint8_t* large_response;
236 : size_t large_response_capacity;
237 : size_t large_response_size;
238 : size_t large_response_size_so_far;
239 : uint64_t max_chunk_data_transfer_size;
240 : size_t min_large_response_size;
241 :
242 11 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_12) {
243 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
244 : }
245 :
246 : /* Fail if requester or responder does not support chunk cap. The Responder's negotiated
247 : * capability flags are only known once the CAPABILITIES response has been processed
248 : * (connection state AFTER_CAPABILITIES). A CAPABILITIES response that carries the Supported
249 : * Algorithms Block can itself be chunked, in which case this handler runs while the state is
250 : * still AFTER_VERSION; skip the check then, since the Responder returning
251 : * ERROR_LARGE_RESPONSE already implies it supports chunking. */
252 11 : if (spdm_context->connection_info.connection_state >= LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
253 10 : if (!libspdm_is_capabilities_flag_supported(
254 : spdm_context, true,
255 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP,
256 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP)) {
257 0 : return LIBSPDM_STATUS_ERROR_PEER;
258 : }
259 : }
260 :
261 11 : if (*inout_response_size < sizeof(spdm_error_response_t) +
262 : sizeof(spdm_error_data_large_response_t)) {
263 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
264 : }
265 :
266 11 : error_response = inout_response;
267 11 : extend_error_data =
268 : (spdm_error_data_large_response_t*)(error_response + 1);
269 11 : chunk_handle = extend_error_data->handle;
270 :
271 : /* now we can get sender buffer */
272 11 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
273 :
274 11 : libspdm_get_scratch_buffer(spdm_context, (void**)&scratch_buffer, &scratch_buffer_size);
275 :
276 : /* The first section of the scratch
277 : * buffer may be used for other purposes. Use only after that section. */
278 11 : large_response = scratch_buffer + libspdm_get_scratch_buffer_large_message_offset(spdm_context);
279 11 : large_response_capacity = libspdm_get_scratch_buffer_large_message_capacity(spdm_context);
280 :
281 : /* Temporary send/receive buffers for chunking are in the scratch space */
282 11 : message = scratch_buffer + libspdm_get_scratch_buffer_sender_receiver_offset(spdm_context);
283 11 : message_size = libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context);
284 :
285 11 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_14) {
286 : /* chunk seq no wrap not considered in spdm 1.4+ */
287 9 : max_chunk_data_transfer_size =
288 9 : ((size_t) spdm_context->local_context.capability.data_transfer_size
289 9 : - sizeof(spdm_chunk_response_response_t)) * 65536 - sizeof(uint32_t);
290 : }
291 :
292 11 : libspdm_zero_mem(large_response, large_response_capacity);
293 11 : large_response_size = 0;
294 11 : large_response_size_so_far = 0;
295 11 : chunk_seq_no = 0;
296 :
297 : /* Mark that a CHUNK_GET transfer is in progress so that the response to a CHUNK_GET is not
298 : * itself dispatched back into this handler by libspdm_receive_spdm_response. Per spec the
299 : * response to CHUNK_GET must be CHUNK_RESPONSE; a nested ERROR_LARGE_RESPONSE would otherwise
300 : * cause unbounded recursion. */
301 11 : spdm_context->chunk_context.get.chunk_in_use = true;
302 :
303 : do {
304 65623 : LIBSPDM_ASSERT(message_size >= transport_header_size);
305 :
306 65623 : spdm_request = (spdm_chunk_get_request_t*)(void*) (message + transport_header_size);
307 65623 : spdm_request_size = message_size - transport_header_size;
308 65623 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_14) {
309 65612 : LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_chunk_get_request_t));
310 65612 : spdm_request->header.spdm_version = libspdm_get_connection_version(spdm_context);
311 65612 : spdm_request->header.request_response_code = SPDM_CHUNK_GET;
312 65612 : spdm_request->header.param1 = 0;
313 65612 : spdm_request->header.param2 = chunk_handle;
314 65612 : spdm_request->chunk_seq_no = (uint16_t) chunk_seq_no;
315 65612 : spdm_request_size = sizeof(spdm_chunk_get_request_t);
316 :
317 65612 : if ((uint16_t) chunk_seq_no == 0 && large_response_size_so_far != 0) {
318 : /* chunk_seq_no wrapped */
319 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
320 4 : break;
321 : }
322 : } else {
323 11 : LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_chunk_get_request_14_t));
324 11 : spdm_request_14 = (spdm_chunk_get_request_14_t*)spdm_request;
325 11 : spdm_request_14->header.spdm_version = libspdm_get_connection_version(spdm_context);
326 11 : spdm_request_14->header.request_response_code = SPDM_CHUNK_GET;
327 11 : spdm_request_14->header.param1 = 0;
328 11 : spdm_request_14->header.param2 = chunk_handle;
329 11 : spdm_request_14->chunk_seq_no = chunk_seq_no;
330 11 : spdm_request_size = sizeof(spdm_chunk_get_request_14_t);
331 : }
332 :
333 :
334 65622 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
335 : "CHUNK_GET Handle %d SeqNo %d\n", chunk_handle, chunk_seq_no));
336 :
337 65622 : status = libspdm_send_spdm_request(spdm_context, session_id,
338 : spdm_request_size, spdm_request);
339 :
340 65622 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
341 0 : break;
342 : }
343 :
344 65622 : libspdm_zero_mem(message, message_size);
345 65622 : void* response = message;
346 65622 : size_t response_size = message_size;
347 :
348 65622 : status = libspdm_receive_spdm_response(
349 : spdm_context, session_id,
350 : &response_size, &response);
351 :
352 65622 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
353 0 : break;
354 : }
355 65622 : spdm_response = (void*) (response);
356 65622 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
357 0 : status = libspdm_handle_simple_error_response(spdm_context,
358 0 : spdm_response->header.param1);
359 0 : break;
360 : }
361 65622 : if (spdm_response->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
362 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
363 0 : break;
364 : }
365 65622 : if (spdm_response->header.request_response_code != SPDM_CHUNK_RESPONSE) {
366 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
367 0 : break;
368 : }
369 65622 : if (spdm_response->header.param2 != chunk_handle) {
370 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
371 1 : break;
372 : }
373 :
374 : LIBSPDM_ASSERT(sizeof(spdm_chunk_response_response_t) == sizeof(spdm_chunk_response_response_14_t));
375 65621 : if (chunk_seq_no == 0) {
376 :
377 10 : if (response_size
378 10 : < (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t))) {
379 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
380 0 : break;
381 : }
382 10 : if (response_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
383 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
384 0 : break;
385 : }
386 :
387 10 : if (spdm_response->chunk_size
388 : < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12
389 : - sizeof(spdm_chunk_response_response_t)
390 : - sizeof(uint32_t)) {
391 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
392 0 : break;
393 : }
394 :
395 10 : large_response_size = libspdm_read_uint32((const uint8_t *)(spdm_response + 1));
396 10 : chunk_ptr = (uint8_t *)(spdm_response + 1) + sizeof(uint32_t);
397 :
398 10 : if (spdm_response->chunk_size > large_response_size) {
399 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
400 0 : break;
401 : }
402 10 : if (large_response_size > spdm_context->local_context.capability.max_spdm_msg_size) {
403 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
404 0 : break;
405 : }
406 10 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_14
407 8 : && large_response_size > max_chunk_data_transfer_size) {
408 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
409 1 : break;
410 : }
411 9 : if (response_from_chunk) {
412 : /* If the Responder's DataTransferSize is approximately equal to MinDataTransferSize
413 : * then Responder may chunk a message whose size is less than MinDataTransferSize. */
414 1 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_14){
415 1 : min_large_response_size = SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 -
416 : sizeof(spdm_chunk_send_ack_response_14_t);
417 : } else {
418 0 : min_large_response_size = SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 -
419 : sizeof(spdm_chunk_send_ack_response_t);
420 : }
421 : } else {
422 8 : min_large_response_size = SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12;
423 : }
424 9 : if (large_response_size <= min_large_response_size) {
425 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
426 0 : break;
427 : }
428 : } else {
429 65611 : if (response_size < sizeof(spdm_chunk_response_response_t)) {
430 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
431 0 : break;
432 : }
433 65611 : if (spdm_response->chunk_size + large_response_size_so_far > large_response_size) {
434 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
435 0 : break;
436 : }
437 :
438 65611 : if (!(spdm_response->header.param1 & SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK)) {
439 65604 : if (response_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
440 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
441 0 : break;
442 : }
443 65604 : if (spdm_response->chunk_size
444 : < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12
445 : - sizeof(spdm_chunk_response_response_t)) {
446 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
447 0 : break;
448 : }
449 : }
450 :
451 65611 : chunk_ptr = (uint8_t*) (spdm_response + 1);
452 : }
453 65620 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_14) {
454 65609 : if (spdm_response->chunk_seq_no != (uint16_t) chunk_seq_no) {
455 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
456 0 : break;
457 : }
458 : } else {
459 11 : spdm_response_14 = (spdm_chunk_response_response_14_t*)spdm_response;
460 11 : if (spdm_response_14->chunk_seq_no != chunk_seq_no) {
461 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
462 0 : break;
463 : }
464 : }
465 :
466 65620 : if (spdm_response->chunk_size >
467 65620 : response_size - (size_t)(chunk_ptr - (uint8_t *)spdm_response)) {
468 1 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
469 1 : break;
470 : }
471 :
472 65619 : libspdm_copy_mem(large_response + large_response_size_so_far,
473 : large_response_size - large_response_size_so_far,
474 65619 : chunk_ptr, spdm_response->chunk_size);
475 :
476 65619 : large_response_size_so_far += spdm_response->chunk_size;
477 :
478 65619 : chunk_seq_no++;
479 :
480 65619 : } while (LIBSPDM_STATUS_IS_SUCCESS(status)
481 65619 : && large_response_size_so_far < large_response_size
482 131231 : && !(spdm_response->header.param1 & SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK));
483 :
484 :
485 11 : if (LIBSPDM_STATUS_IS_SUCCESS(status)) {
486 7 : if (large_response_size_so_far != large_response_size) {
487 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
488 7 : } else if (large_response_size <= response_capacity) {
489 7 : libspdm_copy_mem(inout_response, response_capacity,
490 : large_response, large_response_size);
491 7 : *inout_response_size = large_response_size;
492 :
493 7 : LIBSPDM_INTERNAL_DUMP_HEX(large_response, large_response_size);
494 7 : libspdm_zero_mem(large_response, large_response_size);
495 : }
496 : }
497 :
498 11 : spdm_context->chunk_context.get.chunk_in_use = false;
499 :
500 11 : return status;
501 : }
502 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
503 :
504 393 : libspdm_return_t libspdm_handle_error_response_main(
505 : libspdm_context_t *spdm_context, const uint32_t *session_id,
506 : size_t *response_size, void **response,
507 : uint8_t original_request_code, uint8_t expected_response_code)
508 : {
509 : spdm_message_header_t *spdm_response;
510 :
511 393 : spdm_response = *response;
512 393 : LIBSPDM_ASSERT(spdm_response->request_response_code == SPDM_ERROR);
513 :
514 393 : if ((spdm_response->param1 == SPDM_ERROR_CODE_DECRYPT_ERROR) && (session_id != NULL)) {
515 5 : libspdm_free_session_id(spdm_context, *session_id);
516 5 : return LIBSPDM_STATUS_SESSION_MSG_ERROR;
517 388 : } else if (spdm_response->param1 == SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
518 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
519 29 : return libspdm_handle_response_not_ready(spdm_context, session_id,
520 : response_size, response,
521 : original_request_code,
522 : expected_response_code);
523 : #else
524 : return LIBSPDM_STATUS_NOT_READY_PEER;
525 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
526 : } else {
527 359 : return libspdm_handle_simple_error_response(spdm_context, spdm_response->param1);
528 : }
529 : }
|