Skip to content

Commit

Permalink
Fix chunk_seq_no wrap in chunk send ack.
Browse files Browse the repository at this point in the history
Fix DMTF#2875

Signed-off-by: Aaron Li <[email protected]>
  • Loading branch information
Li-Aaron committed Jan 13, 2025
1 parent 3c6a7d7 commit cfe039c
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
5 changes: 4 additions & 1 deletion library/spdm_responder_lib/libspdm_rsp_chunk_send_ack.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -160,6 +160,9 @@ libspdm_return_t libspdm_get_response_chunk_send(libspdm_context_t *spdm_context
|| ((uint32_t) request_size
> spdm_context->local_context.capability.data_transfer_size))) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
} else if (spdm_request->chunk_seq_no == 0) {
/* Chunk seq no wrapped */
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
} else {

libspdm_copy_mem(
Expand Down
85 changes: 84 additions & 1 deletion unit_test/test_spdm_responder/chunk_send_ack.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2022 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -1705,6 +1705,87 @@ void libspdm_test_responder_chunk_send_ack_rsp_case19(void** state)
libspdm_test_responder_chunk_send_ack_reset_send_state(spdm_context);
}

/**
* Test 20: Request chunk seq warpped.
**/
void libspdm_test_responder_chunk_send_ack_rsp_case20(void** state)
{
libspdm_return_t status;

libspdm_test_context_t* spdm_test_context;
libspdm_context_t* spdm_context;

size_t request_size;
size_t response_size;

uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE];
uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];

spdm_chunk_send_request_t* chunk_send_request;
spdm_chunk_send_ack_response_t* chunk_send_ack_response;
spdm_error_response_t* error_response;

const uint8_t* chunk_src;
uint8_t* chunk_dst;

/* Format the last chunk. */
spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 20;

libspdm_test_responder_chunk_send_ack_setup_algo_state(spdm_context);
spdm_context->chunk_context.send.chunk_in_use = true;
spdm_context->chunk_context.send.chunk_handle = (uint8_t) spdm_test_context->case_id;
spdm_context->chunk_context.send.chunk_seq_no = 65535; /* maximum chunk seq received */
spdm_context->chunk_context.send.large_message_size = 0x10000;
spdm_context->chunk_context.send.chunk_bytes_transferred = 0x8000;

chunk_src = (const uint8_t*) &m_libspdm_chunk_send_negotiate_algorithm_request1;

libspdm_zero_mem(request, sizeof(request));
chunk_send_request = (spdm_chunk_send_request_t*) request;

chunk_send_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
chunk_send_request->header.request_response_code = SPDM_CHUNK_SEND;
chunk_send_request->header.param1 = 0;
chunk_send_request->header.param2 = (uint8_t) spdm_test_context->case_id; /* chunk_handle */
chunk_send_request->chunk_seq_no = 0; /* chunk seq wrapped */

chunk_send_request->chunk_size =
spdm_context->local_context.capability.data_transfer_size
- sizeof(spdm_chunk_send_request_t);

chunk_dst = ((uint8_t*) (chunk_send_request + 1));

request_size = sizeof(spdm_chunk_send_request_t)
+ chunk_send_request->chunk_size;

libspdm_copy_mem(chunk_dst, chunk_send_request->chunk_size,
chunk_src, chunk_send_request->chunk_size);

response_size = sizeof(response);
status = libspdm_get_response_chunk_send(
spdm_context,
request_size, request,
&response_size, response);

assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
assert_true(response_size == sizeof(spdm_chunk_send_ack_response_t)
+ sizeof(spdm_error_response_t));

chunk_send_ack_response = (spdm_chunk_send_ack_response_t*) response;
assert_int_equal(chunk_send_ack_response->header.param1,
SPDM_CHUNK_SEND_ACK_RESPONSE_ATTRIBUTE_EARLY_ERROR_DETECTED);

error_response = (spdm_error_response_t*) (chunk_send_ack_response + 1);
assert_int_equal(error_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
assert_int_equal(error_response->header.request_response_code, SPDM_ERROR);
assert_int_equal(error_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
assert_int_equal(error_response->header.param2, 0);

libspdm_test_responder_chunk_send_ack_reset_send_state(spdm_context);
}

int libspdm_responder_chunk_send_ack_test_main(void)
{
const struct CMUnitTest spdm_responder_chunk_send_ack_tests[] = {
Expand Down Expand Up @@ -1750,6 +1831,8 @@ int libspdm_responder_chunk_send_ack_test_main(void)
cmocka_unit_test(libspdm_test_responder_chunk_send_ack_rsp_case18),
/* Request missing LAST_CHUNK when request size != data transfer size. */
cmocka_unit_test(libspdm_test_responder_chunk_send_ack_rsp_case19),
/* Request chunk seq warpped. */
cmocka_unit_test(libspdm_test_responder_chunk_send_ack_rsp_case20),
};

libspdm_test_context_t test_context = {
Expand Down

0 comments on commit cfe039c

Please sign in to comment.