diff --git a/library/spdm_responder_lib/libspdm_rsp_chunk_send_ack.c b/library/spdm_responder_lib/libspdm_rsp_chunk_send_ack.c index 94aa6b02415..dbae3430fcb 100644 --- a/library/spdm_responder_lib/libspdm_rsp_chunk_send_ack.c +++ b/library/spdm_responder_lib/libspdm_rsp_chunk_send_ack.c @@ -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 **/ @@ -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( diff --git a/unit_test/test_spdm_responder/chunk_send_ack.c b/unit_test/test_spdm_responder/chunk_send_ack.c index f392daa61fb..031b3ce8977 100644 --- a/unit_test/test_spdm_responder/chunk_send_ack.c +++ b/unit_test/test_spdm_responder/chunk_send_ack.c @@ -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 **/ @@ -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[] = { @@ -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 = {