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 % 516 507
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 20 20

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

Generated by: LCOV version 2.0-1