LCOV - code coverage report
Current view: top level - unit_test/test_spdm_responder - certificate.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.3 % 522 513
Test Date: 2025-12-21 08:10:27 Functions: 100.0 % 20 20

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 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_CERT_CAP
      11              : 
      12              : /* #define TEST_LIBSPDM_DEBUG*/
      13              : #ifdef TEST_LIBSPDM_DEBUG
      14              : #define TEST_LIBSPDM_DEBUG_PRINT(format, ...) printf(format, ## __VA_ARGS__)
      15              : #else
      16              : #define TEST_LIBSPDM_DEBUG_PRINT(...)
      17              : #endif
      18              : 
      19              : spdm_get_certificate_request_t m_libspdm_get_certificate_request1 = {
      20              :     { SPDM_MESSAGE_VERSION_10, SPDM_GET_CERTIFICATE, 0, 0 },
      21              :     0,
      22              :     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
      23              : };
      24              : size_t m_libspdm_get_certificate_request1_size = sizeof(m_libspdm_get_certificate_request1);
      25              : 
      26              : spdm_get_certificate_request_t m_libspdm_get_certificate_request3 = {
      27              :     { SPDM_MESSAGE_VERSION_10, SPDM_GET_CERTIFICATE, 0, 0 },
      28              :     0,
      29              :     0
      30              : };
      31              : size_t m_libspdm_get_certificate_request3_size = sizeof(m_libspdm_get_certificate_request3);
      32              : 
      33              : spdm_get_certificate_request_t m_libspdm_get_certificate_request4 = {
      34              :     { SPDM_MESSAGE_VERSION_10, SPDM_GET_CERTIFICATE, 9, 0 },
      35              :     0,
      36              :     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
      37              : };
      38              : size_t m_libspdm_get_certificate_request4_size = sizeof(m_libspdm_get_certificate_request4);
      39              : 
      40              : spdm_get_certificate_request_t m_libspdm_get_certificate_request5 = {
      41              :     { SPDM_MESSAGE_VERSION_13, SPDM_GET_CERTIFICATE, 0, 0 },
      42              :     0,
      43              :     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
      44              : };
      45              : size_t m_libspdm_get_certificate_request5_size = sizeof(m_libspdm_get_certificate_request5);
      46              : /**
      47              :  * Test 1: request the first LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of the certificate chain
      48              :  * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
      49              :  **/
      50            1 : static void rsp_certificate_case1(void **state)
      51              : {
      52              :     libspdm_return_t status;
      53              :     libspdm_test_context_t *spdm_test_context;
      54              :     libspdm_context_t *spdm_context;
      55              :     size_t response_size;
      56              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
      57              :     spdm_certificate_response_t *spdm_response;
      58              :     void *data;
      59              :     size_t data_size;
      60              : 
      61            1 :     spdm_test_context = *state;
      62            1 :     spdm_context = spdm_test_context->spdm_context;
      63            1 :     spdm_test_context->case_id = 0x1;
      64            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
      65              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
      66            1 :     spdm_context->connection_info.connection_state =
      67              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
      68            1 :     spdm_context->local_context.capability.flags |=
      69              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
      70            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
      71              :         m_libspdm_use_hash_algo;
      72            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
      73              :                                                     m_libspdm_use_asym_algo, &data,
      74              :                                                     &data_size, NULL, NULL);
      75            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
      76            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
      77              :         data_size;
      78              : 
      79              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      80              :     spdm_context->transcript.message_m.buffer_size =
      81              :         spdm_context->transcript.message_m.max_buffer_size;
      82              : #endif
      83              : 
      84            1 :     response_size = sizeof(response);
      85            1 :     status = libspdm_get_response_certificate(
      86              :         spdm_context, m_libspdm_get_certificate_request1_size,
      87              :         &m_libspdm_get_certificate_request1, &response_size, response);
      88            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
      89            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
      90              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
      91            1 :     spdm_response = (void *)response;
      92            1 :     assert_int_equal(spdm_response->header.request_response_code,
      93              :                      SPDM_CERTIFICATE);
      94            1 :     assert_int_equal(spdm_response->header.param1, 0);
      95            1 :     assert_int_equal(spdm_response->portion_length,
      96              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
      97            1 :     assert_int_equal(spdm_response->remainder_length,
      98              :                      data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
      99              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     100              :     assert_int_equal(spdm_context->transcript.message_m.buffer_size,
     101              :                      0);
     102              : #endif
     103            1 :     free(data);
     104            1 : }
     105              : 
     106              : /**
     107              :  * Test 2:
     108              :  * Expected Behavior:
     109              :  **/
     110            1 : static void rsp_certificate_case2(void **state)
     111              : {
     112            1 : }
     113              : 
     114              : /**
     115              :  * Test 3: Force response_state = LIBSPDM_RESPONSE_STATE_BUSY when asked GET_CERTIFICATE
     116              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_BUSY
     117              :  **/
     118            1 : static void rsp_certificate_case3(void **state)
     119              : {
     120              :     libspdm_return_t status;
     121              :     libspdm_test_context_t *spdm_test_context;
     122              :     libspdm_context_t *spdm_context;
     123              :     size_t response_size;
     124              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     125              :     spdm_certificate_response_t *spdm_response;
     126              :     void *data;
     127              :     size_t data_size;
     128              : 
     129            1 :     spdm_test_context = *state;
     130            1 :     spdm_context = spdm_test_context->spdm_context;
     131            1 :     spdm_test_context->case_id = 0x3;
     132            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     133              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     134            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
     135            1 :     spdm_context->connection_info.connection_state =
     136              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     137            1 :     spdm_context->local_context.capability.flags |=
     138              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     139            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     140              :         m_libspdm_use_hash_algo;
     141            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     142              :                                                     m_libspdm_use_asym_algo, &data,
     143              :                                                     &data_size, NULL, NULL);
     144            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     145            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     146              :         data_size;
     147              : 
     148            1 :     response_size = sizeof(response);
     149            1 :     status = libspdm_get_response_certificate(
     150              :         spdm_context, m_libspdm_get_certificate_request1_size,
     151              :         &m_libspdm_get_certificate_request1, &response_size, response);
     152            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     153            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     154            1 :     spdm_response = (void *)response;
     155            1 :     assert_int_equal(spdm_response->header.request_response_code,
     156              :                      SPDM_ERROR);
     157            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
     158            1 :     assert_int_equal(spdm_response->header.param2, 0);
     159            1 :     assert_int_equal(spdm_context->response_state,
     160              :                      LIBSPDM_RESPONSE_STATE_BUSY);
     161            1 :     free(data);
     162            1 : }
     163              : 
     164              : /**
     165              :  * Test 4: Force response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC when asked GET_CERTIFICATE
     166              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_REQUEST_RESYNCH
     167              :  **/
     168            1 : static void rsp_certificate_case4(void **state)
     169              : {
     170              :     libspdm_return_t status;
     171              :     libspdm_test_context_t *spdm_test_context;
     172              :     libspdm_context_t *spdm_context;
     173              :     size_t response_size;
     174              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     175              :     spdm_certificate_response_t *spdm_response;
     176              :     void *data;
     177              :     size_t data_size;
     178              : 
     179            1 :     spdm_test_context = *state;
     180            1 :     spdm_context = spdm_test_context->spdm_context;
     181            1 :     spdm_test_context->case_id = 0x4;
     182            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     183              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     184            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
     185            1 :     spdm_context->connection_info.connection_state =
     186              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     187            1 :     spdm_context->local_context.capability.flags |=
     188              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     189            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     190              :         m_libspdm_use_hash_algo;
     191            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     192              :                                                     m_libspdm_use_asym_algo, &data,
     193              :                                                     &data_size, NULL, NULL);
     194            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     195            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     196              :         data_size;
     197              : 
     198            1 :     response_size = sizeof(response);
     199            1 :     status = libspdm_get_response_certificate(
     200              :         spdm_context, m_libspdm_get_certificate_request1_size,
     201              :         &m_libspdm_get_certificate_request1, &response_size, response);
     202            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     203            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     204            1 :     spdm_response = (void *)response;
     205            1 :     assert_int_equal(spdm_response->header.request_response_code,
     206              :                      SPDM_ERROR);
     207            1 :     assert_int_equal(spdm_response->header.param1,
     208              :                      SPDM_ERROR_CODE_REQUEST_RESYNCH);
     209            1 :     assert_int_equal(spdm_response->header.param2, 0);
     210            1 :     assert_int_equal(spdm_context->response_state,
     211              :                      LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
     212            1 :     free(data);
     213            1 : }
     214              : 
     215              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
     216              : /**
     217              :  * Test 5: Force response_state = LIBSPDM_RESPONSE_STATE_NOT_READY when asked GET_CERTIFICATE
     218              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_RESPONSE_NOT_READY and correct error_data
     219              :  **/
     220            1 : static void rsp_certificate_case5(void **state)
     221              : {
     222              :     libspdm_return_t status;
     223              :     libspdm_test_context_t *spdm_test_context;
     224              :     libspdm_context_t *spdm_context;
     225              :     size_t response_size;
     226              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     227              :     spdm_certificate_response_t *spdm_response;
     228              :     void *data;
     229              :     size_t data_size;
     230              :     spdm_error_data_response_not_ready_t *error_data;
     231              : 
     232            1 :     spdm_test_context = *state;
     233            1 :     spdm_context = spdm_test_context->spdm_context;
     234            1 :     spdm_test_context->case_id = 0x5;
     235            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     236              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     237            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
     238            1 :     spdm_context->connection_info.connection_state =
     239              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     240            1 :     spdm_context->local_context.capability.flags |=
     241              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     242            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     243            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     244              :                                                     m_libspdm_use_asym_algo, &data,
     245              :                                                     &data_size, NULL, NULL);
     246            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     247            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
     248              : 
     249            1 :     response_size = sizeof(response);
     250            1 :     status = libspdm_get_response_certificate(
     251              :         spdm_context, m_libspdm_get_certificate_request1_size,
     252              :         &m_libspdm_get_certificate_request1, &response_size, response);
     253            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     254            1 :     assert_int_equal(response_size,
     255              :                      sizeof(spdm_error_response_t) +
     256              :                      sizeof(spdm_error_data_response_not_ready_t));
     257            1 :     spdm_response = (void *)response;
     258            1 :     error_data = (spdm_error_data_response_not_ready_t
     259              :                   *)(&spdm_response->portion_length);
     260            1 :     assert_int_equal(spdm_response->header.request_response_code,
     261              :                      SPDM_ERROR);
     262            1 :     assert_int_equal(spdm_response->header.param1,
     263              :                      SPDM_ERROR_CODE_RESPONSE_NOT_READY);
     264            1 :     assert_int_equal(spdm_response->header.param2, 0);
     265            1 :     assert_int_equal(spdm_context->response_state,
     266              :                      LIBSPDM_RESPONSE_STATE_NOT_READY);
     267            1 :     assert_int_equal(error_data->request_code, SPDM_GET_CERTIFICATE);
     268            1 :     free(data);
     269            1 : }
     270              : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
     271              : 
     272              : /**
     273              :  * Test 6: simulate wrong connection_state when asked GET_CERTIFICATE (missing SPDM_GET_DIGESTS_RECEIVE_FLAG and SPDM_GET_CAPABILITIES_RECEIVE_FLAG)
     274              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_UNEXPECTED_REQUEST
     275              :  **/
     276            1 : static void rsp_certificate_case6(void **state)
     277              : {
     278              :     libspdm_return_t status;
     279              :     libspdm_test_context_t *spdm_test_context;
     280              :     libspdm_context_t *spdm_context;
     281              :     size_t response_size;
     282              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     283              :     spdm_certificate_response_t *spdm_response;
     284              :     void *data;
     285              :     size_t data_size;
     286              : 
     287            1 :     spdm_test_context = *state;
     288            1 :     spdm_context = spdm_test_context->spdm_context;
     289            1 :     spdm_test_context->case_id = 0x6;
     290            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     291              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     292            1 :     spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
     293            1 :     spdm_context->connection_info.connection_state =
     294              :         LIBSPDM_CONNECTION_STATE_NOT_STARTED;
     295            1 :     spdm_context->local_context.capability.flags |=
     296              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     297            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     298              :         m_libspdm_use_hash_algo;
     299            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     300              :                                                     m_libspdm_use_asym_algo, &data,
     301              :                                                     &data_size, NULL, NULL);
     302            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     303            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     304              :         data_size;
     305              : 
     306              : 
     307            1 :     response_size = sizeof(response);
     308            1 :     status = libspdm_get_response_certificate(
     309              :         spdm_context, m_libspdm_get_certificate_request1_size,
     310              :         &m_libspdm_get_certificate_request1, &response_size, response);
     311            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     312            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     313            1 :     spdm_response = (void *)response;
     314            1 :     assert_int_equal(spdm_response->header.request_response_code,
     315              :                      SPDM_ERROR);
     316            1 :     assert_int_equal(spdm_response->header.param1,
     317              :                      SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
     318            1 :     assert_int_equal(spdm_response->header.param2, 0);
     319            1 :     free(data);
     320            1 : }
     321              : 
     322              : /**
     323              :  * Test 7: request length at the boundary of maximum integer values, while keeping offset 0
     324              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     325              :  **/
     326            1 : static void rsp_certificate_case7(void **state)
     327              : {
     328              :     libspdm_return_t status;
     329              :     libspdm_test_context_t *spdm_test_context;
     330              :     libspdm_context_t *spdm_context;
     331              :     size_t response_size;
     332              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     333              :     spdm_certificate_response_t *spdm_response;
     334              :     void *data;
     335              :     size_t data_size;
     336              : 
     337              :     /* Testing Lengths at the boundary of maximum integer values*/
     338            1 :     uint16_t test_lengths[] = {
     339              :         1,        0x7F,     (uint16_t)(0x7F + 1),
     340              :         0xFF,  0x7FFF,     (uint16_t)(0x7FFF + 1),
     341              :         0xFFFF, (uint16_t)(-1)
     342              :     };
     343              :     uint16_t expected_chunk_size;
     344              : 
     345              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     346            1 :     spdm_test_context = *state;
     347            1 :     spdm_context = spdm_test_context->spdm_context;
     348            1 :     spdm_test_context->case_id = 0x7;
     349            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     350              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     351            1 :     spdm_context->connection_info.connection_state =
     352              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     353            1 :     spdm_context->local_context.capability.flags |=
     354              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     355            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     356              :         m_libspdm_use_hash_algo;
     357            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     358              :                                                     m_libspdm_use_asym_algo, &data,
     359              :                                                     &data_size, NULL, NULL);
     360            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     361            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     362              :         data_size;
     363              : 
     364              :     /* This tests considers only offset = 0, other tests vary offset value*/
     365            1 :     m_libspdm_get_certificate_request3.offset = 0;
     366              : 
     367            9 :     for (int i = 0; i < sizeof(test_lengths) / sizeof(test_lengths[0]); i++) {
     368              :         TEST_LIBSPDM_DEBUG_PRINT("i:%d test_lengths[i]:%u\n", i, test_lengths[i]);
     369            8 :         m_libspdm_get_certificate_request3.length = test_lengths[i];
     370              :         /* Expected received length is limited by the response_size*/
     371            8 :         response_size = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + sizeof(spdm_certificate_response_t);
     372            8 :         expected_chunk_size =
     373            8 :             (uint16_t) LIBSPDM_MIN(response_size - sizeof(spdm_certificate_response_t),
     374              :                                    SPDM_MAX_CERTIFICATE_CHAIN_SIZE);
     375            8 :         expected_chunk_size = LIBSPDM_MIN(m_libspdm_get_certificate_request3.length,
     376              :                                           LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     377              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     378            8 :         libspdm_reset_message_b(spdm_context);
     379            8 :         status = libspdm_get_response_certificate(
     380              :             spdm_context, m_libspdm_get_certificate_request3_size,
     381              :             &m_libspdm_get_certificate_request3, &response_size,
     382              :             response);
     383            8 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     384            8 :         assert_int_equal(response_size,
     385              :                          sizeof(spdm_certificate_response_t) +
     386              :                          expected_chunk_size);
     387            8 :         spdm_response = (void *)response;
     388            8 :         assert_int_equal(spdm_response->header.request_response_code,
     389              :                          SPDM_CERTIFICATE);
     390            8 :         assert_int_equal(spdm_response->header.param1, 0);
     391            8 :         assert_int_equal(spdm_response->portion_length,
     392              :                          expected_chunk_size);
     393            8 :         assert_int_equal(spdm_response->remainder_length,
     394              :                          data_size - expected_chunk_size);
     395              :     }
     396            1 :     free(data);
     397            1 : }
     398              : 
     399              : /**
     400              :  * Test 8: request offset at the boundary of maximum integer values, while keeping length 0
     401              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     402              :  **/
     403            1 : static void rsp_certificate_case8(void **state)
     404              : {
     405              :     libspdm_return_t status;
     406              :     libspdm_test_context_t *spdm_test_context;
     407              :     libspdm_context_t *spdm_context;
     408              :     size_t response_size;
     409              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     410              :     spdm_certificate_response_t *spdm_response;
     411              :     spdm_error_response_t *spdm_responseError;
     412              :     void *data;
     413              :     size_t data_size;
     414              : 
     415              :     /* Testing offsets at the boundary of maximum integer values and at the boundary of certificate length (first three positions)*/
     416            1 :     uint16_t test_offsets[] = { (uint16_t)(-1),
     417              :                                 0,
     418              :                                 +1,
     419              :                                 0,
     420              :                                 0x7F,
     421              :                                 (uint16_t)(0x7F + 1),
     422              :                                 0xFF,
     423              :                                 0x7FFF,
     424              :                                 (uint16_t)(0x7FFF + 1),
     425              :                                 0xFFFF,
     426              :                                 (uint16_t)(-1) };
     427              : 
     428              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     429            1 :     spdm_test_context = *state;
     430            1 :     spdm_context = spdm_test_context->spdm_context;
     431            1 :     spdm_test_context->case_id = 0x8;
     432            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     433              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     434            1 :     spdm_context->connection_info.connection_state =
     435              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     436            1 :     spdm_context->local_context.capability.flags |=
     437              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     438            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     439              :         m_libspdm_use_hash_algo;
     440            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     441              :                                                     m_libspdm_use_asym_algo, &data,
     442              :                                                     &data_size, NULL, NULL);
     443            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     444            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     445              :         data_size;
     446              : 
     447              :     /* This tests considers only length = 1, other tests vary length value*/
     448            1 :     m_libspdm_get_certificate_request3.length = 1;
     449              :     /* Setting up offset values at the boundary of certificate length*/
     450            1 :     test_offsets[0] = (uint16_t)(test_offsets[0] + data_size);
     451            1 :     test_offsets[1] = (uint16_t)(test_offsets[1] + data_size);
     452            1 :     test_offsets[2] = (uint16_t)(test_offsets[2] + data_size);
     453              : 
     454           12 :     for (int i = 0; i < sizeof(test_offsets) / sizeof(test_offsets[0]); i++) {
     455              :         TEST_LIBSPDM_DEBUG_PRINT("i:%d test_offsets[i]:%u\n", i, test_offsets[i]);
     456           11 :         m_libspdm_get_certificate_request3.offset = test_offsets[i];
     457              : 
     458              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     459           11 :         libspdm_reset_message_b(spdm_context);
     460           11 :         response_size = sizeof(response);
     461           11 :         status = libspdm_get_response_certificate(
     462              :             spdm_context, m_libspdm_get_certificate_request3_size,
     463              :             &m_libspdm_get_certificate_request3, &response_size,
     464              :             response);
     465           11 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     466              : 
     467           11 :         if (m_libspdm_get_certificate_request3.offset >= data_size) {
     468              :             /* A too long of an offset should return an error*/
     469            6 :             spdm_responseError = (void *)response;
     470            6 :             assert_int_equal(
     471              :                 spdm_responseError->header.request_response_code,
     472              :                 SPDM_ERROR);
     473            6 :             assert_int_equal(spdm_responseError->header.param1,
     474              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     475              :         } else {
     476              :             /* Otherwise it should work properly, considering length = 1*/
     477            5 :             assert_int_equal(response_size,
     478              :                              sizeof(spdm_certificate_response_t) + 1);
     479            5 :             spdm_response = (void *)response;
     480            5 :             assert_int_equal(
     481              :                 spdm_response->header.request_response_code,
     482              :                 SPDM_CERTIFICATE);
     483            5 :             assert_int_equal(spdm_response->header.param1, 0);
     484            5 :             assert_int_equal(spdm_response->portion_length, 1);
     485            5 :             assert_int_equal(
     486              :                 spdm_response->remainder_length + 1,
     487              :                 (uint16_t)(
     488              :                     data_size -
     489              :                     m_libspdm_get_certificate_request3.offset));
     490              :         }
     491              :     }
     492            1 :     free(data);
     493            1 : }
     494              : 
     495              : /**
     496              :  * Test 9: request offset and length at the boundary of maximum integer values
     497              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     498              :  **/
     499            1 : static void rsp_certificate_case9(void **state)
     500              : {
     501              :     libspdm_return_t status;
     502              :     libspdm_test_context_t *spdm_test_context;
     503              :     libspdm_context_t *spdm_context;
     504              :     size_t response_size;
     505              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     506              :     spdm_certificate_response_t *spdm_response;
     507              :     spdm_error_response_t *spdm_responseError;
     508              :     void *data;
     509              :     size_t data_size;
     510              : 
     511              :     /* Testing offsets and length combinations
     512              :      * Check at the boundary of maximum integer values and at the boundary of certificate length*/
     513            1 :     uint16_t test_sizes[] = {
     514              :         (uint16_t)(-1),
     515              :         0,
     516              :         +1, /* reserved for sizes around the certificate chain size*/
     517              :         (uint16_t)(-1),
     518              :         +1,
     519              :         (uint16_t)(0x7F - 1),
     520              :         0x7F,
     521              :         (uint16_t)(0x7F + 1),
     522              :         (uint16_t)(0xFF - 1),
     523              :         0xFF,
     524              :         (uint16_t)(0x7FFF - 1),
     525              :         0x7FFF,
     526              :         (uint16_t)(0x7FFF + 1),
     527              :         (uint16_t)(0xFFFF - 1),
     528              :         0xFFFF
     529              :     };
     530              :     uint16_t expected_chunk_size;
     531              :     uint16_t expected_remainder;
     532              : 
     533              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     534            1 :     spdm_test_context = *state;
     535            1 :     spdm_context = spdm_test_context->spdm_context;
     536            1 :     spdm_test_context->case_id = 0x9;
     537            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     538              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     539            1 :     spdm_context->connection_info.connection_state =
     540              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     541            1 :     spdm_context->local_context.capability.flags |=
     542              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     543            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     544              :         m_libspdm_use_hash_algo;
     545            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     546              :                                                     m_libspdm_use_asym_algo, &data,
     547              :                                                     &data_size, NULL, NULL);
     548            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     549            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     550              :         data_size;
     551              : 
     552              :     /* Setting up offset values at the boundary of certificate length*/
     553            1 :     test_sizes[0] += (uint16_t)(test_sizes[0] + data_size);
     554            1 :     test_sizes[1] += (uint16_t)(test_sizes[1] + data_size);
     555            1 :     test_sizes[2] += (uint16_t)(test_sizes[2] + data_size);
     556              : 
     557           16 :     for (int i = 0; i < sizeof(test_sizes) / sizeof(test_sizes[0]); i++) {
     558              :         TEST_LIBSPDM_DEBUG_PRINT("i:%d test_sizes[i]=length:%u\n", i,
     559              :                                  test_sizes[i]);
     560           15 :         m_libspdm_get_certificate_request3.length = test_sizes[i];
     561          240 :         for (int j = 0; j < sizeof(test_sizes) / sizeof(test_sizes[0]);
     562          225 :              j++) {
     563              :             TEST_LIBSPDM_DEBUG_PRINT("\tj:%d test_sizes[j]=offset:%u\n", j,
     564              :                                      test_sizes[j]);
     565          225 :             m_libspdm_get_certificate_request3.offset = test_sizes[j];
     566              : 
     567              :             /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     568          225 :             libspdm_reset_message_b(spdm_context);
     569          225 :             response_size = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + sizeof(spdm_certificate_response_t);
     570          225 :             status = libspdm_get_response_certificate(
     571              :                 spdm_context,
     572              :                 m_libspdm_get_certificate_request3_size,
     573              :                 &m_libspdm_get_certificate_request3,
     574              :                 &response_size, response);
     575          225 :             assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     576              : 
     577          225 :             if (m_libspdm_get_certificate_request3.offset >=
     578              :                 data_size) {
     579              :                 /* A too long of an offset should return an error*/
     580          120 :                 spdm_responseError = (void *)response;
     581          120 :                 assert_int_equal(spdm_responseError->header
     582              :                                  .request_response_code,
     583              :                                  SPDM_ERROR);
     584          120 :                 assert_int_equal(
     585              :                     spdm_responseError->header.param1,
     586              :                     SPDM_ERROR_CODE_INVALID_REQUEST);
     587              :             } else {
     588              :                 /* Otherwise it should work properly*/
     589              : 
     590              :                 /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     591          105 :                 expected_chunk_size = (uint16_t)(LIBSPDM_MIN(
     592              :                                                      m_libspdm_get_certificate_request3.length,
     593              :                                                      data_size -
     594              :                                                      m_libspdm_get_certificate_request3
     595              :                                                      .offset));
     596              : 
     597              :                 /* Expected received length is limited by the response_size*/
     598          105 :                 expected_chunk_size =
     599          105 :                     LIBSPDM_MIN(expected_chunk_size,
     600              :                                 (uint16_t)(response_size - sizeof(spdm_certificate_response_t)));
     601              : 
     602              :                 /* Expected certificate length left*/
     603          105 :                 expected_remainder = (uint16_t)(
     604          105 :                     data_size -
     605          105 :                     m_libspdm_get_certificate_request3.offset -
     606              :                     expected_chunk_size);
     607              : 
     608          105 :                 assert_int_equal(
     609              :                     response_size,
     610              :                     sizeof(spdm_certificate_response_t) +
     611              :                     expected_chunk_size);
     612          105 :                 spdm_response = (void *)response;
     613          105 :                 assert_int_equal(spdm_response->header
     614              :                                  .request_response_code,
     615              :                                  SPDM_CERTIFICATE);
     616          105 :                 assert_int_equal(spdm_response->header.param1,
     617              :                                  0);
     618          105 :                 assert_int_equal(spdm_response->portion_length,
     619              :                                  expected_chunk_size);
     620          105 :                 assert_int_equal(
     621              :                     spdm_response->remainder_length,
     622              :                     expected_remainder);
     623              :             }
     624              :         }
     625              :     }
     626            1 :     free(data);
     627            1 : }
     628              : 
     629              : /**
     630              :  * Test 10: request LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of long certificate chains, with the largest valid offset
     631              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     632              :  **/
     633            1 : static void rsp_certificate_case10(void **state)
     634              : {
     635              :     libspdm_return_t status;
     636              :     libspdm_test_context_t *spdm_test_context;
     637              :     libspdm_context_t *spdm_context;
     638              :     size_t response_size;
     639              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     640              :     spdm_certificate_response_t *spdm_response;
     641              :     spdm_error_response_t *spdm_responseError;
     642              :     void *data;
     643              :     size_t data_size;
     644              : 
     645            1 :     uint16_t test_cases[] = { LIBSPDM_TEST_CERT_MAXINT16, LIBSPDM_TEST_CERT_MAXUINT16 };
     646              : 
     647              :     size_t expected_chunk_size;
     648              :     size_t expected_remainder;
     649              : 
     650              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     651            1 :     spdm_test_context = *state;
     652            1 :     spdm_context = spdm_test_context->spdm_context;
     653            1 :     spdm_test_context->case_id = 0xA;
     654            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     655              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     656            1 :     spdm_context->connection_info.connection_state =
     657              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     658            1 :     spdm_context->local_context.capability.flags |=
     659              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     660            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     661              :         m_libspdm_use_hash_algo;
     662              : 
     663            1 :     m_libspdm_get_certificate_request3.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     664              : 
     665            3 :     for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
     666            2 :         libspdm_read_responder_public_certificate_chain_by_size(
     667              :             /*MAXUINT16_CERT signature_algo is SHA256RSA */
     668              :             m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
     669            2 :             test_cases[i], &data, &data_size, NULL, NULL);
     670              : 
     671            2 :         spdm_context->local_context.local_cert_chain_provision[0] =
     672              :             data;
     673            2 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     674              :             data_size;
     675              : 
     676            2 :         m_libspdm_get_certificate_request3.offset =
     677            2 :             (uint16_t)(LIBSPDM_MIN(data_size - 1, 0xFFFF));
     678              :         TEST_LIBSPDM_DEBUG_PRINT("data_size: %u\n", data_size);
     679              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.offset: %u\n",
     680              :                                  m_libspdm_get_certificate_request3.offset);
     681              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.length: %u\n",
     682              :                                  m_libspdm_get_certificate_request3.length);
     683              :         TEST_LIBSPDM_DEBUG_PRINT(
     684              :             "offset + length: %u\n",
     685              :             m_libspdm_get_certificate_request3.offset +
     686              :             m_libspdm_get_certificate_request3.length);
     687              : 
     688              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     689            2 :         libspdm_reset_message_b(spdm_context);
     690            2 :         response_size = sizeof(response);
     691            2 :         status = libspdm_get_response_certificate(
     692              :             spdm_context, m_libspdm_get_certificate_request3_size,
     693              :             &m_libspdm_get_certificate_request3, &response_size,
     694              :             response);
     695            2 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     696              : 
     697              :         /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     698            2 :         expected_chunk_size = (uint16_t)(LIBSPDM_MIN(
     699              :                                              m_libspdm_get_certificate_request3.length,
     700              :                                              data_size -
     701              :                                              m_libspdm_get_certificate_request3.offset));
     702            2 :         expected_chunk_size =
     703              :             LIBSPDM_MIN(expected_chunk_size, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     704              :         /* Expected certificate length left*/
     705            2 :         expected_remainder = (uint16_t)(
     706            2 :             data_size - m_libspdm_get_certificate_request3.offset -
     707              :             expected_chunk_size);
     708              : 
     709              :         TEST_LIBSPDM_DEBUG_PRINT("expected_chunk_size %u\n", expected_chunk_size);
     710              :         TEST_LIBSPDM_DEBUG_PRINT("expected_remainder %u\n", expected_remainder);
     711              : 
     712            2 :         if (expected_remainder > 0xFFFF ||
     713              :             expected_chunk_size > 0xFFFF) {
     714            0 :             spdm_responseError = (void *)response;
     715            0 :             assert_int_equal(
     716              :                 spdm_responseError->header.request_response_code,
     717              :                 SPDM_ERROR);
     718            0 :             assert_int_equal(spdm_responseError->header.param1,
     719              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     720              :         } else {
     721            2 :             assert_int_equal(response_size,
     722              :                              sizeof(spdm_certificate_response_t) +
     723              :                              expected_chunk_size);
     724            2 :             spdm_response = (void *)response;
     725            2 :             assert_int_equal(
     726              :                 spdm_response->header.request_response_code,
     727              :                 SPDM_CERTIFICATE);
     728            2 :             assert_int_equal(spdm_response->header.param1, 0);
     729            2 :             assert_int_equal(spdm_response->portion_length,
     730              :                              expected_chunk_size);
     731            2 :             assert_int_equal(spdm_response->remainder_length,
     732              :                              expected_remainder);
     733              :         }
     734              : 
     735              :         TEST_LIBSPDM_DEBUG_PRINT("\n");
     736              : 
     737            2 :         spdm_context->local_context.local_cert_chain_provision[0] =
     738              :             NULL;
     739            2 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     740              :             0;
     741            2 :         free(data);
     742              :     }
     743            1 : }
     744              : 
     745              : /**
     746              :  * Test 11: request LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of a short certificate chain (fits in 1 message)
     747              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     748              :  **/
     749            1 : static void rsp_certificate_case11(void **state)
     750              : {
     751              :     libspdm_return_t status;
     752              :     libspdm_test_context_t *spdm_test_context;
     753              :     libspdm_context_t *spdm_context;
     754              :     size_t response_size;
     755              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     756              :     spdm_certificate_response_t *spdm_response;
     757              :     spdm_error_response_t *spdm_responseError;
     758              :     void *data;
     759              :     size_t data_size;
     760              : 
     761            1 :     uint16_t test_cases[] = { LIBSPDM_TEST_CERT_SMALL };
     762              : 
     763              :     size_t expected_chunk_size;
     764              :     size_t expected_remainder;
     765              : 
     766              :     /* This case requires a short certificate chain (fits in 1 message) for testing,
     767              :      * so skip when m_libspdm_use_asym_algo is other than ECC_P256 */
     768            1 :     if (m_libspdm_use_asym_algo !=
     769              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256) {
     770            0 :         return;
     771              :     }
     772              : 
     773              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     774            1 :     spdm_test_context = *state;
     775            1 :     spdm_context = spdm_test_context->spdm_context;
     776            1 :     spdm_test_context->case_id = 0xB;
     777            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     778              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     779            1 :     spdm_context->connection_info.connection_state =
     780              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     781            1 :     spdm_context->local_context.capability.flags |=
     782              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     783            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     784              :         m_libspdm_use_hash_algo;
     785              : 
     786            1 :     m_libspdm_get_certificate_request3.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     787            1 :     m_libspdm_get_certificate_request3.offset = 0;
     788              : 
     789            2 :     for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
     790            1 :         libspdm_read_responder_public_certificate_chain_by_size(
     791            1 :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, test_cases[i], &data,
     792              :             &data_size, NULL, NULL);
     793            1 :         spdm_context->local_context.local_cert_chain_provision[0] =
     794              :             data;
     795            1 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     796              :             data_size;
     797              : 
     798              :         TEST_LIBSPDM_DEBUG_PRINT("data_size: %u\n", data_size);
     799              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.offset: %u\n",
     800              :                                  m_libspdm_get_certificate_request3.offset);
     801              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.length: %u\n",
     802              :                                  m_libspdm_get_certificate_request3.length);
     803              :         TEST_LIBSPDM_DEBUG_PRINT(
     804              :             "offset + length: %u\n",
     805              :             m_libspdm_get_certificate_request3.offset +
     806              :             m_libspdm_get_certificate_request3.length);
     807              : 
     808              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     809            1 :         libspdm_reset_message_b(spdm_context);
     810            1 :         response_size = sizeof(response);
     811            1 :         status = libspdm_get_response_certificate(
     812              :             spdm_context, m_libspdm_get_certificate_request3_size,
     813              :             &m_libspdm_get_certificate_request3, &response_size,
     814              :             response);
     815            1 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     816              : 
     817              :         /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     818            1 :         expected_chunk_size =
     819            1 :             LIBSPDM_MIN(m_libspdm_get_certificate_request3.length,
     820              :                         data_size - m_libspdm_get_certificate_request3.offset);
     821            1 :         expected_chunk_size =
     822              :             LIBSPDM_MIN(expected_chunk_size, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     823              :         /* Expected certificate length left*/
     824            1 :         expected_remainder = data_size -
     825            1 :                              m_libspdm_get_certificate_request3.offset -
     826              :                              expected_chunk_size;
     827              : 
     828              :         TEST_LIBSPDM_DEBUG_PRINT("expected_chunk_size %u\n", expected_chunk_size);
     829              :         TEST_LIBSPDM_DEBUG_PRINT("expected_remainder %u\n", expected_remainder);
     830              : 
     831            1 :         if (expected_remainder > 0xFFFF ||
     832              :             expected_chunk_size > 0xFFFF) {
     833            0 :             spdm_responseError = (void *)response;
     834            0 :             assert_int_equal(
     835              :                 spdm_responseError->header.request_response_code,
     836              :                 SPDM_ERROR);
     837            0 :             assert_int_equal(spdm_responseError->header.param1,
     838              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     839              :         } else {
     840            1 :             assert_int_equal(response_size,
     841              :                              sizeof(spdm_certificate_response_t) +
     842              :                              expected_chunk_size);
     843            1 :             spdm_response = (void *)response;
     844            1 :             assert_int_equal(
     845              :                 spdm_response->header.request_response_code,
     846              :                 SPDM_CERTIFICATE);
     847            1 :             assert_int_equal(spdm_response->header.param1, 0);
     848            1 :             assert_int_equal(spdm_response->portion_length,
     849              :                              expected_chunk_size);
     850            1 :             assert_int_equal(spdm_response->remainder_length,
     851              :                              expected_remainder);
     852              :         }
     853              : 
     854              :         TEST_LIBSPDM_DEBUG_PRINT("\n");
     855              : 
     856            1 :         free(data);
     857              :     }
     858              : }
     859              : 
     860              : /**
     861              :  * Test 12: request a whole certificate chain byte by byte
     862              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     863              :  **/
     864            1 : static void rsp_certificate_case12(void **state)
     865              : {
     866              :     libspdm_return_t status;
     867              :     libspdm_test_context_t *spdm_test_context;
     868              :     libspdm_context_t *spdm_context;
     869              :     size_t response_size;
     870              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     871              :     spdm_certificate_response_t *spdm_response;
     872              :     void *data;
     873              :     size_t data_size;
     874              :     uint16_t expected_chunk_size;
     875              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     876              :     size_t count;
     877              : #endif
     878              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     879            1 :     spdm_test_context = *state;
     880            1 :     spdm_context = spdm_test_context->spdm_context;
     881            1 :     spdm_test_context->case_id = 0xC;
     882            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     883              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     884            1 :     spdm_context->connection_info.connection_state =
     885              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     886            1 :     spdm_context->local_context.capability.flags |=
     887              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     888            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     889              :         m_libspdm_use_hash_algo;
     890            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     891              :                                                     m_libspdm_use_asym_algo, &data,
     892              :                                                     &data_size, NULL, NULL);
     893            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     894            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     895              :         data_size;
     896              : 
     897              :     /* This tests considers only length = 1*/
     898            1 :     m_libspdm_get_certificate_request3.length = 1;
     899            1 :     expected_chunk_size = 1;
     900              : 
     901              : 
     902              :     /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     903            1 :     libspdm_reset_message_b(spdm_context);
     904              : 
     905            1 :     spdm_response = NULL;
     906         1391 :     for (size_t offset = 0; offset < data_size; offset++) {
     907              :         TEST_LIBSPDM_DEBUG_PRINT("offset:%u \n", offset);
     908         1390 :         m_libspdm_get_certificate_request3.offset = (uint16_t)offset;
     909              : 
     910         1390 :         response_size = sizeof(response);
     911         1390 :         status = libspdm_get_response_certificate(
     912              :             spdm_context, m_libspdm_get_certificate_request3_size,
     913              :             &m_libspdm_get_certificate_request3, &response_size,
     914              :             response);
     915         1390 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     916         1390 :         spdm_response = (void *)response;
     917              :         /* It may fail because the spdm does not support too many messages.
     918              :          * assert_int_equal (spdm_response->header.request_response_code, SPDM_CERTIFICATE);*/
     919         1390 :         if (spdm_response->header.request_response_code ==
     920              :             SPDM_CERTIFICATE) {
     921         1390 :             assert_int_equal(
     922              :                 spdm_response->header.request_response_code,
     923              :                 SPDM_CERTIFICATE);
     924         1390 :             assert_int_equal(response_size,
     925              :                              sizeof(spdm_certificate_response_t) +
     926              :                              expected_chunk_size);
     927         1390 :             assert_int_equal(spdm_response->header.param1, 0);
     928         1390 :             assert_int_equal(spdm_response->portion_length,
     929              :                              expected_chunk_size);
     930         1390 :             assert_int_equal(spdm_response->remainder_length,
     931              :                              data_size - offset -
     932              :                              expected_chunk_size);
     933         1390 :             assert_int_equal(
     934              :                 ((uint8_t *)data)[offset],
     935              :                 (response +
     936              :                  sizeof(spdm_certificate_response_t))[0]);
     937              :         } else {
     938            0 :             assert_int_equal(
     939              :                 spdm_response->header.request_response_code,
     940              :                 SPDM_ERROR);
     941            0 :             break;
     942              :         }
     943              :     }
     944            1 :     if (spdm_response != NULL) {
     945            1 :         if (spdm_response->header.request_response_code ==
     946              :             SPDM_CERTIFICATE) {
     947              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     948              :             count = (data_size + m_libspdm_get_certificate_request3.length - 1) /
     949              :                     m_libspdm_get_certificate_request3.length;
     950              :             assert_int_equal(
     951              :                 spdm_context->transcript.message_b.buffer_size,
     952              :                 sizeof(spdm_get_certificate_request_t) * count +
     953              :                 sizeof(spdm_certificate_response_t) *
     954              :                 count +
     955              :                 data_size);
     956              : #endif
     957              :         }
     958              :     }
     959            1 :     free(data);
     960            1 : }
     961              : 
     962              : /**
     963              :  * Test 13: receiving a correct GET_CERTIFICATE from the requester. Buffer B
     964              :  * already has arbitrary data.
     965              :  * Expected behavior: the responder accepts the request and produces a valid
     966              :  * CERTIFICATE response message, and buffer B receives the exchanged
     967              :  * GET_CERTIFICATE and CERTIFICATE messages.
     968              :  **/
     969            1 : static void rsp_certificate_case13(void **state)
     970              : {
     971              :     libspdm_return_t status;
     972              :     libspdm_test_context_t *spdm_test_context;
     973              :     libspdm_context_t *spdm_context;
     974              :     size_t response_size;
     975              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     976              :     spdm_certificate_response_t *spdm_response;
     977              :     void *data;
     978              :     size_t data_size;
     979              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     980              :     size_t arbitrary_size;
     981              : #endif
     982              : 
     983            1 :     spdm_test_context = *state;
     984            1 :     spdm_context = spdm_test_context->spdm_context;
     985            1 :     spdm_test_context->case_id = 0xD;
     986            1 :     spdm_context->connection_info.connection_state =
     987              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     988            1 :     spdm_context->local_context.capability.flags |=
     989              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     990            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     991            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     992              :                                                     m_libspdm_use_asym_algo, &data,
     993              :                                                     &data_size, NULL, NULL);
     994            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     995            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
     996              : 
     997              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     998              :     /*filling buffer B with arbitrary data*/
     999              :     arbitrary_size = 8;
    1000              :     libspdm_set_mem(spdm_context->transcript.message_b.buffer, arbitrary_size, (uint8_t) 0xEE);
    1001              :     spdm_context->transcript.message_b.buffer_size = arbitrary_size;
    1002              : #endif
    1003              : 
    1004            1 :     response_size = sizeof(response);
    1005            1 :     status = libspdm_get_response_certificate(
    1006              :         spdm_context, m_libspdm_get_certificate_request1_size,
    1007              :         &m_libspdm_get_certificate_request1, &response_size, response);
    1008            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1009            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
    1010              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1011            1 :     spdm_response = (void *)response;
    1012            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CERTIFICATE);
    1013            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1014            1 :     assert_int_equal(spdm_response->portion_length, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1015            1 :     assert_int_equal(spdm_response->remainder_length,
    1016              :                      data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1017              : 
    1018              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1019              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    1020              :                      arbitrary_size + m_libspdm_get_certificate_request1_size + response_size);
    1021              :     assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size,
    1022              :                         &m_libspdm_get_certificate_request1,
    1023              :                         m_libspdm_get_certificate_request1_size);
    1024              :     assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size +
    1025              :                         m_libspdm_get_certificate_request1_size,
    1026              :                         response, response_size);
    1027              : #endif
    1028              : 
    1029            1 :     free(data);
    1030            1 : }
    1031              : 
    1032              : /**
    1033              :  * Test 14: request the first LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of the certificate chain in a session
    1034              :  * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
    1035              :  **/
    1036            1 : static void rsp_certificate_case14(void **state)
    1037              : {
    1038              :     libspdm_return_t status;
    1039              :     libspdm_test_context_t *spdm_test_context;
    1040              :     libspdm_context_t *spdm_context;
    1041              :     size_t response_size;
    1042              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1043              :     spdm_certificate_response_t *spdm_response;
    1044              :     void *data;
    1045              :     size_t data_size;
    1046              :     libspdm_session_info_t *session_info;
    1047              :     uint32_t session_id;
    1048              : 
    1049            1 :     spdm_test_context = *state;
    1050            1 :     spdm_context = spdm_test_context->spdm_context;
    1051            1 :     spdm_test_context->case_id = 0xE;
    1052            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1053              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1054            1 :     spdm_context->connection_info.connection_state =
    1055              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1056            1 :     spdm_context->local_context.capability.flags |=
    1057              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1058            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1059              :         m_libspdm_use_hash_algo;
    1060              : 
    1061            1 :     session_id = 0xFFFFFFFF;
    1062            1 :     spdm_context->latest_session_id = session_id;
    1063            1 :     spdm_context->last_spdm_request_session_id_valid = true;
    1064            1 :     spdm_context->last_spdm_request_session_id = session_id;
    1065            1 :     session_info = &spdm_context->session_info[0];
    1066            1 :     libspdm_session_info_init(spdm_context, session_info, session_id,
    1067              :                               SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
    1068            1 :     libspdm_secured_message_set_session_state(
    1069              :         session_info->secured_message_context,
    1070              :         LIBSPDM_SESSION_STATE_ESTABLISHED);
    1071              : 
    1072            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1073              :                                                     m_libspdm_use_asym_algo, &data,
    1074              :                                                     &data_size, NULL, NULL);
    1075            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1076            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1077              :         data_size;
    1078              : 
    1079              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1080              :     session_info->session_transcript.message_m.buffer_size =
    1081              :         session_info->session_transcript.message_m.max_buffer_size;
    1082              : #endif
    1083              : 
    1084            1 :     response_size = sizeof(response);
    1085            1 :     status = libspdm_get_response_certificate(
    1086              :         spdm_context, m_libspdm_get_certificate_request1_size,
    1087              :         &m_libspdm_get_certificate_request1, &response_size, response);
    1088            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1089            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
    1090              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1091            1 :     spdm_response = (void *)response;
    1092            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1093              :                      SPDM_CERTIFICATE);
    1094            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1095            1 :     assert_int_equal(spdm_response->portion_length,
    1096              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1097            1 :     assert_int_equal(spdm_response->remainder_length,
    1098              :                      data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1099              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1100              :     assert_int_equal(session_info->session_transcript.message_m.buffer_size,
    1101              :                      0);
    1102              : #endif
    1103            1 :     free(data);
    1104            1 : }
    1105              : 
    1106              : /**
    1107              :  * Test 15: Produce a CERTIFICATE response that is meant to be chunked.
    1108              :  *          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN is ignored when chunking is enabled.
    1109              :  **/
    1110            1 : static void rsp_certificate_case15(void **state)
    1111              : {
    1112              :     libspdm_return_t status;
    1113              :     bool ret;
    1114              :     libspdm_test_context_t *spdm_test_context;
    1115              :     libspdm_context_t *spdm_context;
    1116              :     size_t response_size;
    1117              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1118              :     uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1119              :     spdm_get_certificate_request_t *spdm_cert_request;
    1120              :     spdm_certificate_response_t *spdm_cert_response;
    1121              :     void *data;
    1122              :     size_t data_size;
    1123              : 
    1124            1 :     spdm_test_context = *state;
    1125            1 :     spdm_context = spdm_test_context->spdm_context;
    1126            1 :     spdm_test_context->case_id = 15;
    1127            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
    1128              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1129              : 
    1130            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1131            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1132            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    1133            1 :     spdm_context->connection_info.capability.flags = 0;
    1134            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1135            1 :     spdm_context->connection_info.capability.data_transfer_size =
    1136              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12;
    1137              : 
    1138            1 :     spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1139            1 :     spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    1140            1 :     spdm_context->local_context.capability.data_transfer_size =
    1141              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12;
    1142            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP |
    1143              :                                                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1144              : 
    1145            1 :     ret = libspdm_read_responder_public_certificate_chain(
    1146              :         m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, &data,
    1147              :         &data_size, NULL, NULL);
    1148            1 :     assert_true(ret);
    1149              : 
    1150            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1151            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1152              : 
    1153            1 :     spdm_cert_request = (spdm_get_certificate_request_t *) request;
    1154              : 
    1155            1 :     spdm_cert_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
    1156            1 :     spdm_cert_request->header.request_response_code = SPDM_GET_CERTIFICATE;
    1157            1 :     spdm_cert_request->header.param1 = 0;
    1158            1 :     spdm_cert_request->header.param2 = 0;
    1159            1 :     spdm_cert_request->offset = 0;
    1160            1 :     spdm_cert_request->length = 0xffff;
    1161              : 
    1162            1 :     response_size = sizeof(response);
    1163            1 :     libspdm_zero_mem(response, response_size);
    1164              : 
    1165            1 :     status = libspdm_get_response_certificate(
    1166              :         spdm_context,
    1167              :         sizeof(spdm_get_certificate_request_t), &request,
    1168              :         &response_size, response);
    1169            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1170              : 
    1171            1 :     spdm_cert_response = (spdm_certificate_response_t *) response;
    1172              : 
    1173            1 :     assert_int_equal(spdm_cert_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
    1174            1 :     assert_int_equal(spdm_cert_response->header.request_response_code, SPDM_CERTIFICATE);
    1175            1 :     assert_int_equal(spdm_cert_response->header.param1, 0);
    1176            1 :     assert_int_equal(spdm_cert_response->header.param2, 0);
    1177            1 :     assert_int_equal(spdm_cert_response->portion_length, data_size);
    1178            1 :     assert_int_equal(spdm_cert_response->remainder_length, 0);
    1179              : 
    1180            1 :     free(data);
    1181            1 : }
    1182              : 
    1183              : /**
    1184              :  * Test 16: request a 0 byte certificate chain
    1185              :  * Expected Behavior: portion length should be 0 and remainder length should be the size of the
    1186              :  *                    certificate chain.
    1187              :  **/
    1188            1 : static void rsp_certificate_case16(void **state)
    1189              : {
    1190              :     libspdm_return_t status;
    1191              :     libspdm_test_context_t *spdm_test_context;
    1192              :     libspdm_context_t *spdm_context;
    1193              :     size_t response_size;
    1194              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1195              :     spdm_certificate_response_t *spdm_response;
    1196              :     void *data;
    1197              :     size_t data_size;
    1198              : 
    1199            1 :     spdm_test_context = *state;
    1200            1 :     spdm_context = spdm_test_context->spdm_context;
    1201            1 :     spdm_test_context->case_id = 16;
    1202            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1203              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1204            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1205            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1206            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1207            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1208              :                                                     m_libspdm_use_asym_algo, &data,
    1209              :                                                     &data_size, NULL, NULL);
    1210            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1211            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1212              : 
    1213            1 :     m_libspdm_get_certificate_request3.offset = 0;
    1214            1 :     m_libspdm_get_certificate_request3.length = 0;
    1215              : 
    1216            1 :     response_size = sizeof(response);
    1217            1 :     status = libspdm_get_response_certificate(
    1218              :         spdm_context, m_libspdm_get_certificate_request3_size,
    1219              :         &m_libspdm_get_certificate_request3, &response_size, response);
    1220            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1221            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
    1222            1 :     spdm_response = (void *)response;
    1223            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CERTIFICATE);
    1224            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1225            1 :     assert_int_equal(spdm_response->portion_length, 0);
    1226            1 :     assert_int_equal(spdm_response->remainder_length, data_size);
    1227              : 
    1228            1 :     free(data);
    1229            1 : }
    1230              : 
    1231              : /**
    1232              :  * Test 17: SlotID in GET_CERTIFICATE request message is 9, but it should be between 0 and 7 inclusive.
    1233              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_INVALID_REQUEST.
    1234              :  **/
    1235            1 : static void rsp_certificate_case17(void **state)
    1236              : {
    1237              :     libspdm_return_t status;
    1238              :     libspdm_test_context_t *spdm_test_context;
    1239              :     libspdm_context_t *spdm_context;
    1240              :     size_t response_size;
    1241              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1242              :     spdm_certificate_response_t *spdm_response;
    1243              :     void *data;
    1244              :     size_t data_size;
    1245              : 
    1246            1 :     spdm_test_context = *state;
    1247            1 :     spdm_context = spdm_test_context->spdm_context;
    1248            1 :     spdm_test_context->case_id = 17;
    1249            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1250              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1251            1 :     spdm_context->connection_info.connection_state =
    1252              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1253            1 :     spdm_context->local_context.capability.flags |=
    1254              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1255            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1256              :         m_libspdm_use_hash_algo;
    1257            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1258              :                                                     m_libspdm_use_asym_algo, &data,
    1259              :                                                     &data_size, NULL, NULL);
    1260            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1261            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1262              :         data_size;
    1263              : 
    1264            1 :     response_size = sizeof(response);
    1265            1 :     status = libspdm_get_response_certificate(
    1266              :         spdm_context, m_libspdm_get_certificate_request4_size,
    1267              :         &m_libspdm_get_certificate_request4, &response_size, response);
    1268            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1269            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
    1270            1 :     spdm_response = (void *)response;
    1271            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1272              :                      SPDM_ERROR);
    1273            1 :     assert_int_equal(spdm_response->header.param1,
    1274              :                      SPDM_ERROR_CODE_INVALID_REQUEST);
    1275            1 :     assert_int_equal(spdm_response->header.param2, 0);
    1276            1 :     free(data);
    1277            1 : }
    1278              : 
    1279              : /**
    1280              :  * Test 18: check request attributes and response attributes , SlotSizeRequested=1b the Offset and Length fields in the
    1281              :  * GET_CERTIFICATE request shall be ignored by the Responder
    1282              :  * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
    1283              :  **/
    1284            1 : static void rsp_certificate_case18(void **state)
    1285              : {
    1286              :     libspdm_return_t status;
    1287              :     libspdm_test_context_t *spdm_test_context;
    1288              :     libspdm_context_t *spdm_context;
    1289              :     size_t response_size;
    1290              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1291              :     spdm_certificate_response_t *spdm_response;
    1292              :     void *data;
    1293              :     size_t data_size;
    1294              : 
    1295            1 :     spdm_test_context = *state;
    1296            1 :     spdm_context = spdm_test_context->spdm_context;
    1297            1 :     spdm_test_context->case_id = 18;
    1298            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
    1299              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1300            1 :     spdm_context->connection_info.connection_state =
    1301              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1302            1 :     spdm_context->local_context.capability.flags |=
    1303              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1304            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1305              :         m_libspdm_use_hash_algo;
    1306            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1307              :                                                     m_libspdm_use_asym_algo, &data,
    1308              :                                                     &data_size, NULL, NULL);
    1309            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1310            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1311              :         data_size;
    1312              : 
    1313              :     /* When SlotSizeRequested=1b , the Offset and Length fields in the GET_CERTIFICATE request shall be ignored by the Responder */
    1314            1 :     m_libspdm_get_certificate_request5.header.param2 =
    1315              :         SPDM_GET_CERTIFICATE_REQUEST_ATTRIBUTES_SLOT_SIZE_REQUESTED;
    1316            1 :     m_libspdm_get_certificate_request5.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1317            1 :     m_libspdm_get_certificate_request5.offset = 0xFF;
    1318              : 
    1319            1 :     response_size = sizeof(response);
    1320            1 :     status = libspdm_get_response_certificate(
    1321              :         spdm_context, m_libspdm_get_certificate_request5_size,
    1322              :         &m_libspdm_get_certificate_request5, &response_size, response);
    1323            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1324            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
    1325            1 :     spdm_response = (void *)response;
    1326            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1327              :                      SPDM_CERTIFICATE);
    1328            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1329            1 :     assert_int_equal(spdm_response->portion_length,0);
    1330            1 :     assert_int_equal(spdm_response->remainder_length, data_size);
    1331            1 :     free(data);
    1332            1 : }
    1333              : 
    1334              : /**
    1335              :  * Test 19: Attempt to retrieve a certificate chain from a slot that needs to be reset.
    1336              :  * Expected Behavior: Responder responds with ResetRequired.
    1337              :  **/
    1338            1 : static void rsp_certificate_case19(void **state)
    1339              : {
    1340              :     libspdm_return_t status;
    1341              :     libspdm_test_context_t *spdm_test_context;
    1342              :     libspdm_context_t *spdm_context;
    1343              :     size_t response_size;
    1344              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1345              :     spdm_error_response_t *spdm_response;
    1346              :     void *data;
    1347              :     size_t data_size;
    1348            1 :     const uint8_t slot_id = 5;
    1349              : 
    1350            1 :     spdm_test_context = *state;
    1351            1 :     spdm_context = spdm_test_context->spdm_context;
    1352            1 :     spdm_test_context->case_id = 19;
    1353            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
    1354              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1355            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1356            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1357            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1358            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1359              :                                                     m_libspdm_use_asym_algo, &data,
    1360              :                                                     &data_size, NULL, NULL);
    1361            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1362            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1363              : 
    1364              :     /* Responder needs to be reset before certificate can be retrieved from specified SlotID. */
    1365            1 :     m_libspdm_get_certificate_request5.header.param1 = slot_id;
    1366            1 :     spdm_context->local_context.cert_slot_reset_mask = 1 << slot_id;
    1367              : 
    1368            1 :     response_size = sizeof(response);
    1369            1 :     status = libspdm_get_response_certificate(
    1370              :         spdm_context, m_libspdm_get_certificate_request5_size,
    1371              :         &m_libspdm_get_certificate_request5, &response_size, response);
    1372              : 
    1373            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1374            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
    1375            1 :     spdm_response = (void *)response;
    1376            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
    1377            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
    1378            1 :     assert_int_equal(spdm_response->header.param2, 0);
    1379              : 
    1380            1 :     free(data);
    1381            1 : }
    1382              : 
    1383            1 : int libspdm_rsp_certificate_test(void)
    1384              : {
    1385            1 :     const struct CMUnitTest test_cases[] = {
    1386              :         /* Success Case*/
    1387              :         cmocka_unit_test(rsp_certificate_case1),
    1388              :         /* Can be populated with new test.*/
    1389              :         cmocka_unit_test(rsp_certificate_case2),
    1390              :         /* response_state: LIBSPDM_RESPONSE_STATE_BUSY*/
    1391              :         cmocka_unit_test(rsp_certificate_case3),
    1392              :         /* response_state: LIBSPDM_RESPONSE_STATE_NEED_RESYNC*/
    1393              :         cmocka_unit_test(rsp_certificate_case4),
    1394              :         #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    1395              :         /* response_state: LIBSPDM_RESPONSE_STATE_NOT_READY*/
    1396              :         cmocka_unit_test(rsp_certificate_case5),
    1397              :         #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
    1398              :         /* connection_state Check*/
    1399              :         cmocka_unit_test(rsp_certificate_case6),
    1400              :         /* Tests varying length*/
    1401              :         cmocka_unit_test(rsp_certificate_case7),
    1402              :         /* Tests varying offset*/
    1403              :         cmocka_unit_test(rsp_certificate_case8),
    1404              :         /* Tests varying length and offset*/
    1405              :         cmocka_unit_test(rsp_certificate_case9),
    1406              :         /* Tests large certificate chains*/
    1407              :         cmocka_unit_test(rsp_certificate_case10),
    1408              :         /* Certificate fits in one single message*/
    1409              :         cmocka_unit_test(rsp_certificate_case11),
    1410              :         /* Requests byte by byte*/
    1411              :         cmocka_unit_test(rsp_certificate_case12),
    1412              :         /* Buffer verification*/
    1413              :         cmocka_unit_test(rsp_certificate_case13),
    1414              :         /* Success Case in a session*/
    1415              :         cmocka_unit_test(rsp_certificate_case14),
    1416              :         /* Produce a CERTIFICATE response that is meant to be chunked. */
    1417              :         cmocka_unit_test(rsp_certificate_case15),
    1418              :         cmocka_unit_test(rsp_certificate_case16),
    1419              :         /* Bad SlotID in request message */
    1420              :         cmocka_unit_test(rsp_certificate_case17),
    1421              :         /* check request attributes and response attributes*/
    1422              :         cmocka_unit_test(rsp_certificate_case18),
    1423              :         cmocka_unit_test(rsp_certificate_case19),
    1424              :     };
    1425              : 
    1426            1 :     libspdm_test_context_t test_context = {
    1427              :         LIBSPDM_TEST_CONTEXT_VERSION,
    1428              :         false,
    1429              :     };
    1430              : 
    1431            1 :     libspdm_setup_test_context(&test_context);
    1432              : 
    1433            1 :     return cmocka_run_group_tests(test_cases,
    1434              :                                   libspdm_unit_test_group_setup,
    1435              :                                   libspdm_unit_test_group_teardown);
    1436              : }
    1437              : 
    1438              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
        

Generated by: LCOV version 2.0-1