LCOV - code coverage report
Current view: top level - unit_test/test_spdm_responder - chunk_response.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 769 769
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 19 19

            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 "spdm_unit_test.h"
       8              : #include "internal/libspdm_responder_lib.h"
       9              : 
      10              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      11              : 
      12              : #define CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE (44)
      13              : 
      14              : /**
      15              :  * Test 1: Responder receives a CHUNK_GET request when it is not expecting it.
      16              :  * Responder does not have response CHUNK cap set.
      17              :  * Expected Behavior: Returns ERROR response message
      18              :  * with SPDM_ERROR_CODE_UNEXPECTED_REQUEST error code.
      19              :  **/
      20            1 : static void rsp_chunk_response_case1(void** state)
      21              : {
      22              :     libspdm_return_t status;
      23              :     libspdm_test_context_t* spdm_test_context;
      24              :     libspdm_context_t* spdm_context;
      25              :     size_t response_size;
      26              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
      27              :     spdm_error_response_t* spdm_response;
      28              :     spdm_chunk_get_request_t spdm_request;
      29              : 
      30            1 :     spdm_test_context = *state;
      31            1 :     spdm_context = spdm_test_context->spdm_context;
      32            1 :     spdm_test_context->case_id = 1;
      33            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
      34              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
      35              : 
      36            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
      37            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
      38              : 
      39            1 :     spdm_context->connection_info.capability.data_transfer_size =
      40              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
      41              : 
      42            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
      43            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
      44            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
      45            1 :     spdm_request.header.param1 = 0;
      46            1 :     spdm_request.header.param2 = 0;
      47            1 :     spdm_request.chunk_seq_no = 0;
      48              : 
      49            1 :     response_size = sizeof(response);
      50            1 :     status = libspdm_get_response_chunk_get(
      51              :         spdm_context,
      52              :         sizeof(spdm_request), &spdm_request,
      53              :         &response_size, response);
      54              : 
      55            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
      56            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
      57              : 
      58            1 :     spdm_response = (spdm_error_response_t*) response;
      59            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
      60            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
      61            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
      62            1 :     assert_int_equal(spdm_response->header.param2, 0);
      63            1 : }
      64              : 
      65              : /**
      66              :  * Test 2: Responder receives a CHUNK_GET request with bad response state.
      67              :  * Expected Behavior: Returns ERROR response message with an error code.
      68              :  **/
      69            1 : static void rsp_chunk_response_case2(void** state)
      70              : {
      71              :     libspdm_return_t status;
      72              :     libspdm_test_context_t* spdm_test_context;
      73              :     libspdm_context_t* spdm_context;
      74              :     size_t response_size;
      75              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
      76              :     spdm_error_response_t* spdm_response;
      77              :     spdm_chunk_get_request_t spdm_request;
      78              : 
      79            1 :     spdm_test_context = *state;
      80            1 :     spdm_context = spdm_test_context->spdm_context;
      81            1 :     spdm_test_context->case_id = 2;
      82            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
      83              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
      84              : 
      85            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
      86            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
      87              : 
      88            1 :     spdm_context->local_context.capability.data_transfer_size =
      89              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
      90              : 
      91            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
      92            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
      93              : 
      94              :     /* Set bad response state */
      95            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
      96              : 
      97            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
      98            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
      99            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     100            1 :     spdm_request.header.param1 = 0;
     101            1 :     spdm_request.header.param2 = 0;
     102            1 :     spdm_request.chunk_seq_no = 0;
     103              : 
     104            1 :     response_size = sizeof(response);
     105            1 :     status = libspdm_get_response_chunk_get(
     106              :         spdm_context,
     107              :         sizeof(spdm_request), &spdm_request,
     108              :         &response_size, response);
     109              : 
     110            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     111            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     112              : 
     113            1 :     spdm_response = (spdm_error_response_t*) response;
     114            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     115            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     116            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
     117            1 :     assert_int_equal(spdm_response->header.param2, 0);
     118            1 : }
     119              : 
     120              : /**
     121              :  * Test 3: Responder receives a CHUNK_GET request with bad connection state.
     122              :  * Expected Behavior: Returns ERROR response message
     123              :  * with SPDM_ERROR_CODE_UNEXPECTED_REQUEST error code.
     124              :  **/
     125            1 : static void rsp_chunk_response_case3(void** state)
     126              : {
     127              :     libspdm_return_t status;
     128              :     libspdm_test_context_t* spdm_test_context;
     129              :     libspdm_context_t* spdm_context;
     130              :     size_t response_size;
     131              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     132              :     spdm_error_response_t* spdm_response;
     133              :     spdm_chunk_get_request_t spdm_request;
     134              : 
     135            1 :     spdm_test_context = *state;
     136            1 :     spdm_context = spdm_test_context->spdm_context;
     137            1 :     spdm_test_context->case_id = 3;
     138            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     139              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     140              : 
     141              :     /* Set bad connection_state */
     142            1 :     spdm_context->connection_info.connection_state =
     143              :         LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES - 1;
     144            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     145              : 
     146            1 :     spdm_context->local_context.capability.data_transfer_size =
     147              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     148            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     149            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     150            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
     151              : 
     152            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     153            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     154            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     155            1 :     spdm_request.header.param1 = 0;
     156            1 :     spdm_request.header.param2 = 0; /* Handle */
     157            1 :     spdm_request.chunk_seq_no = 0;
     158              : 
     159            1 :     response_size = sizeof(response);
     160            1 :     status = libspdm_get_response_chunk_get(
     161              :         spdm_context,
     162              :         sizeof(spdm_request), &spdm_request,
     163              :         &response_size, response);
     164              : 
     165            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     166            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     167              : 
     168            1 :     spdm_response = (spdm_error_response_t*) response;
     169            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     170            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     171            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
     172            1 :     assert_int_equal(spdm_response->header.param2, 0);
     173            1 : }
     174              : 
     175              : /**
     176              :  * Test 4: Responder receives a CHUNK_GET request with bad size.
     177              :  * Expected Behavior: Returns ERROR response message
     178              :  * with SPDM_ERROR_CODE_INVALID_REQUEST error code.
     179              :  **/
     180            1 : static void rsp_chunk_response_case4(void** state)
     181              : {
     182              :     libspdm_return_t status;
     183              :     libspdm_test_context_t* spdm_test_context;
     184              :     libspdm_context_t* spdm_context;
     185              :     size_t response_size;
     186              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     187              :     spdm_error_response_t* spdm_response;
     188              :     spdm_chunk_get_request_t spdm_request;
     189              : 
     190            1 :     spdm_test_context = *state;
     191            1 :     spdm_context = spdm_test_context->spdm_context;
     192            1 :     spdm_test_context->case_id = 4;
     193            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     194              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     195              : 
     196            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
     197            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     198              : 
     199            1 :     spdm_context->local_context.capability.data_transfer_size =
     200              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     201              : 
     202            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     203            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     204              : 
     205            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     206            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     207            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     208            1 :     spdm_request.header.param1 = 0;
     209            1 :     spdm_request.header.param2 = 0;
     210            1 :     spdm_request.chunk_seq_no = 0;
     211              : 
     212            1 :     response_size = sizeof(response);
     213            1 :     status = libspdm_get_response_chunk_get(
     214              :         spdm_context,
     215              :         sizeof(spdm_request) - 1, &spdm_request, /* Bad request size */
     216              :         &response_size, response);
     217              : 
     218            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     219            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     220              : 
     221            1 :     spdm_response = (spdm_error_response_t*) response;
     222            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     223            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     224            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     225            1 :     assert_int_equal(spdm_response->header.param2, 0);
     226            1 : }
     227              : 
     228              : /**
     229              :  * Test 5: Responder receives a CHUNK_GET request with wrong SPDM version.
     230              :  * Expected Behavior: Returns ERROR response message
     231              :  * with SPDM_ERROR_CODE_VERSION_MISMATCH error code.
     232              :  **/
     233            1 : static void rsp_chunk_response_case5(void** state)
     234              : {
     235              :     libspdm_return_t status;
     236              :     libspdm_test_context_t* spdm_test_context;
     237              :     libspdm_context_t* spdm_context;
     238              :     size_t response_size;
     239              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     240              :     spdm_error_response_t* spdm_response;
     241              :     spdm_chunk_get_request_t spdm_request;
     242              : 
     243            1 :     spdm_test_context = *state;
     244            1 :     spdm_context = spdm_test_context->spdm_context;
     245            1 :     spdm_test_context->case_id = 5;
     246            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     247              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     248              : 
     249            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
     250            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     251              : 
     252            1 :     spdm_context->local_context.capability.data_transfer_size =
     253              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     254            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     255            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     256              : 
     257            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     258            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_11; /* Mismatching SPDM version */
     259            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     260            1 :     spdm_request.header.param1 = 0;
     261            1 :     spdm_request.header.param2 = 0;
     262            1 :     spdm_request.chunk_seq_no = 0;
     263              : 
     264            1 :     response_size = sizeof(response);
     265            1 :     status = libspdm_get_response_chunk_get(
     266              :         spdm_context,
     267              :         sizeof(spdm_request), &spdm_request,
     268              :         &response_size, response);
     269              : 
     270            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     271            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     272              : 
     273            1 :     spdm_response = (spdm_error_response_t*) response;
     274            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     275            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     276            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST);
     277            1 :     assert_int_equal(spdm_response->header.param2, SPDM_CHUNK_GET);
     278            1 : }
     279              : 
     280              : /**
     281              :  * Test 6: Responder has no chunk saved to get.
     282              :  **/
     283            1 : static void rsp_chunk_response_case6(void** state)
     284              : {
     285              :     libspdm_return_t status;
     286              :     libspdm_test_context_t* spdm_test_context;
     287              :     libspdm_context_t* spdm_context;
     288              :     size_t response_size;
     289              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     290              :     spdm_error_response_t* spdm_response;
     291              :     spdm_chunk_get_request_t spdm_request;
     292              : 
     293            1 :     spdm_test_context = *state;
     294            1 :     spdm_context = spdm_test_context->spdm_context;
     295            1 :     spdm_test_context->case_id = 6;
     296            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     297              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     298              : 
     299            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
     300            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     301              : 
     302            1 :     spdm_context->local_context.capability.data_transfer_size =
     303              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     304            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     305            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     306              : 
     307              :     /* Set no chunk saved */
     308            1 :     spdm_context->chunk_context.get.chunk_in_use = false;
     309              : 
     310            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     311            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     312            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     313            1 :     spdm_request.header.param1 = 0;
     314            1 :     spdm_request.header.param2 = 0;
     315            1 :     spdm_request.chunk_seq_no = 0;
     316              : 
     317            1 :     response_size = sizeof(response);
     318            1 :     status = libspdm_get_response_chunk_get(
     319              :         spdm_context,
     320              :         sizeof(spdm_request), &spdm_request,
     321              :         &response_size, response);
     322              : 
     323            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     324            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     325              : 
     326            1 :     spdm_response = (spdm_error_response_t*) response;
     327            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     328            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     329            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
     330            1 :     assert_int_equal(spdm_response->header.param2, 0);
     331            1 : }
     332              : 
     333              : /**
     334              :  * Test 7: Responder has handle that does not match request.
     335              :  **/
     336            1 : static void rsp_chunk_response_case7(void** state)
     337              : {
     338              :     libspdm_return_t status;
     339              :     libspdm_test_context_t* spdm_test_context;
     340              :     libspdm_context_t* spdm_context;
     341              :     size_t response_size;
     342              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     343              :     spdm_error_response_t* spdm_response;
     344              :     spdm_chunk_get_request_t spdm_request;
     345              :     void* scratch_buffer;
     346              :     size_t scratch_buffer_size;
     347              : 
     348              :     uint8_t chunk_handle;
     349              : 
     350            1 :     spdm_test_context = *state;
     351            1 :     spdm_context = spdm_test_context->spdm_context;
     352            1 :     spdm_test_context->case_id = 7;
     353            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     354              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     355              : 
     356            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
     357            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     358              : 
     359            1 :     spdm_context->local_context.capability.data_transfer_size =
     360              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     361            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     362            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     363              : 
     364            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     365              : 
     366            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     367            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     368            2 :     scratch_buffer_size = scratch_buffer_size -
     369            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     370            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     371              : 
     372            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id;
     373            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     374            1 :     spdm_context->chunk_context.get.chunk_handle = (uint8_t) spdm_test_context->case_id;
     375            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_handle;
     376            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     377            1 :     spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
     378              : 
     379            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     380            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     381            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     382            1 :     spdm_request.header.param1 = 0;
     383            1 :     spdm_request.header.param2 = chunk_handle - 1; /* Bad chunk handle */
     384            1 :     spdm_request.chunk_seq_no = 0;
     385              : 
     386            1 :     response_size = sizeof(response);
     387            1 :     status = libspdm_get_response_chunk_get(
     388              :         spdm_context,
     389              :         sizeof(spdm_request), &spdm_request,
     390              :         &response_size, response);
     391              : 
     392            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     393            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     394              : 
     395            1 :     spdm_response = (spdm_error_response_t*) response;
     396            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     397            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     398            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     399            1 :     assert_int_equal(spdm_response->header.param2, 0);
     400            1 : }
     401              : 
     402              : /**
     403              :  * Test 8: Responder has earlier sequence number than request .
     404              :  **/
     405            1 : static void rsp_chunk_response_case8(void** state)
     406              : {
     407              :     libspdm_return_t status;
     408              :     libspdm_test_context_t* spdm_test_context;
     409              :     libspdm_context_t* spdm_context;
     410              :     size_t response_size;
     411              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     412              :     spdm_error_response_t* spdm_response;
     413              :     spdm_chunk_get_request_t spdm_request;
     414              :     void* scratch_buffer;
     415              :     size_t scratch_buffer_size;
     416              :     uint8_t chunk_handle;
     417              : 
     418            1 :     spdm_test_context = *state;
     419            1 :     spdm_context = spdm_test_context->spdm_context;
     420            1 :     spdm_test_context->case_id = 8;
     421            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     422              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     423              : 
     424            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     425            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     426              : 
     427            1 :     spdm_context->local_context.capability.data_transfer_size =
     428              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     429            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     430            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     431              : 
     432            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     433              : 
     434            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     435            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     436            2 :     scratch_buffer_size = scratch_buffer_size -
     437            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     438            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     439              : 
     440            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id;
     441            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     442            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     443            1 :     spdm_context->chunk_context.get.chunk_seq_no = 0;
     444            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     445            1 :     spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
     446              : 
     447            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     448            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     449            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     450            1 :     spdm_request.header.param1 = 0;
     451            1 :     spdm_request.header.param2 = chunk_handle;
     452            1 :     spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
     453              : 
     454            1 :     response_size = sizeof(response);
     455            1 :     status = libspdm_get_response_chunk_get(
     456              :         spdm_context,
     457              :         sizeof(spdm_request), &spdm_request,
     458              :         &response_size, response);
     459              : 
     460            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     461            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     462              : 
     463            1 :     spdm_response = (spdm_error_response_t*) response;
     464            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     465            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     466            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     467            1 :     assert_int_equal(spdm_response->header.param2, 0);
     468            1 : }
     469              : 
     470              : /**
     471              :  * Test 9: Responder has later sequence number than request.
     472              :  **/
     473            1 : static void rsp_chunk_response_case9(void** state)
     474              : {
     475              :     libspdm_return_t status;
     476              :     libspdm_test_context_t* spdm_test_context;
     477              :     libspdm_context_t* spdm_context;
     478              :     size_t response_size;
     479              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     480              :     spdm_error_response_t* spdm_response;
     481              :     spdm_chunk_get_request_t spdm_request;
     482              :     void* scratch_buffer;
     483              :     size_t scratch_buffer_size;
     484              :     uint8_t chunk_handle;
     485              : 
     486            1 :     spdm_test_context = *state;
     487            1 :     spdm_context = spdm_test_context->spdm_context;
     488            1 :     spdm_test_context->case_id = 9;
     489            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     490              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     491              : 
     492            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     493            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     494              : 
     495            1 :     spdm_context->local_context.capability.data_transfer_size =
     496              :         CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     497            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     498            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     499              : 
     500            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     501              : 
     502            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     503            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     504            2 :     scratch_buffer_size = scratch_buffer_size -
     505            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     506            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     507              : 
     508            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id;
     509            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     510            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     511            1 :     spdm_context->chunk_context.get.chunk_seq_no = 0;
     512            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     513            1 :     spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
     514            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
     515              : 
     516            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     517            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     518            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     519            1 :     spdm_request.header.param1 = 0;
     520            1 :     spdm_request.header.param2 = chunk_handle;
     521            1 :     spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
     522              : 
     523            1 :     response_size = sizeof(response);
     524            1 :     status = libspdm_get_response_chunk_get(
     525              :         spdm_context,
     526              :         sizeof(spdm_request), &spdm_request,
     527              :         &response_size, response);
     528              : 
     529            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     530            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     531              : 
     532            1 :     spdm_response = (spdm_error_response_t*) response;
     533            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     534            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     535            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     536            1 :     assert_int_equal(spdm_response->header.param2, 0);
     537            1 : }
     538              : 
     539              : /**
     540              :  * Test 10: Successful request of first chunk.
     541              :  **/
     542            1 : static void rsp_chunk_response_case10(void** state)
     543              : {
     544              :     libspdm_return_t status;
     545              :     libspdm_test_context_t* spdm_test_context;
     546              :     libspdm_context_t* spdm_context;
     547              :     size_t response_size;
     548              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     549              :     spdm_chunk_response_response_t* spdm_response;
     550              :     spdm_chunk_get_request_t spdm_request;
     551              :     void* scratch_buffer;
     552              :     size_t scratch_buffer_size;
     553              : 
     554              :     uint8_t chunk_handle;
     555              :     uint32_t data_transfer_size;
     556              :     uint32_t first_chunk_size;
     557              :     uint32_t second_chunk_size;
     558              :     uint32_t third_chunk_size;
     559              :     uint32_t total_chunk_size;
     560              :     uint32_t large_response;
     561              :     uint8_t* chunk_ptr;
     562              :     uint32_t i;
     563              : 
     564            1 :     spdm_test_context = *state;
     565            1 :     spdm_context = spdm_test_context->spdm_context;
     566            1 :     spdm_test_context->case_id = 10;
     567            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     568              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     569              : 
     570            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     571            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     572              : 
     573            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     574            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
     575            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     576            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     577              : 
     578            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     579              : 
     580            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     581            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     582            2 :     scratch_buffer_size = scratch_buffer_size -
     583            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     584            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     585              : 
     586              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
     587            1 :     first_chunk_size = data_transfer_size -
     588              :                        (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
     589            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     590            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     591            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
     592            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
     593              : 
     594            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
     595            1 :     libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
     596            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
     597              :                     third_chunk_size, 3);
     598              : 
     599            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
     600            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     601            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     602            1 :     spdm_context->chunk_context.get.chunk_seq_no = 0;
     603            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     604            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
     605            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
     606              : 
     607            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     608            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     609            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     610            1 :     spdm_request.header.param1 = 0;
     611            1 :     spdm_request.header.param2 = chunk_handle;
     612            1 :     spdm_request.chunk_seq_no = 0;
     613              : 
     614            1 :     response_size = sizeof(response);
     615            1 :     status = libspdm_get_response_chunk_get(
     616              :         spdm_context,
     617              :         sizeof(spdm_request), &spdm_request,
     618              :         &response_size, response);
     619              : 
     620            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     621            1 :     assert_int_equal(response_size, data_transfer_size);
     622              : 
     623            1 :     spdm_response = (spdm_chunk_response_response_t*) response;
     624            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     625            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
     626            1 :     assert_int_equal(spdm_response->header.param1, 0);
     627            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
     628            1 :     assert_int_equal(spdm_response->chunk_seq_no, 0);
     629            1 :     assert_int_equal(spdm_response->chunk_size, first_chunk_size);
     630              : 
     631            1 :     large_response = *(uint32_t*) (spdm_response + 1);
     632            1 :     assert_int_equal(large_response, total_chunk_size);
     633              : 
     634              :     /* Verify the 1st chunk is filled with 1 */
     635            1 :     chunk_ptr = (uint8_t*)(((uint32_t*) (spdm_response + 1)) + 1);
     636           29 :     for (i = 0; i < spdm_response->chunk_size; i++) {
     637           28 :         assert_int_equal(chunk_ptr[i], 1);
     638              :     }
     639            1 : }
     640              : 
     641              : /**
     642              :  * Test 11: Successful request of middle chunk.
     643              :  **/
     644            1 : static void rsp_chunk_response_case11(void** state)
     645              : {
     646              :     libspdm_return_t status;
     647              :     libspdm_test_context_t* spdm_test_context;
     648              :     libspdm_context_t* spdm_context;
     649              :     size_t response_size;
     650              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     651              :     spdm_chunk_response_response_t* spdm_response;
     652              :     spdm_chunk_get_request_t spdm_request;
     653              :     void* scratch_buffer;
     654              :     size_t scratch_buffer_size;
     655              : 
     656              :     uint8_t chunk_handle;
     657              :     uint16_t chunk_seq_no;
     658              :     uint32_t data_transfer_size;
     659              :     uint32_t first_chunk_size;
     660              :     uint32_t second_chunk_size;
     661              :     uint32_t third_chunk_size;
     662              :     uint32_t total_chunk_size;
     663              :     uint8_t* chunk_ptr;
     664              :     uint32_t i;
     665              : 
     666            1 :     spdm_test_context = *state;
     667            1 :     spdm_context = spdm_test_context->spdm_context;
     668            1 :     spdm_test_context->case_id = 11;
     669            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     670              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     671              : 
     672            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     673            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     674              : 
     675            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     676            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
     677            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     678            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     679              : 
     680            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     681              : 
     682            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     683            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     684            2 :     scratch_buffer_size = scratch_buffer_size -
     685            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     686            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     687              : 
     688              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
     689            1 :     first_chunk_size = data_transfer_size -
     690              :                        (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
     691            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     692            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     693            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
     694            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
     695              : 
     696            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
     697            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
     698            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
     699              :                     third_chunk_size, 3);
     700              : 
     701            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
     702            1 :     chunk_seq_no = 1; /* 1 == 2nd chunk */
     703            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     704            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     705            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
     706            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     707            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
     708            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
     709              : 
     710            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     711            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     712            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     713            1 :     spdm_request.header.param1 = 0;
     714            1 :     spdm_request.header.param2 = chunk_handle;
     715            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
     716              : 
     717            1 :     response_size = sizeof(response);
     718            1 :     status = libspdm_get_response_chunk_get(
     719              :         spdm_context,
     720              :         sizeof(spdm_request), &spdm_request,
     721              :         &response_size, response);
     722              : 
     723            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     724            1 :     assert_int_equal(response_size, data_transfer_size);
     725              : 
     726            1 :     spdm_response = (spdm_chunk_response_response_t*) response;
     727            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     728            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
     729            1 :     assert_int_equal(spdm_response->header.param1, 0);
     730            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
     731            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
     732            1 :     assert_int_equal(spdm_response->chunk_size, second_chunk_size);
     733              : 
     734              :     /* Verify the 2nd chunk is filled with 2 */
     735            1 :     chunk_ptr = (uint8_t*) (spdm_response + 1);
     736           33 :     for (i = 0; i < spdm_response->chunk_size; i++) {
     737           32 :         assert_int_equal(chunk_ptr[i], 2);
     738              :     }
     739            1 : }
     740              : 
     741              : /**
     742              :  * Test 12: Successful request of last chunk where size is exactly max chunk size
     743              :  **/
     744            1 : static void rsp_chunk_response_case12(void** state)
     745              : {
     746              :     libspdm_return_t status;
     747              :     libspdm_test_context_t* spdm_test_context;
     748              :     libspdm_context_t* spdm_context;
     749              :     size_t response_size;
     750              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     751              :     spdm_chunk_response_response_t* spdm_response;
     752              :     spdm_chunk_get_request_t spdm_request;
     753              :     void* scratch_buffer;
     754              :     size_t scratch_buffer_size;
     755              : 
     756              :     uint8_t chunk_handle;
     757              :     uint16_t chunk_seq_no;
     758              :     uint32_t data_transfer_size;
     759              :     uint32_t first_chunk_size;
     760              :     uint32_t second_chunk_size;
     761              :     uint32_t third_chunk_size;
     762              :     uint32_t total_chunk_size;
     763              :     uint8_t* chunk_ptr;
     764              :     uint32_t i;
     765              : 
     766            1 :     spdm_test_context = *state;
     767            1 :     spdm_context = spdm_test_context->spdm_context;
     768            1 :     spdm_test_context->case_id = 12;
     769            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     770              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     771              : 
     772            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     773            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     774              : 
     775            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     776            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
     777            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     778            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     779              : 
     780            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     781              : 
     782            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     783            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     784            2 :     scratch_buffer_size = scratch_buffer_size -
     785            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     786            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     787              : 
     788              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
     789            1 :     first_chunk_size = data_transfer_size -
     790              :                        (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
     791            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     792            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     793            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
     794            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
     795              : 
     796            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
     797            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
     798            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
     799              :                     third_chunk_size, 3);
     800              : 
     801            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
     802            1 :     chunk_seq_no = 2; /* 2 == 3rd chunk */
     803            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     804            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     805            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
     806            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     807            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
     808            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
     809              : 
     810            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     811            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     812            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     813            1 :     spdm_request.header.param1 = 0;
     814            1 :     spdm_request.header.param2 = chunk_handle;
     815            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
     816              : 
     817            1 :     response_size = sizeof(response);
     818            1 :     status = libspdm_get_response_chunk_get(
     819              :         spdm_context,
     820              :         sizeof(spdm_request), &spdm_request,
     821              :         &response_size, response);
     822              : 
     823            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     824            1 :     assert_int_equal(response_size, data_transfer_size);
     825              : 
     826            1 :     spdm_response = (spdm_chunk_response_response_t*) response;
     827            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     828            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
     829            1 :     assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
     830            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
     831            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
     832            1 :     assert_int_equal(spdm_response->chunk_size, third_chunk_size);
     833              : 
     834              :     /* Verify the 3rd chunk is filled with 3 */
     835            1 :     chunk_ptr = (uint8_t*) (spdm_response + 1);
     836           33 :     for (i = 0; i < spdm_response->chunk_size; i++) {
     837           32 :         assert_int_equal(chunk_ptr[i], 3);
     838              :     }
     839            1 : }
     840              : 
     841              : /**
     842              :  * Test 13: Successful request of last chunk where size is exactly 1.
     843              :  **/
     844            1 : static void rsp_chunk_response_case13(void** state)
     845              : {
     846              :     libspdm_return_t status;
     847              :     libspdm_test_context_t* spdm_test_context;
     848              :     libspdm_context_t* spdm_context;
     849              :     size_t response_size;
     850              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     851              :     spdm_chunk_response_response_t* spdm_response;
     852              :     spdm_chunk_get_request_t spdm_request;
     853              :     void* scratch_buffer;
     854              :     size_t scratch_buffer_size;
     855              : 
     856              :     uint8_t chunk_handle;
     857              :     uint16_t chunk_seq_no;
     858              :     uint32_t data_transfer_size;
     859              :     uint32_t first_chunk_size;
     860              :     uint32_t second_chunk_size;
     861              :     uint32_t third_chunk_size;
     862              :     uint32_t total_chunk_size;
     863              :     uint32_t fourth_chunk_size;
     864              :     uint32_t expected_response_size;
     865              :     uint8_t* chunk_ptr;
     866              :     uint32_t i;
     867              : 
     868            1 :     spdm_test_context = *state;
     869            1 :     spdm_context = spdm_test_context->spdm_context;
     870            1 :     spdm_test_context->case_id = 12;
     871            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     872              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     873              : 
     874            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     875            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     876              : 
     877            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     878            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
     879            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     880            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     881              : 
     882            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     883              : 
     884            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     885            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     886            2 :     scratch_buffer_size = scratch_buffer_size -
     887            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     888            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
     889              : 
     890              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
     891            1 :     first_chunk_size = data_transfer_size -
     892              :                        (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
     893            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     894            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
     895            1 :     fourth_chunk_size = 1;
     896              : 
     897            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
     898            1 :     expected_response_size = sizeof(spdm_chunk_response_response_t) + fourth_chunk_size;
     899            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
     900              : 
     901            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
     902            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
     903            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
     904              :                     third_chunk_size, 3);
     905            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
     906            1 :                     + second_chunk_size + third_chunk_size,
     907              :                     fourth_chunk_size, 4);
     908              : 
     909            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
     910            1 :     chunk_seq_no = 3; /* 3 == 4th chunk */
     911            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
     912            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
     913            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
     914            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
     915            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
     916            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred =
     917            1 :         first_chunk_size + second_chunk_size + third_chunk_size;
     918              : 
     919            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
     920            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
     921            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
     922            1 :     spdm_request.header.param1 = 0;
     923            1 :     spdm_request.header.param2 = chunk_handle;
     924            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
     925              : 
     926            1 :     response_size = sizeof(response);
     927            1 :     status = libspdm_get_response_chunk_get(
     928              :         spdm_context,
     929              :         sizeof(spdm_request), &spdm_request,
     930              :         &response_size, response);
     931              : 
     932            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     933            1 :     assert_int_equal(response_size, expected_response_size);
     934              : 
     935            1 :     spdm_response = (spdm_chunk_response_response_t*) response;
     936            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
     937            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
     938            1 :     assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
     939            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
     940            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
     941            1 :     assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
     942              : 
     943              :     /* Verify the 4th chunk is filled with 4 */
     944            1 :     chunk_ptr = (uint8_t*)(spdm_response + 1);
     945            2 :     for (i = 0; i < spdm_response->chunk_size; i++) {
     946            1 :         assert_int_equal(chunk_ptr[i], 4);
     947              :     }
     948            1 : }
     949              : 
     950              : 
     951              : /**
     952              :  * Test 14: Responder has response exceed chunk seq no
     953              :  **/
     954            1 : static void rsp_chunk_response_case14(void** state)
     955              : {
     956              :     libspdm_return_t status;
     957              :     libspdm_test_context_t* spdm_test_context;
     958              :     libspdm_context_t* spdm_context;
     959              :     size_t response_size;
     960              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     961              :     spdm_error_response_t* spdm_response;
     962              :     spdm_chunk_get_request_t spdm_request;
     963              :     void* scratch_buffer;
     964              :     size_t scratch_buffer_size;
     965              : 
     966              :     uint8_t chunk_handle;
     967              :     uint32_t data_transfer_size;
     968              :     uint32_t total_chunk_size;
     969              : 
     970            1 :     spdm_test_context = *state;
     971            1 :     spdm_context = spdm_test_context->spdm_context;
     972            1 :     spdm_test_context->case_id = 10;
     973            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     974              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     975              : 
     976            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     977            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     978              : 
     979            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
     980            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
     981            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
     982            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
     983              : 
     984              :     /* large response need a large scratch buffer */
     985            1 :     spdm_context->connection_info.capability.max_spdm_msg_size = data_transfer_size * 65536;
     986            1 :     spdm_context->local_context.capability.max_spdm_msg_size = data_transfer_size * 65536;
     987            1 :     spdm_test_context->scratch_buffer_size =
     988            1 :         libspdm_get_sizeof_required_scratch_buffer(spdm_context);
     989            1 :     spdm_test_context->scratch_buffer = (void *)malloc(spdm_test_context->scratch_buffer_size);
     990            1 :     libspdm_set_scratch_buffer (spdm_context,
     991              :                                 spdm_test_context->scratch_buffer,
     992              :                                 spdm_test_context->scratch_buffer_size);
     993              : 
     994              : 
     995            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
     996              : 
     997            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
     998            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     999            2 :     scratch_buffer_size = scratch_buffer_size -
    1000            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1001            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
    1002              : 
    1003              :     /* a huge chunk size to cause the chunk seq no wrap */
    1004            1 :     total_chunk_size = data_transfer_size * 65536;
    1005              : 
    1006            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
    1007              : 
    1008            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
    1009            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
    1010            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
    1011            1 :     spdm_context->chunk_context.get.chunk_seq_no = 0;
    1012            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
    1013            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
    1014            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
    1015              : 
    1016            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
    1017            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
    1018            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
    1019            1 :     spdm_request.header.param1 = 0;
    1020            1 :     spdm_request.header.param2 = chunk_handle;
    1021            1 :     spdm_request.chunk_seq_no = 0;
    1022              : 
    1023            1 :     response_size = sizeof(response);
    1024            1 :     status = libspdm_get_response_chunk_get(
    1025              :         spdm_context,
    1026              :         sizeof(spdm_request), &spdm_request,
    1027              :         &response_size, response);
    1028              : 
    1029            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1030            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
    1031              : 
    1032            1 :     spdm_response = (spdm_error_response_t*) response;
    1033              : 
    1034            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
    1035            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
    1036            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_TOO_LARGE);
    1037            1 :     assert_int_equal(spdm_response->header.param2, 0);
    1038            1 : }
    1039              : 
    1040              : /**
    1041              :  * Test 15: Successful request of first chunk, spdm 1.4.
    1042              :  **/
    1043            1 : static void rsp_chunk_response_case15(void** state)
    1044              : {
    1045              :     libspdm_return_t status;
    1046              :     libspdm_test_context_t* spdm_test_context;
    1047              :     libspdm_context_t* spdm_context;
    1048              :     size_t response_size;
    1049              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1050              :     spdm_chunk_response_response_14_t* spdm_response;
    1051              :     spdm_chunk_get_request_14_t spdm_request;
    1052              :     void* scratch_buffer;
    1053              :     size_t scratch_buffer_size;
    1054              : 
    1055              :     uint8_t chunk_handle;
    1056              :     uint32_t data_transfer_size;
    1057              :     uint32_t first_chunk_size;
    1058              :     uint32_t second_chunk_size;
    1059              :     uint32_t third_chunk_size;
    1060              :     uint32_t total_chunk_size;
    1061              :     uint32_t large_response;
    1062              :     uint8_t* chunk_ptr;
    1063              :     uint32_t i;
    1064              : 
    1065            1 :     spdm_test_context = *state;
    1066            1 :     spdm_context = spdm_test_context->spdm_context;
    1067            1 :     spdm_test_context->case_id = 15;
    1068            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
    1069              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1070              : 
    1071            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1072            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1073              : 
    1074            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
    1075            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
    1076            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
    1077            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1078              : 
    1079            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
    1080              : 
    1081            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
    1082            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1083            2 :     scratch_buffer_size = scratch_buffer_size -
    1084            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1085            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
    1086              : 
    1087              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
    1088            1 :     first_chunk_size = data_transfer_size -
    1089              :                        (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
    1090            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1091            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1092            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
    1093            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
    1094              : 
    1095            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
    1096            1 :     libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
    1097            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
    1098              :                     third_chunk_size, 3);
    1099              : 
    1100            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
    1101            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
    1102            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
    1103            1 :     spdm_context->chunk_context.get.chunk_seq_no = 0;
    1104            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
    1105            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
    1106            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
    1107              : 
    1108            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
    1109            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
    1110            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
    1111            1 :     spdm_request.header.param1 = 0;
    1112            1 :     spdm_request.header.param2 = chunk_handle;
    1113            1 :     spdm_request.chunk_seq_no = 0;
    1114              : 
    1115            1 :     response_size = sizeof(response);
    1116            1 :     status = libspdm_get_response_chunk_get(
    1117              :         spdm_context,
    1118              :         sizeof(spdm_request), &spdm_request,
    1119              :         &response_size, response);
    1120              : 
    1121            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1122            1 :     assert_int_equal(response_size, data_transfer_size);
    1123              : 
    1124            1 :     spdm_response = (spdm_chunk_response_response_14_t*) response;
    1125            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
    1126            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
    1127            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1128            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
    1129            1 :     assert_int_equal(spdm_response->chunk_seq_no, 0);
    1130            1 :     assert_int_equal(spdm_response->chunk_size, first_chunk_size);
    1131              : 
    1132            1 :     large_response = *(uint32_t*) (spdm_response + 1);
    1133            1 :     assert_int_equal(large_response, total_chunk_size);
    1134              : 
    1135              :     /* Verify the 1st chunk is filled with 1 */
    1136            1 :     chunk_ptr = (uint8_t*)(((uint32_t*) (spdm_response + 1)) + 1);
    1137           29 :     for (i = 0; i < spdm_response->chunk_size; i++) {
    1138           28 :         assert_int_equal(chunk_ptr[i], 1);
    1139              :     }
    1140            1 : }
    1141              : 
    1142              : /**
    1143              :  * Test 16: Successful request of middle chunk, spdm 1.4.
    1144              :  **/
    1145            1 : static void rsp_chunk_response_case16(void** state)
    1146              : {
    1147              :     libspdm_return_t status;
    1148              :     libspdm_test_context_t* spdm_test_context;
    1149              :     libspdm_context_t* spdm_context;
    1150              :     size_t response_size;
    1151              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1152              :     spdm_chunk_response_response_14_t* spdm_response;
    1153              :     spdm_chunk_get_request_14_t spdm_request;
    1154              :     void* scratch_buffer;
    1155              :     size_t scratch_buffer_size;
    1156              : 
    1157              :     uint8_t chunk_handle;
    1158              :     uint32_t chunk_seq_no;
    1159              :     uint32_t data_transfer_size;
    1160              :     uint32_t first_chunk_size;
    1161              :     uint32_t second_chunk_size;
    1162              :     uint32_t third_chunk_size;
    1163              :     uint32_t total_chunk_size;
    1164              :     uint8_t* chunk_ptr;
    1165              :     uint32_t i;
    1166              : 
    1167            1 :     spdm_test_context = *state;
    1168            1 :     spdm_context = spdm_test_context->spdm_context;
    1169            1 :     spdm_test_context->case_id = 16;
    1170            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
    1171              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1172              : 
    1173            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1174            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1175              : 
    1176            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
    1177            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
    1178            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
    1179            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1180              : 
    1181            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
    1182              : 
    1183            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
    1184            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1185            2 :     scratch_buffer_size = scratch_buffer_size -
    1186            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1187            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
    1188              : 
    1189              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
    1190            1 :     first_chunk_size = data_transfer_size -
    1191              :                        (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
    1192            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1193            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1194            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
    1195            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
    1196              : 
    1197            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
    1198            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
    1199            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
    1200              :                     third_chunk_size, 3);
    1201              : 
    1202            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
    1203            1 :     chunk_seq_no = 1; /* 1 == 2nd chunk */
    1204            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
    1205            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
    1206            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
    1207            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
    1208            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
    1209            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
    1210              : 
    1211            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
    1212            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
    1213            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
    1214            1 :     spdm_request.header.param1 = 0;
    1215            1 :     spdm_request.header.param2 = chunk_handle;
    1216            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
    1217              : 
    1218            1 :     response_size = sizeof(response);
    1219            1 :     status = libspdm_get_response_chunk_get(
    1220              :         spdm_context,
    1221              :         sizeof(spdm_request), &spdm_request,
    1222              :         &response_size, response);
    1223              : 
    1224            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1225            1 :     assert_int_equal(response_size, data_transfer_size);
    1226              : 
    1227            1 :     spdm_response = (spdm_chunk_response_response_14_t*) response;
    1228            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
    1229            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
    1230            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1231            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
    1232            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
    1233            1 :     assert_int_equal(spdm_response->chunk_size, second_chunk_size);
    1234              : 
    1235              :     /* Verify the 2nd chunk is filled with 2 */
    1236            1 :     chunk_ptr = (uint8_t*) (spdm_response + 1);
    1237           33 :     for (i = 0; i < spdm_response->chunk_size; i++) {
    1238           32 :         assert_int_equal(chunk_ptr[i], 2);
    1239              :     }
    1240            1 : }
    1241              : 
    1242              : /**
    1243              :  * Test 17: Successful request of last chunk where size is exactly max chunk size
    1244              :  **/
    1245            1 : static void rsp_chunk_response_case17(void** state)
    1246              : {
    1247              :     libspdm_return_t status;
    1248              :     libspdm_test_context_t* spdm_test_context;
    1249              :     libspdm_context_t* spdm_context;
    1250              :     size_t response_size;
    1251              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1252              :     spdm_chunk_response_response_14_t* spdm_response;
    1253              :     spdm_chunk_get_request_14_t spdm_request;
    1254              :     void* scratch_buffer;
    1255              :     size_t scratch_buffer_size;
    1256              : 
    1257              :     uint8_t chunk_handle;
    1258              :     uint32_t chunk_seq_no;
    1259              :     uint32_t data_transfer_size;
    1260              :     uint32_t first_chunk_size;
    1261              :     uint32_t second_chunk_size;
    1262              :     uint32_t third_chunk_size;
    1263              :     uint32_t total_chunk_size;
    1264              :     uint8_t* chunk_ptr;
    1265              :     uint32_t i;
    1266              : 
    1267            1 :     spdm_test_context = *state;
    1268            1 :     spdm_context = spdm_test_context->spdm_context;
    1269            1 :     spdm_test_context->case_id = 17;
    1270            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
    1271              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1272              : 
    1273            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1274            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1275              : 
    1276            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
    1277            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
    1278            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
    1279            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1280              : 
    1281            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
    1282              : 
    1283            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
    1284            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1285            2 :     scratch_buffer_size = scratch_buffer_size -
    1286            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1287            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
    1288              : 
    1289              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
    1290            1 :     first_chunk_size = data_transfer_size -
    1291              :                        (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
    1292            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1293            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1294            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
    1295            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
    1296              : 
    1297            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
    1298            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
    1299            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
    1300              :                     third_chunk_size, 3);
    1301              : 
    1302            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
    1303            1 :     chunk_seq_no = 2; /* 2 == 3rd chunk */
    1304            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
    1305            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
    1306            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
    1307            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
    1308            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
    1309            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
    1310              : 
    1311            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
    1312            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
    1313            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
    1314            1 :     spdm_request.header.param1 = 0;
    1315            1 :     spdm_request.header.param2 = chunk_handle;
    1316            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
    1317              : 
    1318            1 :     response_size = sizeof(response);
    1319            1 :     status = libspdm_get_response_chunk_get(
    1320              :         spdm_context,
    1321              :         sizeof(spdm_request), &spdm_request,
    1322              :         &response_size, response);
    1323              : 
    1324            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1325            1 :     assert_int_equal(response_size, data_transfer_size);
    1326              : 
    1327            1 :     spdm_response = (spdm_chunk_response_response_14_t*) response;
    1328            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
    1329            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
    1330            1 :     assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
    1331            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
    1332            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
    1333            1 :     assert_int_equal(spdm_response->chunk_size, third_chunk_size);
    1334              : 
    1335              :     /* Verify the 3rd chunk is filled with 3 */
    1336            1 :     chunk_ptr = (uint8_t*) (spdm_response + 1);
    1337           33 :     for (i = 0; i < spdm_response->chunk_size; i++) {
    1338           32 :         assert_int_equal(chunk_ptr[i], 3);
    1339              :     }
    1340            1 : }
    1341              : 
    1342              : /**
    1343              :  * Test 18: Successful request of last chunk where size is exactly 1.
    1344              :  **/
    1345            1 : static void rsp_chunk_response_case18(void** state)
    1346              : {
    1347              :     libspdm_return_t status;
    1348              :     libspdm_test_context_t* spdm_test_context;
    1349              :     libspdm_context_t* spdm_context;
    1350              :     size_t response_size;
    1351              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1352              :     spdm_chunk_response_response_14_t* spdm_response;
    1353              :     spdm_chunk_get_request_14_t spdm_request;
    1354              :     void* scratch_buffer;
    1355              :     size_t scratch_buffer_size;
    1356              : 
    1357              :     uint8_t chunk_handle;
    1358              :     uint16_t chunk_seq_no;
    1359              :     uint32_t data_transfer_size;
    1360              :     uint32_t first_chunk_size;
    1361              :     uint32_t second_chunk_size;
    1362              :     uint32_t third_chunk_size;
    1363              :     uint32_t total_chunk_size;
    1364              :     uint32_t fourth_chunk_size;
    1365              :     uint32_t expected_response_size;
    1366              :     uint8_t* chunk_ptr;
    1367              :     uint32_t i;
    1368              : 
    1369            1 :     spdm_test_context = *state;
    1370            1 :     spdm_context = spdm_test_context->spdm_context;
    1371            1 :     spdm_test_context->case_id = 18;
    1372            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
    1373              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1374              : 
    1375            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1376            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1377              : 
    1378            1 :     data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
    1379            1 :     spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
    1380            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
    1381            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1382              : 
    1383            1 :     libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
    1384              : 
    1385            2 :     scratch_buffer = (uint8_t*)scratch_buffer +
    1386            1 :                      libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1387            2 :     scratch_buffer_size = scratch_buffer_size -
    1388            1 :                           libspdm_get_scratch_buffer_large_message_offset(spdm_context);
    1389            1 :     libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
    1390              : 
    1391              :     /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
    1392            1 :     first_chunk_size = data_transfer_size -
    1393              :                        (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
    1394            1 :     second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1395            1 :     third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
    1396            1 :     fourth_chunk_size = 1;
    1397              : 
    1398            1 :     total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
    1399            1 :     expected_response_size = sizeof(spdm_chunk_response_response_14_t) + fourth_chunk_size;
    1400            1 :     LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
    1401              : 
    1402            1 :     libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
    1403            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
    1404            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
    1405              :                     third_chunk_size, 3);
    1406            1 :     libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
    1407            1 :                     + second_chunk_size + third_chunk_size,
    1408              :                     fourth_chunk_size, 4);
    1409              : 
    1410            1 :     chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
    1411            1 :     chunk_seq_no = 3; /* 3 == 4th chunk */
    1412            1 :     spdm_context->chunk_context.get.chunk_in_use = true;
    1413            1 :     spdm_context->chunk_context.get.chunk_handle = chunk_handle;
    1414            1 :     spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
    1415            1 :     spdm_context->chunk_context.get.large_message = scratch_buffer;
    1416            1 :     spdm_context->chunk_context.get.large_message_size = total_chunk_size;
    1417            1 :     spdm_context->chunk_context.get.chunk_bytes_transferred =
    1418            1 :         first_chunk_size + second_chunk_size + third_chunk_size;
    1419              : 
    1420            1 :     libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
    1421            1 :     spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
    1422            1 :     spdm_request.header.request_response_code = SPDM_CHUNK_GET;
    1423            1 :     spdm_request.header.param1 = 0;
    1424            1 :     spdm_request.header.param2 = chunk_handle;
    1425            1 :     spdm_request.chunk_seq_no = chunk_seq_no;
    1426              : 
    1427            1 :     response_size = sizeof(response);
    1428            1 :     status = libspdm_get_response_chunk_get(
    1429              :         spdm_context,
    1430              :         sizeof(spdm_request), &spdm_request,
    1431              :         &response_size, response);
    1432              : 
    1433            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1434            1 :     assert_int_equal(response_size, expected_response_size);
    1435              : 
    1436            1 :     spdm_response = (spdm_chunk_response_response_14_t*) response;
    1437            1 :     assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
    1438            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
    1439            1 :     assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
    1440            1 :     assert_int_equal(spdm_response->header.param2, chunk_handle);
    1441            1 :     assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
    1442            1 :     assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
    1443              : 
    1444              :     /* Verify the 4th chunk is filled with 4 */
    1445            1 :     chunk_ptr = (uint8_t*)(spdm_response + 1);
    1446            2 :     for (i = 0; i < spdm_response->chunk_size; i++) {
    1447            1 :         assert_int_equal(chunk_ptr[i], 4);
    1448              :     }
    1449            1 : }
    1450              : 
    1451              : 
    1452            1 : int libspdm_rsp_chunk_response_test(void)
    1453              : {
    1454            1 :     const struct CMUnitTest test_cases[] = {
    1455              :         /* Responder has no response flag chunk cap */
    1456              :         cmocka_unit_test(rsp_chunk_response_case1),
    1457              :         /* Responder has response state != NORMAL */
    1458              :         cmocka_unit_test(rsp_chunk_response_case2),
    1459              :         /* Responder has connection state <= NOT_START */
    1460              :         cmocka_unit_test(rsp_chunk_response_case3),
    1461              :         /* Request has wrong size */
    1462              :         cmocka_unit_test(rsp_chunk_response_case4),
    1463              :         /* Request has wrong SPDM version */
    1464              :         cmocka_unit_test(rsp_chunk_response_case5),
    1465              :         /* Responder has no chunk saved to get */
    1466              :         cmocka_unit_test(rsp_chunk_response_case6),
    1467              :         /* Responder has handle that does not match request */
    1468              :         cmocka_unit_test(rsp_chunk_response_case7),
    1469              :         /* Responder has earlier sequence number than request */
    1470              :         cmocka_unit_test(rsp_chunk_response_case8),
    1471              :         /* Responder has later sequence number than request*/
    1472              :         cmocka_unit_test(rsp_chunk_response_case9),
    1473              :         /* Successful request of first chunk */
    1474              :         cmocka_unit_test(rsp_chunk_response_case10),
    1475              :         /* Successful request of middle chunk */
    1476              :         cmocka_unit_test(rsp_chunk_response_case11),
    1477              :         /* Successful request of last chunk, where size is exactly max chunk size */
    1478              :         cmocka_unit_test(rsp_chunk_response_case12),
    1479              :         /* Successful request of last chunk where chunk size is exactly 1 byte */
    1480              :         cmocka_unit_test(rsp_chunk_response_case13),
    1481              :         /* Responder has response exceed chunk seq no */
    1482              :         cmocka_unit_test(rsp_chunk_response_case14),
    1483              :         /* Successful request of first chunk, spdm 1.4*/
    1484              :         cmocka_unit_test(rsp_chunk_response_case15),
    1485              :         /* Successful request of middle chunk, spdm 1.4 */
    1486              :         cmocka_unit_test(rsp_chunk_response_case16),
    1487              :         /* Successful request of last chunk, where size is exactly max chunk size, spdm 1.4 */
    1488              :         cmocka_unit_test(rsp_chunk_response_case17),
    1489              :         /* Successful request of last chunk where chunk size is exactly 1 byte, spdm 1.4 */
    1490              :         cmocka_unit_test(rsp_chunk_response_case18),
    1491              :     };
    1492              : 
    1493            1 :     libspdm_test_context_t test_context = {
    1494              :         LIBSPDM_TEST_CONTEXT_VERSION,
    1495              :         false,
    1496              :     };
    1497              : 
    1498            1 :     libspdm_setup_test_context(&test_context);
    1499              : 
    1500            1 :     return cmocka_run_group_tests(test_cases,
    1501              :                                   libspdm_unit_test_group_setup,
    1502              :                                   libspdm_unit_test_group_teardown);
    1503              : }
    1504              : 
    1505              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
        

Generated by: LCOV version 2.0-1