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

Generated by: LCOV version 2.0-1