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 % 519 510
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 20 20

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2022 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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN (implementation specific?)*/
     371            8 :         expected_chunk_size = LIBSPDM_MIN(m_libspdm_get_certificate_request3.length,
     372              :                                           LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     373              : 
     374              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     375            8 :         libspdm_reset_message_b(spdm_context);
     376            8 :         response_size = sizeof(response);
     377            8 :         status = libspdm_get_response_certificate(
     378              :             spdm_context, m_libspdm_get_certificate_request3_size,
     379              :             &m_libspdm_get_certificate_request3, &response_size,
     380              :             response);
     381            8 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     382            8 :         assert_int_equal(response_size,
     383              :                          sizeof(spdm_certificate_response_t) +
     384              :                          expected_chunk_size);
     385            8 :         spdm_response = (void *)response;
     386            8 :         assert_int_equal(spdm_response->header.request_response_code,
     387              :                          SPDM_CERTIFICATE);
     388            8 :         assert_int_equal(spdm_response->header.param1, 0);
     389            8 :         assert_int_equal(spdm_response->portion_length,
     390              :                          expected_chunk_size);
     391            8 :         assert_int_equal(spdm_response->remainder_length,
     392              :                          data_size - expected_chunk_size);
     393              :     }
     394            1 :     free(data);
     395            1 : }
     396              : 
     397              : /**
     398              :  * Test 8: request offset at the boundary of maximum integer values, while keeping length 0
     399              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     400              :  **/
     401            1 : void libspdm_test_responder_certificate_case8(void **state)
     402              : {
     403              :     libspdm_return_t status;
     404              :     libspdm_test_context_t *spdm_test_context;
     405              :     libspdm_context_t *spdm_context;
     406              :     size_t response_size;
     407              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     408              :     spdm_certificate_response_t *spdm_response;
     409              :     spdm_error_response_t *spdm_responseError;
     410              :     void *data;
     411              :     size_t data_size;
     412              : 
     413              :     /* Testing offsets at the boundary of maximum integer values and at the boundary of certificate length (first three positions)*/
     414            1 :     uint16_t test_offsets[] = { (uint16_t)(-1),
     415              :                                 0,
     416              :                                 +1,
     417              :                                 0,
     418              :                                 0x7F,
     419              :                                 (uint16_t)(0x7F + 1),
     420              :                                 0xFF,
     421              :                                 0x7FFF,
     422              :                                 (uint16_t)(0x7FFF + 1),
     423              :                                 0xFFFF,
     424              :                                 (uint16_t)(-1) };
     425              : 
     426              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     427            1 :     spdm_test_context = *state;
     428            1 :     spdm_context = spdm_test_context->spdm_context;
     429            1 :     spdm_test_context->case_id = 0x8;
     430            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     431              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     432            1 :     spdm_context->connection_info.connection_state =
     433              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     434            1 :     spdm_context->local_context.capability.flags |=
     435              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     436            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     437              :         m_libspdm_use_hash_algo;
     438            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     439              :                                                     m_libspdm_use_asym_algo, &data,
     440              :                                                     &data_size, NULL, NULL);
     441            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     442            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     443              :         data_size;
     444              : 
     445              :     /* This tests considers only length = 1, other tests vary length value*/
     446            1 :     m_libspdm_get_certificate_request3.length = 1;
     447              :     /* Setting up offset values at the boundary of certificate length*/
     448            1 :     test_offsets[0] = (uint16_t)(test_offsets[0] + data_size);
     449            1 :     test_offsets[1] = (uint16_t)(test_offsets[1] + data_size);
     450            1 :     test_offsets[2] = (uint16_t)(test_offsets[2] + data_size);
     451              : 
     452           12 :     for (int i = 0; i < sizeof(test_offsets) / sizeof(test_offsets[0]); i++) {
     453              :         TEST_LIBSPDM_DEBUG_PRINT("i:%d test_offsets[i]:%u\n", i, test_offsets[i]);
     454           11 :         m_libspdm_get_certificate_request3.offset = test_offsets[i];
     455              : 
     456              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     457           11 :         libspdm_reset_message_b(spdm_context);
     458           11 :         response_size = sizeof(response);
     459           11 :         status = libspdm_get_response_certificate(
     460              :             spdm_context, m_libspdm_get_certificate_request3_size,
     461              :             &m_libspdm_get_certificate_request3, &response_size,
     462              :             response);
     463           11 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     464              : 
     465           11 :         if (m_libspdm_get_certificate_request3.offset >= data_size) {
     466              :             /* A too long of an offset should return an error*/
     467            6 :             spdm_responseError = (void *)response;
     468            6 :             assert_int_equal(
     469              :                 spdm_responseError->header.request_response_code,
     470              :                 SPDM_ERROR);
     471            6 :             assert_int_equal(spdm_responseError->header.param1,
     472              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     473              :         } else {
     474              :             /* Otherwise it should work properly, considering length = 1*/
     475            5 :             assert_int_equal(response_size,
     476              :                              sizeof(spdm_certificate_response_t) + 1);
     477            5 :             spdm_response = (void *)response;
     478            5 :             assert_int_equal(
     479              :                 spdm_response->header.request_response_code,
     480              :                 SPDM_CERTIFICATE);
     481            5 :             assert_int_equal(spdm_response->header.param1, 0);
     482            5 :             assert_int_equal(spdm_response->portion_length, 1);
     483            5 :             assert_int_equal(
     484              :                 spdm_response->remainder_length + 1,
     485              :                 (uint16_t)(
     486              :                     data_size -
     487              :                     m_libspdm_get_certificate_request3.offset));
     488              :         }
     489              :     }
     490            1 :     free(data);
     491            1 : }
     492              : 
     493              : /**
     494              :  * Test 9: request offset and length at the boundary of maximum integer values
     495              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     496              :  **/
     497            1 : void libspdm_test_responder_certificate_case9(void **state)
     498              : {
     499              :     libspdm_return_t status;
     500              :     libspdm_test_context_t *spdm_test_context;
     501              :     libspdm_context_t *spdm_context;
     502              :     size_t response_size;
     503              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     504              :     spdm_certificate_response_t *spdm_response;
     505              :     spdm_error_response_t *spdm_responseError;
     506              :     void *data;
     507              :     size_t data_size;
     508              : 
     509              :     /* Testing offsets and length combinations
     510              :      * Check at the boundary of maximum integer values and at the boundary of certificate length*/
     511            1 :     uint16_t test_sizes[] = {
     512              :         (uint16_t)(-1),
     513              :         0,
     514              :         +1, /* reserved for sizes around the certificate chain size*/
     515              :         (uint16_t)(-1),
     516              :         +1,
     517              :         (uint16_t)(0x7F - 1),
     518              :         0x7F,
     519              :         (uint16_t)(0x7F + 1),
     520              :         (uint16_t)(0xFF - 1),
     521              :         0xFF,
     522              :         (uint16_t)(0x7FFF - 1),
     523              :         0x7FFF,
     524              :         (uint16_t)(0x7FFF + 1),
     525              :         (uint16_t)(0xFFFF - 1),
     526              :         0xFFFF
     527              :     };
     528              :     uint16_t expected_chunk_size;
     529              :     uint16_t expected_remainder;
     530              : 
     531              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     532            1 :     spdm_test_context = *state;
     533            1 :     spdm_context = spdm_test_context->spdm_context;
     534            1 :     spdm_test_context->case_id = 0x9;
     535            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     536              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     537            1 :     spdm_context->connection_info.connection_state =
     538              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     539            1 :     spdm_context->local_context.capability.flags |=
     540              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     541            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     542              :         m_libspdm_use_hash_algo;
     543            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     544              :                                                     m_libspdm_use_asym_algo, &data,
     545              :                                                     &data_size, NULL, NULL);
     546            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     547            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     548              :         data_size;
     549              : 
     550              :     /* Setting up offset values at the boundary of certificate length*/
     551            1 :     test_sizes[0] += (uint16_t)(test_sizes[0] + data_size);
     552            1 :     test_sizes[1] += (uint16_t)(test_sizes[1] + data_size);
     553            1 :     test_sizes[2] += (uint16_t)(test_sizes[2] + data_size);
     554              : 
     555           16 :     for (int i = 0; i < sizeof(test_sizes) / sizeof(test_sizes[0]); i++) {
     556              :         TEST_LIBSPDM_DEBUG_PRINT("i:%d test_sizes[i]=length:%u\n", i,
     557              :                                  test_sizes[i]);
     558           15 :         m_libspdm_get_certificate_request3.length = test_sizes[i];
     559          240 :         for (int j = 0; j < sizeof(test_sizes) / sizeof(test_sizes[0]);
     560          225 :              j++) {
     561              :             TEST_LIBSPDM_DEBUG_PRINT("\tj:%d test_sizes[j]=offset:%u\n", j,
     562              :                                      test_sizes[j]);
     563          225 :             m_libspdm_get_certificate_request3.offset = test_sizes[j];
     564              : 
     565              :             /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     566          225 :             libspdm_reset_message_b(spdm_context);
     567          225 :             response_size = sizeof(response);
     568          225 :             status = libspdm_get_response_certificate(
     569              :                 spdm_context,
     570              :                 m_libspdm_get_certificate_request3_size,
     571              :                 &m_libspdm_get_certificate_request3,
     572              :                 &response_size, response);
     573          225 :             assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     574              : 
     575          225 :             if (m_libspdm_get_certificate_request3.offset >=
     576              :                 data_size) {
     577              :                 /* A too long of an offset should return an error*/
     578          120 :                 spdm_responseError = (void *)response;
     579          120 :                 assert_int_equal(spdm_responseError->header
     580              :                                  .request_response_code,
     581              :                                  SPDM_ERROR);
     582          120 :                 assert_int_equal(
     583              :                     spdm_responseError->header.param1,
     584              :                     SPDM_ERROR_CODE_INVALID_REQUEST);
     585              :             } else {
     586              :                 /* Otherwise it should work properly*/
     587              : 
     588              :                 /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     589          105 :                 expected_chunk_size = (uint16_t)(LIBSPDM_MIN(
     590              :                                                      m_libspdm_get_certificate_request3.length,
     591              :                                                      data_size -
     592              :                                                      m_libspdm_get_certificate_request3
     593              :                                                      .offset));
     594          105 :                 expected_chunk_size =
     595              :                     LIBSPDM_MIN(expected_chunk_size,
     596              :                                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     597              :                 /* Expected certificate length left*/
     598          105 :                 expected_remainder = (uint16_t)(
     599          105 :                     data_size -
     600          105 :                     m_libspdm_get_certificate_request3.offset -
     601              :                     expected_chunk_size);
     602              : 
     603          105 :                 assert_int_equal(
     604              :                     response_size,
     605              :                     sizeof(spdm_certificate_response_t) +
     606              :                     expected_chunk_size);
     607          105 :                 spdm_response = (void *)response;
     608          105 :                 assert_int_equal(spdm_response->header
     609              :                                  .request_response_code,
     610              :                                  SPDM_CERTIFICATE);
     611          105 :                 assert_int_equal(spdm_response->header.param1,
     612              :                                  0);
     613          105 :                 assert_int_equal(spdm_response->portion_length,
     614              :                                  expected_chunk_size);
     615          105 :                 assert_int_equal(
     616              :                     spdm_response->remainder_length,
     617              :                     expected_remainder);
     618              :             }
     619              :         }
     620              :     }
     621            1 :     free(data);
     622            1 : }
     623              : 
     624              : /**
     625              :  * Test 10: request LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of long certificate chains, with the largest valid offset
     626              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     627              :  **/
     628            1 : void libspdm_test_responder_certificate_case10(void **state)
     629              : {
     630              :     libspdm_return_t status;
     631              :     libspdm_test_context_t *spdm_test_context;
     632              :     libspdm_context_t *spdm_context;
     633              :     size_t response_size;
     634              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     635              :     spdm_certificate_response_t *spdm_response;
     636              :     spdm_error_response_t *spdm_responseError;
     637              :     void *data;
     638              :     size_t data_size;
     639              : 
     640            1 :     uint16_t test_cases[] = { LIBSPDM_TEST_CERT_MAXINT16, LIBSPDM_TEST_CERT_MAXUINT16 };
     641              : 
     642              :     size_t expected_chunk_size;
     643              :     size_t expected_remainder;
     644              : 
     645              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     646            1 :     spdm_test_context = *state;
     647            1 :     spdm_context = spdm_test_context->spdm_context;
     648            1 :     spdm_test_context->case_id = 0xA;
     649            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     650              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     651            1 :     spdm_context->connection_info.connection_state =
     652              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     653            1 :     spdm_context->local_context.capability.flags |=
     654              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     655            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     656              :         m_libspdm_use_hash_algo;
     657              : 
     658            1 :     m_libspdm_get_certificate_request3.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     659              : 
     660            3 :     for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
     661            2 :         libspdm_read_responder_public_certificate_chain_by_size(
     662              :             /*MAXUINT16_CERT signature_algo is SHA256RSA */
     663              :             m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
     664            2 :             test_cases[i], &data, &data_size, NULL, NULL);
     665              : 
     666            2 :         spdm_context->local_context.local_cert_chain_provision[0] =
     667              :             data;
     668            2 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     669              :             data_size;
     670              : 
     671            2 :         m_libspdm_get_certificate_request3.offset =
     672            2 :             (uint16_t)(LIBSPDM_MIN(data_size - 1, 0xFFFF));
     673              :         TEST_LIBSPDM_DEBUG_PRINT("data_size: %u\n", data_size);
     674              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.offset: %u\n",
     675              :                                  m_libspdm_get_certificate_request3.offset);
     676              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.length: %u\n",
     677              :                                  m_libspdm_get_certificate_request3.length);
     678              :         TEST_LIBSPDM_DEBUG_PRINT(
     679              :             "offset + length: %u\n",
     680              :             m_libspdm_get_certificate_request3.offset +
     681              :             m_libspdm_get_certificate_request3.length);
     682              : 
     683              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     684            2 :         libspdm_reset_message_b(spdm_context);
     685            2 :         response_size = sizeof(response);
     686            2 :         status = libspdm_get_response_certificate(
     687              :             spdm_context, m_libspdm_get_certificate_request3_size,
     688              :             &m_libspdm_get_certificate_request3, &response_size,
     689              :             response);
     690            2 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     691              : 
     692              :         /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     693            2 :         expected_chunk_size = (uint16_t)(LIBSPDM_MIN(
     694              :                                              m_libspdm_get_certificate_request3.length,
     695              :                                              data_size -
     696              :                                              m_libspdm_get_certificate_request3.offset));
     697            2 :         expected_chunk_size =
     698              :             LIBSPDM_MIN(expected_chunk_size, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     699              :         /* Expected certificate length left*/
     700            2 :         expected_remainder = (uint16_t)(
     701            2 :             data_size - m_libspdm_get_certificate_request3.offset -
     702              :             expected_chunk_size);
     703              : 
     704              :         TEST_LIBSPDM_DEBUG_PRINT("expected_chunk_size %u\n", expected_chunk_size);
     705              :         TEST_LIBSPDM_DEBUG_PRINT("expected_remainder %u\n", expected_remainder);
     706              : 
     707            2 :         if (expected_remainder > 0xFFFF ||
     708              :             expected_chunk_size > 0xFFFF) {
     709            0 :             spdm_responseError = (void *)response;
     710            0 :             assert_int_equal(
     711              :                 spdm_responseError->header.request_response_code,
     712              :                 SPDM_ERROR);
     713            0 :             assert_int_equal(spdm_responseError->header.param1,
     714              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     715              :         } else {
     716            2 :             assert_int_equal(response_size,
     717              :                              sizeof(spdm_certificate_response_t) +
     718              :                              expected_chunk_size);
     719            2 :             spdm_response = (void *)response;
     720            2 :             assert_int_equal(
     721              :                 spdm_response->header.request_response_code,
     722              :                 SPDM_CERTIFICATE);
     723            2 :             assert_int_equal(spdm_response->header.param1, 0);
     724            2 :             assert_int_equal(spdm_response->portion_length,
     725              :                              expected_chunk_size);
     726            2 :             assert_int_equal(spdm_response->remainder_length,
     727              :                              expected_remainder);
     728              :         }
     729              : 
     730              :         TEST_LIBSPDM_DEBUG_PRINT("\n");
     731              : 
     732            2 :         spdm_context->local_context.local_cert_chain_provision[0] =
     733              :             NULL;
     734            2 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     735              :             0;
     736            2 :         free(data);
     737              :     }
     738            1 : }
     739              : 
     740              : /**
     741              :  * Test 11: request LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of a short certificate chain (fits in 1 message)
     742              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     743              :  **/
     744            1 : void libspdm_test_responder_certificate_case11(void **state)
     745              : {
     746              :     libspdm_return_t status;
     747              :     libspdm_test_context_t *spdm_test_context;
     748              :     libspdm_context_t *spdm_context;
     749              :     size_t response_size;
     750              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     751              :     spdm_certificate_response_t *spdm_response;
     752              :     spdm_error_response_t *spdm_responseError;
     753              :     void *data;
     754              :     size_t data_size;
     755              : 
     756            1 :     uint16_t test_cases[] = { LIBSPDM_TEST_CERT_SMALL };
     757              : 
     758              :     size_t expected_chunk_size;
     759              :     size_t expected_remainder;
     760              : 
     761              :     /* This case requires a short certificate chain (fits in 1 message) for testing,
     762              :      * so skip when m_libspdm_use_asym_algo is other than ECC_P256 */
     763            1 :     if (m_libspdm_use_asym_algo !=
     764              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256) {
     765            0 :         return;
     766              :     }
     767              : 
     768              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     769            1 :     spdm_test_context = *state;
     770            1 :     spdm_context = spdm_test_context->spdm_context;
     771            1 :     spdm_test_context->case_id = 0xB;
     772            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     773              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     774            1 :     spdm_context->connection_info.connection_state =
     775              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     776            1 :     spdm_context->local_context.capability.flags |=
     777              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     778            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     779              :         m_libspdm_use_hash_algo;
     780              : 
     781            1 :     m_libspdm_get_certificate_request3.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     782            1 :     m_libspdm_get_certificate_request3.offset = 0;
     783              : 
     784            2 :     for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
     785            1 :         libspdm_read_responder_public_certificate_chain_by_size(
     786            1 :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, test_cases[i], &data,
     787              :             &data_size, NULL, NULL);
     788            1 :         spdm_context->local_context.local_cert_chain_provision[0] =
     789              :             data;
     790            1 :         spdm_context->local_context.local_cert_chain_provision_size[0] =
     791              :             data_size;
     792              : 
     793              :         TEST_LIBSPDM_DEBUG_PRINT("data_size: %u\n", data_size);
     794              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.offset: %u\n",
     795              :                                  m_libspdm_get_certificate_request3.offset);
     796              :         TEST_LIBSPDM_DEBUG_PRINT("m_libspdm_get_certificate_request3.length: %u\n",
     797              :                                  m_libspdm_get_certificate_request3.length);
     798              :         TEST_LIBSPDM_DEBUG_PRINT(
     799              :             "offset + length: %u\n",
     800              :             m_libspdm_get_certificate_request3.offset +
     801              :             m_libspdm_get_certificate_request3.length);
     802              : 
     803              :         /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     804            1 :         libspdm_reset_message_b(spdm_context);
     805            1 :         response_size = sizeof(response);
     806            1 :         status = libspdm_get_response_certificate(
     807              :             spdm_context, m_libspdm_get_certificate_request3_size,
     808              :             &m_libspdm_get_certificate_request3, &response_size,
     809              :             response);
     810            1 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     811              : 
     812              :         /* Expected received length is limited by LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN and by the remaining length*/
     813            1 :         expected_chunk_size =
     814            1 :             LIBSPDM_MIN(m_libspdm_get_certificate_request3.length,
     815              :                         data_size - m_libspdm_get_certificate_request3.offset);
     816            1 :         expected_chunk_size =
     817              :             LIBSPDM_MIN(expected_chunk_size, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
     818              :         /* Expected certificate length left*/
     819            1 :         expected_remainder = data_size -
     820            1 :                              m_libspdm_get_certificate_request3.offset -
     821              :                              expected_chunk_size;
     822              : 
     823              :         TEST_LIBSPDM_DEBUG_PRINT("expected_chunk_size %u\n", expected_chunk_size);
     824              :         TEST_LIBSPDM_DEBUG_PRINT("expected_remainder %u\n", expected_remainder);
     825              : 
     826            1 :         if (expected_remainder > 0xFFFF ||
     827              :             expected_chunk_size > 0xFFFF) {
     828            0 :             spdm_responseError = (void *)response;
     829            0 :             assert_int_equal(
     830              :                 spdm_responseError->header.request_response_code,
     831              :                 SPDM_ERROR);
     832            0 :             assert_int_equal(spdm_responseError->header.param1,
     833              :                              SPDM_ERROR_CODE_INVALID_REQUEST);
     834              :         } else {
     835            1 :             assert_int_equal(response_size,
     836              :                              sizeof(spdm_certificate_response_t) +
     837              :                              expected_chunk_size);
     838            1 :             spdm_response = (void *)response;
     839            1 :             assert_int_equal(
     840              :                 spdm_response->header.request_response_code,
     841              :                 SPDM_CERTIFICATE);
     842            1 :             assert_int_equal(spdm_response->header.param1, 0);
     843            1 :             assert_int_equal(spdm_response->portion_length,
     844              :                              expected_chunk_size);
     845            1 :             assert_int_equal(spdm_response->remainder_length,
     846              :                              expected_remainder);
     847              :         }
     848              : 
     849              :         TEST_LIBSPDM_DEBUG_PRINT("\n");
     850              : 
     851            1 :         free(data);
     852              :     }
     853              : }
     854              : 
     855              : /**
     856              :  * Test 12: request a whole certificate chain byte by byte
     857              :  * Expected Behavior: generate correctly formed Certificate messages, including its portion_length and remainder_length fields
     858              :  **/
     859            1 : void libspdm_test_responder_certificate_case12(void **state)
     860              : {
     861              :     libspdm_return_t status;
     862              :     libspdm_test_context_t *spdm_test_context;
     863              :     libspdm_context_t *spdm_context;
     864              :     size_t response_size;
     865              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     866              :     spdm_certificate_response_t *spdm_response;
     867              :     void *data;
     868              :     size_t data_size;
     869              :     uint16_t expected_chunk_size;
     870              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     871              :     size_t count;
     872              : #endif
     873              :     /* Setting up the spdm_context and loading a sample certificate chain*/
     874            1 :     spdm_test_context = *state;
     875            1 :     spdm_context = spdm_test_context->spdm_context;
     876            1 :     spdm_test_context->case_id = 0xC;
     877            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
     878              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     879            1 :     spdm_context->connection_info.connection_state =
     880              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     881            1 :     spdm_context->local_context.capability.flags |=
     882              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     883            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     884              :         m_libspdm_use_hash_algo;
     885            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     886              :                                                     m_libspdm_use_asym_algo, &data,
     887              :                                                     &data_size, NULL, NULL);
     888            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     889            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
     890              :         data_size;
     891              : 
     892              :     /* This tests considers only length = 1*/
     893            1 :     m_libspdm_get_certificate_request3.length = 1;
     894            1 :     expected_chunk_size = 1;
     895              : 
     896              : 
     897              :     /* resetting an internal buffer to avoid overflow and prevent tests to succeed*/
     898            1 :     libspdm_reset_message_b(spdm_context);
     899              : 
     900            1 :     spdm_response = NULL;
     901         1391 :     for (size_t offset = 0; offset < data_size; offset++) {
     902              :         TEST_LIBSPDM_DEBUG_PRINT("offset:%u \n", offset);
     903         1390 :         m_libspdm_get_certificate_request3.offset = (uint16_t)offset;
     904              : 
     905         1390 :         response_size = sizeof(response);
     906         1390 :         status = libspdm_get_response_certificate(
     907              :             spdm_context, m_libspdm_get_certificate_request3_size,
     908              :             &m_libspdm_get_certificate_request3, &response_size,
     909              :             response);
     910         1390 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     911         1390 :         spdm_response = (void *)response;
     912              :         /* It may fail because the spdm does not support too many messages.
     913              :          * assert_int_equal (spdm_response->header.request_response_code, SPDM_CERTIFICATE);*/
     914         1390 :         if (spdm_response->header.request_response_code ==
     915              :             SPDM_CERTIFICATE) {
     916         1390 :             assert_int_equal(
     917              :                 spdm_response->header.request_response_code,
     918              :                 SPDM_CERTIFICATE);
     919         1390 :             assert_int_equal(response_size,
     920              :                              sizeof(spdm_certificate_response_t) +
     921              :                              expected_chunk_size);
     922         1390 :             assert_int_equal(spdm_response->header.param1, 0);
     923         1390 :             assert_int_equal(spdm_response->portion_length,
     924              :                              expected_chunk_size);
     925         1390 :             assert_int_equal(spdm_response->remainder_length,
     926              :                              data_size - offset -
     927              :                              expected_chunk_size);
     928         1390 :             assert_int_equal(
     929              :                 ((uint8_t *)data)[offset],
     930              :                 (response +
     931              :                  sizeof(spdm_certificate_response_t))[0]);
     932              :         } else {
     933            0 :             assert_int_equal(
     934              :                 spdm_response->header.request_response_code,
     935              :                 SPDM_ERROR);
     936            0 :             break;
     937              :         }
     938              :     }
     939            1 :     if (spdm_response != NULL) {
     940            1 :         if (spdm_response->header.request_response_code ==
     941              :             SPDM_CERTIFICATE) {
     942              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     943              :             count = (data_size + m_libspdm_get_certificate_request3.length - 1) /
     944              :                     m_libspdm_get_certificate_request3.length;
     945              :             assert_int_equal(
     946              :                 spdm_context->transcript.message_b.buffer_size,
     947              :                 sizeof(spdm_get_certificate_request_t) * count +
     948              :                 sizeof(spdm_certificate_response_t) *
     949              :                 count +
     950              :                 data_size);
     951              : #endif
     952              :         }
     953              :     }
     954            1 :     free(data);
     955            1 : }
     956              : 
     957              : /**
     958              :  * Test 13: receiving a correct GET_CERTIFICATE from the requester. Buffer B
     959              :  * already has arbitrary data.
     960              :  * Expected behavior: the responder accepts the request and produces a valid
     961              :  * CERTIFICATE response message, and buffer B receives the exchanged
     962              :  * GET_CERTIFICATE and CERTIFICATE messages.
     963              :  **/
     964            1 : void libspdm_test_responder_certificate_case13(void **state)
     965              : {
     966              :     libspdm_return_t status;
     967              :     libspdm_test_context_t *spdm_test_context;
     968              :     libspdm_context_t *spdm_context;
     969              :     size_t response_size;
     970              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     971              :     spdm_certificate_response_t *spdm_response;
     972              :     void *data;
     973              :     size_t data_size;
     974              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     975              :     size_t arbitrary_size;
     976              : #endif
     977              : 
     978            1 :     spdm_test_context = *state;
     979            1 :     spdm_context = spdm_test_context->spdm_context;
     980            1 :     spdm_test_context->case_id = 0xD;
     981            1 :     spdm_context->connection_info.connection_state =
     982              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
     983            1 :     spdm_context->local_context.capability.flags |=
     984              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
     985            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     986            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
     987              :                                                     m_libspdm_use_asym_algo, &data,
     988              :                                                     &data_size, NULL, NULL);
     989            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
     990            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
     991              : 
     992              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     993              :     /*filling buffer B with arbitrary data*/
     994              :     arbitrary_size = 8;
     995              :     libspdm_set_mem(spdm_context->transcript.message_b.buffer, arbitrary_size, (uint8_t) 0xEE);
     996              :     spdm_context->transcript.message_b.buffer_size = arbitrary_size;
     997              : #endif
     998              : 
     999            1 :     response_size = sizeof(response);
    1000            1 :     status = libspdm_get_response_certificate(
    1001              :         spdm_context, m_libspdm_get_certificate_request1_size,
    1002              :         &m_libspdm_get_certificate_request1, &response_size, response);
    1003            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1004            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
    1005              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1006            1 :     spdm_response = (void *)response;
    1007            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CERTIFICATE);
    1008            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1009            1 :     assert_int_equal(spdm_response->portion_length, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1010            1 :     assert_int_equal(spdm_response->remainder_length,
    1011              :                      data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1012              : 
    1013              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1014              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    1015              :                      arbitrary_size + m_libspdm_get_certificate_request1_size + response_size);
    1016              :     assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size,
    1017              :                         &m_libspdm_get_certificate_request1,
    1018              :                         m_libspdm_get_certificate_request1_size);
    1019              :     assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size +
    1020              :                         m_libspdm_get_certificate_request1_size,
    1021              :                         response, response_size);
    1022              : #endif
    1023              : 
    1024            1 :     free(data);
    1025            1 : }
    1026              : 
    1027              : /**
    1028              :  * Test 14: request the first LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN bytes of the certificate chain in a session
    1029              :  * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
    1030              :  **/
    1031            1 : void libspdm_test_responder_certificate_case14(void **state)
    1032              : {
    1033              :     libspdm_return_t status;
    1034              :     libspdm_test_context_t *spdm_test_context;
    1035              :     libspdm_context_t *spdm_context;
    1036              :     size_t response_size;
    1037              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1038              :     spdm_certificate_response_t *spdm_response;
    1039              :     void *data;
    1040              :     size_t data_size;
    1041              :     libspdm_session_info_t *session_info;
    1042              :     uint32_t session_id;
    1043              : 
    1044            1 :     spdm_test_context = *state;
    1045            1 :     spdm_context = spdm_test_context->spdm_context;
    1046            1 :     spdm_test_context->case_id = 0xE;
    1047            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1048              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1049            1 :     spdm_context->connection_info.connection_state =
    1050              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1051            1 :     spdm_context->local_context.capability.flags |=
    1052              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1053            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1054              :         m_libspdm_use_hash_algo;
    1055              : 
    1056            1 :     session_id = 0xFFFFFFFF;
    1057            1 :     spdm_context->latest_session_id = session_id;
    1058            1 :     spdm_context->last_spdm_request_session_id_valid = true;
    1059            1 :     spdm_context->last_spdm_request_session_id = session_id;
    1060            1 :     session_info = &spdm_context->session_info[0];
    1061            1 :     libspdm_session_info_init(spdm_context, session_info, session_id, true);
    1062            1 :     libspdm_secured_message_set_session_state(
    1063              :         session_info->secured_message_context,
    1064              :         LIBSPDM_SESSION_STATE_ESTABLISHED);
    1065              : 
    1066            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1067              :                                                     m_libspdm_use_asym_algo, &data,
    1068              :                                                     &data_size, NULL, NULL);
    1069            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1070            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1071              :         data_size;
    1072              : 
    1073              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1074              :     session_info->session_transcript.message_m.buffer_size =
    1075              :         session_info->session_transcript.message_m.max_buffer_size;
    1076              : #endif
    1077              : 
    1078            1 :     response_size = sizeof(response);
    1079            1 :     status = libspdm_get_response_certificate(
    1080              :         spdm_context, m_libspdm_get_certificate_request1_size,
    1081              :         &m_libspdm_get_certificate_request1, &response_size, response);
    1082            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1083            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t) +
    1084              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1085            1 :     spdm_response = (void *)response;
    1086            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1087              :                      SPDM_CERTIFICATE);
    1088            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1089            1 :     assert_int_equal(spdm_response->portion_length,
    1090              :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1091            1 :     assert_int_equal(spdm_response->remainder_length,
    1092              :                      data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
    1093              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1094              :     assert_int_equal(session_info->session_transcript.message_m.buffer_size,
    1095              :                      0);
    1096              : #endif
    1097            1 :     free(data);
    1098            1 : }
    1099              : 
    1100              : /**
    1101              :  * Test 15: Produce a CERTIFICATE response that is meant to be chunked.
    1102              :  *          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN is ignored when chunking is enabled.
    1103              :  **/
    1104            1 : void libspdm_test_responder_certificate_case15(void **state)
    1105              : {
    1106              :     libspdm_return_t status;
    1107              :     bool ret;
    1108              :     libspdm_test_context_t *spdm_test_context;
    1109              :     libspdm_context_t *spdm_context;
    1110              :     size_t response_size;
    1111              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1112              :     uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1113              :     spdm_get_certificate_request_t *spdm_cert_request;
    1114              :     spdm_certificate_response_t *spdm_cert_response;
    1115              :     void *data;
    1116              :     size_t data_size;
    1117              : 
    1118            1 :     spdm_test_context = *state;
    1119            1 :     spdm_context = spdm_test_context->spdm_context;
    1120            1 :     spdm_test_context->case_id = 15;
    1121            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
    1122              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1123              : 
    1124            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
    1125            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1126            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    1127            1 :     spdm_context->connection_info.capability.flags = 0;
    1128            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
    1129            1 :     spdm_context->connection_info.capability.data_transfer_size =
    1130              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12;
    1131              : 
    1132            1 :     spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1133            1 :     spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    1134            1 :     spdm_context->local_context.capability.data_transfer_size =
    1135              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12;
    1136            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP |
    1137              :                                                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1138              : 
    1139            1 :     ret = libspdm_read_responder_public_certificate_chain(
    1140              :         m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, &data,
    1141              :         &data_size, NULL, NULL);
    1142            1 :     assert_true(ret);
    1143              : 
    1144            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1145            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1146              : 
    1147            1 :     spdm_cert_request = (spdm_get_certificate_request_t *) request;
    1148              : 
    1149            1 :     spdm_cert_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
    1150            1 :     spdm_cert_request->header.request_response_code = SPDM_GET_CERTIFICATE;
    1151            1 :     spdm_cert_request->header.param1 = 0;
    1152            1 :     spdm_cert_request->header.param2 = 0;
    1153            1 :     spdm_cert_request->offset = 0;
    1154            1 :     spdm_cert_request->length = 0xffff;
    1155              : 
    1156            1 :     response_size = sizeof(response);
    1157            1 :     libspdm_zero_mem(response, response_size);
    1158              : 
    1159            1 :     status = libspdm_get_response_certificate(
    1160              :         spdm_context,
    1161              :         sizeof(spdm_get_certificate_request_t), &request,
    1162              :         &response_size, response);
    1163            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1164              : 
    1165            1 :     spdm_cert_response = (spdm_certificate_response_t *) response;
    1166              : 
    1167            1 :     assert_int_equal(spdm_cert_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
    1168            1 :     assert_int_equal(spdm_cert_response->header.request_response_code, SPDM_CERTIFICATE);
    1169            1 :     assert_int_equal(spdm_cert_response->header.param1, 0);
    1170            1 :     assert_int_equal(spdm_cert_response->header.param2, 0);
    1171            1 :     assert_int_equal(spdm_cert_response->portion_length, data_size);
    1172            1 :     assert_int_equal(spdm_cert_response->remainder_length, 0);
    1173              : 
    1174            1 :     free(data);
    1175            1 : }
    1176              : 
    1177              : /**
    1178              :  * Test 16: request a 0 byte certificate chain
    1179              :  * Expected Behavior: portion length should be 0 and remainder length should be the size of the
    1180              :  *                    certificate chain.
    1181              :  **/
    1182            1 : void libspdm_test_responder_certificate_case16(void **state)
    1183              : {
    1184              :     libspdm_return_t status;
    1185              :     libspdm_test_context_t *spdm_test_context;
    1186              :     libspdm_context_t *spdm_context;
    1187              :     size_t response_size;
    1188              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1189              :     spdm_certificate_response_t *spdm_response;
    1190              :     void *data;
    1191              :     size_t data_size;
    1192              : 
    1193            1 :     spdm_test_context = *state;
    1194            1 :     spdm_context = spdm_test_context->spdm_context;
    1195            1 :     spdm_test_context->case_id = 16;
    1196            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1197              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1198            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1199            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1200            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1201            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1202              :                                                     m_libspdm_use_asym_algo, &data,
    1203              :                                                     &data_size, NULL, NULL);
    1204            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1205            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1206              : 
    1207            1 :     m_libspdm_get_certificate_request3.offset = 0;
    1208            1 :     m_libspdm_get_certificate_request3.length = 0;
    1209              : 
    1210            1 :     response_size = sizeof(response);
    1211            1 :     status = libspdm_get_response_certificate(
    1212              :         spdm_context, m_libspdm_get_certificate_request3_size,
    1213              :         &m_libspdm_get_certificate_request3, &response_size, response);
    1214            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1215            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
    1216            1 :     spdm_response = (void *)response;
    1217            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_CERTIFICATE);
    1218            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1219            1 :     assert_int_equal(spdm_response->portion_length, 0);
    1220            1 :     assert_int_equal(spdm_response->remainder_length, data_size);
    1221              : 
    1222            1 :     free(data);
    1223            1 : }
    1224              : 
    1225              : /**
    1226              :  * Test 17: SlotID in GET_CERTIFICATE request message is 9, but it should be between 0 and 7 inclusive.
    1227              :  * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_INVALID_REQUEST.
    1228              :  **/
    1229            1 : void libspdm_test_responder_certificate_case17(void **state)
    1230              : {
    1231              :     libspdm_return_t status;
    1232              :     libspdm_test_context_t *spdm_test_context;
    1233              :     libspdm_context_t *spdm_context;
    1234              :     size_t response_size;
    1235              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1236              :     spdm_certificate_response_t *spdm_response;
    1237              :     void *data;
    1238              :     size_t data_size;
    1239              : 
    1240            1 :     spdm_test_context = *state;
    1241            1 :     spdm_context = spdm_test_context->spdm_context;
    1242            1 :     spdm_test_context->case_id = 17;
    1243            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    1244              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1245            1 :     spdm_context->connection_info.connection_state =
    1246              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1247            1 :     spdm_context->local_context.capability.flags |=
    1248              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1249            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1250              :         m_libspdm_use_hash_algo;
    1251            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1252              :                                                     m_libspdm_use_asym_algo, &data,
    1253              :                                                     &data_size, NULL, NULL);
    1254            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1255            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1256              :         data_size;
    1257              : 
    1258            1 :     response_size = sizeof(response);
    1259            1 :     status = libspdm_get_response_certificate(
    1260              :         spdm_context, m_libspdm_get_certificate_request4_size,
    1261              :         &m_libspdm_get_certificate_request4, &response_size, response);
    1262            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1263            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
    1264            1 :     spdm_response = (void *)response;
    1265            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1266              :                      SPDM_ERROR);
    1267            1 :     assert_int_equal(spdm_response->header.param1,
    1268              :                      SPDM_ERROR_CODE_INVALID_REQUEST);
    1269            1 :     assert_int_equal(spdm_response->header.param2, 0);
    1270            1 :     free(data);
    1271            1 : }
    1272              : 
    1273              : /**
    1274              :  * Test 18: check request attributes and response attributes , SlotSizeRequested=1b the Offset and Length fields in the
    1275              :  * GET_CERTIFICATE request shall be ignored by the Responder
    1276              :  * Expected Behavior: generate a correctly formed Certificate message, including its portion_length and remainder_length fields
    1277              :  **/
    1278            1 : void libspdm_test_responder_certificate_case18(void **state)
    1279              : {
    1280              :     libspdm_return_t status;
    1281              :     libspdm_test_context_t *spdm_test_context;
    1282              :     libspdm_context_t *spdm_context;
    1283              :     size_t response_size;
    1284              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1285              :     spdm_certificate_response_t *spdm_response;
    1286              :     void *data;
    1287              :     size_t data_size;
    1288              : 
    1289            1 :     spdm_test_context = *state;
    1290            1 :     spdm_context = spdm_test_context->spdm_context;
    1291            1 :     spdm_test_context->case_id = 18;
    1292            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
    1293              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1294            1 :     spdm_context->connection_info.connection_state =
    1295              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1296            1 :     spdm_context->local_context.capability.flags |=
    1297              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1298            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    1299              :         m_libspdm_use_hash_algo;
    1300            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1301              :                                                     m_libspdm_use_asym_algo, &data,
    1302              :                                                     &data_size, NULL, NULL);
    1303            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1304            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] =
    1305              :         data_size;
    1306              : 
    1307              :     /* When SlotSizeRequested=1b , the Offset and Length fields in the GET_CERTIFICATE request shall be ignored by the Responder */
    1308            1 :     m_libspdm_get_certificate_request5.header.param2 =
    1309              :         SPDM_GET_CERTIFICATE_REQUEST_ATTRIBUTES_SLOT_SIZE_REQUESTED;
    1310            1 :     m_libspdm_get_certificate_request5.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1311            1 :     m_libspdm_get_certificate_request5.offset = 0xFF;
    1312              : 
    1313            1 :     response_size = sizeof(response);
    1314            1 :     status = libspdm_get_response_certificate(
    1315              :         spdm_context, m_libspdm_get_certificate_request5_size,
    1316              :         &m_libspdm_get_certificate_request5, &response_size, response);
    1317            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1318            1 :     assert_int_equal(response_size, sizeof(spdm_certificate_response_t));
    1319            1 :     spdm_response = (void *)response;
    1320            1 :     assert_int_equal(spdm_response->header.request_response_code,
    1321              :                      SPDM_CERTIFICATE);
    1322            1 :     assert_int_equal(spdm_response->header.param1, 0);
    1323            1 :     assert_int_equal(spdm_response->portion_length,0);
    1324            1 :     assert_int_equal(spdm_response->remainder_length, data_size);
    1325            1 :     free(data);
    1326            1 : }
    1327              : 
    1328              : /**
    1329              :  * Test 19: Attempt to retrieve a certificate chain from a slot that needs to be reset.
    1330              :  * Expected Behavior: Responder responds with ResetRequired.
    1331              :  **/
    1332            1 : void libspdm_test_responder_certificate_case19(void **state)
    1333              : {
    1334              :     libspdm_return_t status;
    1335              :     libspdm_test_context_t *spdm_test_context;
    1336              :     libspdm_context_t *spdm_context;
    1337              :     size_t response_size;
    1338              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
    1339              :     spdm_error_response_t *spdm_response;
    1340              :     void *data;
    1341              :     size_t data_size;
    1342            1 :     const uint8_t slot_id = 5;
    1343              : 
    1344            1 :     spdm_test_context = *state;
    1345            1 :     spdm_context = spdm_test_context->spdm_context;
    1346            1 :     spdm_test_context->case_id = 19;
    1347            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
    1348              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    1349            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    1350            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    1351            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    1352            1 :     libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1353              :                                                     m_libspdm_use_asym_algo, &data,
    1354              :                                                     &data_size, NULL, NULL);
    1355            1 :     spdm_context->local_context.local_cert_chain_provision[0] = data;
    1356            1 :     spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
    1357              : 
    1358              :     /* Responder needs to be reset before certificate can be retrieved from specified SlotID. */
    1359            1 :     m_libspdm_get_certificate_request5.header.param1 = slot_id;
    1360            1 :     spdm_context->local_context.cert_slot_reset_mask = 1 << slot_id;
    1361              : 
    1362            1 :     response_size = sizeof(response);
    1363            1 :     status = libspdm_get_response_certificate(
    1364              :         spdm_context, m_libspdm_get_certificate_request5_size,
    1365              :         &m_libspdm_get_certificate_request5, &response_size, response);
    1366              : 
    1367            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    1368            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
    1369            1 :     spdm_response = (void *)response;
    1370            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
    1371            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
    1372            1 :     assert_int_equal(spdm_response->header.param2, 0);
    1373              : 
    1374            1 :     free(data);
    1375            1 : }
    1376              : 
    1377            1 : int libspdm_responder_certificate_test_main(void)
    1378              : {
    1379            1 :     const struct CMUnitTest spdm_responder_certificate_tests[] = {
    1380              :         /* Success Case*/
    1381              :         cmocka_unit_test(libspdm_test_responder_certificate_case1),
    1382              :         /* Can be populated with new test.*/
    1383              :         cmocka_unit_test(libspdm_test_responder_certificate_case2),
    1384              :         /* response_state: LIBSPDM_RESPONSE_STATE_BUSY*/
    1385              :         cmocka_unit_test(libspdm_test_responder_certificate_case3),
    1386              :         /* response_state: LIBSPDM_RESPONSE_STATE_NEED_RESYNC*/
    1387              :         cmocka_unit_test(libspdm_test_responder_certificate_case4),
    1388              :         #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    1389              :         /* response_state: LIBSPDM_RESPONSE_STATE_NOT_READY*/
    1390              :         cmocka_unit_test(libspdm_test_responder_certificate_case5),
    1391              :         #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
    1392              :         /* connection_state Check*/
    1393              :         cmocka_unit_test(libspdm_test_responder_certificate_case6),
    1394              :         /* Tests varying length*/
    1395              :         cmocka_unit_test(libspdm_test_responder_certificate_case7),
    1396              :         /* Tests varying offset*/
    1397              :         cmocka_unit_test(libspdm_test_responder_certificate_case8),
    1398              :         /* Tests varying length and offset*/
    1399              :         cmocka_unit_test(libspdm_test_responder_certificate_case9),
    1400              :         /* Tests large certificate chains*/
    1401              :         cmocka_unit_test(libspdm_test_responder_certificate_case10),
    1402              :         /* Certificate fits in one single message*/
    1403              :         cmocka_unit_test(libspdm_test_responder_certificate_case11),
    1404              :         /* Requests byte by byte*/
    1405              :         cmocka_unit_test(libspdm_test_responder_certificate_case12),
    1406              :         /* Buffer verification*/
    1407              :         cmocka_unit_test(libspdm_test_responder_certificate_case13),
    1408              :         /* Success Case in a session*/
    1409              :         cmocka_unit_test(libspdm_test_responder_certificate_case14),
    1410              :         /* Produce a CERTIFICATE response that is meant to be chunked. */
    1411              :         cmocka_unit_test(libspdm_test_responder_certificate_case15),
    1412              :         cmocka_unit_test(libspdm_test_responder_certificate_case16),
    1413              :         /* Bad SlotID in request message */
    1414              :         cmocka_unit_test(libspdm_test_responder_certificate_case17),
    1415              :         /* check request attributes and response attributes*/
    1416              :         cmocka_unit_test(libspdm_test_responder_certificate_case18),
    1417              :         cmocka_unit_test(libspdm_test_responder_certificate_case19),
    1418              :     };
    1419              : 
    1420            1 :     libspdm_test_context_t test_context = {
    1421              :         LIBSPDM_TEST_CONTEXT_VERSION,
    1422              :         false,
    1423              :     };
    1424              : 
    1425            1 :     libspdm_setup_test_context(&test_context);
    1426              : 
    1427            1 :     return cmocka_run_group_tests(spdm_responder_certificate_tests,
    1428              :                                   libspdm_unit_test_group_setup,
    1429              :                                   libspdm_unit_test_group_teardown);
    1430              : }
    1431              : 
    1432              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
        

Generated by: LCOV version 2.0-1