LCOV - code coverage report
Current view: top level - unit_test/test_spdm_requester - get_certificate.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.4 % 2198 2009
Test Date: 2025-10-12 08:10:56 Functions: 100.0 % 35 35

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "spdm_unit_test.h"
       8              : #include "internal/libspdm_requester_lib.h"
       9              : #include "internal/libspdm_secured_message_lib.h"
      10              : 
      11              : #if LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT
      12              : 
      13              : static void *m_libspdm_local_certificate_chain;
      14              : static size_t m_libspdm_local_certificate_chain_size;
      15              : 
      16              : static size_t m_libspdm_local_buffer_size;
      17              : static uint8_t m_libspdm_local_buffer[LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE];
      18              : 
      19              : static bool m_get_cert;
      20              : 
      21              : static uint8_t m_cert_model;
      22              : 
      23              : static uint8_t m_slot_id;
      24              : 
      25              : static size_t m_calling_index;
      26              : 
      27              : 
      28              : /* Loading the target expiration certificate chain and saving root certificate hash
      29              :  * "rsa3072_Expiration/bundle_responder.certchain.der"*/
      30            2 : bool libspdm_libspdm_read_responder_public_certificate_chain_expiration(
      31              :     void **data, size_t *size, void **hash, size_t *hash_size)
      32              : {
      33            2 :     uint32_t base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
      34              :     bool res;
      35              :     void *file_data;
      36              :     size_t file_size;
      37              :     spdm_cert_chain_t *cert_chain;
      38              :     size_t cert_chain_size;
      39              :     char *file;
      40              :     const uint8_t *root_cert;
      41              :     size_t root_cert_len;
      42              :     size_t digest_size;
      43              : 
      44            2 :     *data = NULL;
      45            2 :     *size = 0;
      46            2 :     if (hash != NULL) {
      47            1 :         *hash = NULL;
      48              :     }
      49            2 :     if (hash_size != NULL) {
      50            1 :         *hash_size = 0;
      51              :     }
      52              : 
      53            2 :     file = "rsa3072_Expiration/bundle_responder.certchain.der";
      54            2 :     res = libspdm_read_input_file(file, &file_data, &file_size);
      55            2 :     if (!res) {
      56            0 :         return res;
      57              :     }
      58              : 
      59            2 :     digest_size = libspdm_get_hash_size(base_hash_algo);
      60              : 
      61            2 :     cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + file_size;
      62            2 :     cert_chain = (void *)malloc(cert_chain_size);
      63            2 :     if (cert_chain == NULL) {
      64            0 :         free(file_data);
      65            0 :         return false;
      66              :     }
      67            2 :     cert_chain->length = (uint32_t)cert_chain_size;
      68              : 
      69              :     /* Get Root Certificate and calculate hash value*/
      70              : 
      71            2 :     res = libspdm_x509_get_cert_from_cert_chain(file_data, file_size, 0, &root_cert,
      72              :                                                 &root_cert_len);
      73            2 :     if (!res) {
      74            0 :         free(file_data);
      75            0 :         free(cert_chain);
      76            0 :         return res;
      77              :     }
      78              : 
      79            2 :     libspdm_hash_all(base_hash_algo, root_cert, root_cert_len,
      80            2 :                      (uint8_t *)(cert_chain + 1));
      81            2 :     libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
      82            2 :                      cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
      83              :                      file_data, file_size);
      84              : 
      85            2 :     *data = cert_chain;
      86            2 :     *size = cert_chain_size;
      87            2 :     if (hash != NULL) {
      88            1 :         *hash = (cert_chain + 1);
      89              :     }
      90            2 :     if (hash_size != NULL) {
      91            1 :         *hash_size = digest_size;
      92              :     }
      93              : 
      94            2 :     free(file_data);
      95            2 :     return true;
      96              : }
      97              : 
      98         1469 : static libspdm_return_t send_message(
      99              :     void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
     100              : {
     101              :     libspdm_test_context_t *spdm_test_context;
     102              : 
     103         1469 :     spdm_test_context = libspdm_get_test_context();
     104         1469 :     switch (spdm_test_context->case_id) {
     105            1 :     case 0x1:
     106            1 :         return LIBSPDM_STATUS_SEND_FAIL;
     107            2 :     case 0x2:
     108            2 :         return LIBSPDM_STATUS_SUCCESS;
     109            0 :     case 0x3:
     110            0 :         return LIBSPDM_STATUS_SUCCESS;
     111            1 :     case 0x4:
     112            1 :         return LIBSPDM_STATUS_SUCCESS;
     113            1 :     case 0x5:
     114            1 :         return LIBSPDM_STATUS_SUCCESS;
     115            3 :     case 0x6:
     116            3 :         return LIBSPDM_STATUS_SUCCESS;
     117            1 :     case 0x7:
     118            1 :         return LIBSPDM_STATUS_SUCCESS;
     119            2 :     case 0x8:
     120            2 :         return LIBSPDM_STATUS_SUCCESS;
     121            3 :     case 0x9:
     122            3 :         return LIBSPDM_STATUS_SUCCESS;
     123            2 :     case 0xA:
     124            2 :         return LIBSPDM_STATUS_SUCCESS;
     125            2 :     case 0xB:
     126            2 :         return LIBSPDM_STATUS_SUCCESS;
     127            2 :     case 0xC:
     128            2 :         return LIBSPDM_STATUS_SUCCESS;
     129            1 :     case 0xD:
     130            1 :         return LIBSPDM_STATUS_SUCCESS;
     131         1390 :     case 0xE:
     132         1390 :         return LIBSPDM_STATUS_SUCCESS;
     133            2 :     case 0xF:
     134            2 :         return LIBSPDM_STATUS_SUCCESS;
     135           18 :     case 0x10:
     136           18 :         return LIBSPDM_STATUS_SUCCESS;
     137            1 :     case 0x11:
     138            1 :         return LIBSPDM_STATUS_SUCCESS;
     139            1 :     case 0x12:
     140            1 :         return LIBSPDM_STATUS_SUCCESS;
     141            4 :     case 0x13:
     142            4 :         return LIBSPDM_STATUS_SUCCESS;
     143            1 :     case 0x14:
     144            1 :         return LIBSPDM_STATUS_SUCCESS;
     145            1 :     case 0x15:
     146            1 :         return LIBSPDM_STATUS_SUCCESS;
     147            2 :     case 0x16:
     148            2 :         return LIBSPDM_STATUS_SUCCESS;
     149            2 :     case 0x17: {
     150              :         static uint16_t req_cnt = 0;
     151            2 :         const uint8_t *ptr = (const uint8_t *)request;
     152              : 
     153            2 :         if(req_cnt == 0) {
     154            1 :             m_libspdm_local_buffer_size = 0;
     155              :         }
     156            2 :         libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
     157              :                          sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
     158            2 :                          &ptr[1], request_size - 1);
     159            2 :         m_libspdm_local_buffer_size += (request_size - 1);
     160              : 
     161            2 :         req_cnt++;
     162              :     }
     163            2 :         return LIBSPDM_STATUS_SUCCESS;
     164            2 :     case 0x18:
     165            2 :         return LIBSPDM_STATUS_SUCCESS;
     166            6 :     case 0x19: {
     167              :         const uint8_t *ptr;
     168              : 
     169            6 :         ptr = (const uint8_t *)request;
     170            6 :         m_libspdm_local_buffer_size = 0;
     171            6 :         libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer), &ptr[1],
     172              :                          request_size - 1);
     173            6 :         m_libspdm_local_buffer_size += (request_size - 1);
     174              :     }
     175            6 :         return LIBSPDM_STATUS_SUCCESS;
     176            2 :     case 0x1A:
     177            2 :         return LIBSPDM_STATUS_SUCCESS;
     178            1 :     case 0x1B:
     179            1 :         return LIBSPDM_STATUS_SUCCESS;
     180            2 :     case 0x1C:
     181            2 :         return LIBSPDM_STATUS_SUCCESS;
     182           13 :     case 0x1D:
     183              :     case 0x1E:
     184              :     case 0x1F:
     185           13 :         return LIBSPDM_STATUS_SUCCESS;
     186            0 :     default:
     187            0 :         return LIBSPDM_STATUS_SEND_FAIL;
     188              :     }
     189              : }
     190              : 
     191         1468 : static libspdm_return_t receive_message(
     192              :     void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
     193              : {
     194              :     libspdm_test_context_t *spdm_test_context;
     195              : 
     196         1468 :     spdm_test_context = libspdm_get_test_context();
     197         1468 :     switch (spdm_test_context->case_id) {
     198            0 :     case 0x1:
     199            0 :         return LIBSPDM_STATUS_RECEIVE_FAIL;
     200              : 
     201            2 :     case 0x2: {
     202              :         spdm_certificate_response_t *spdm_response;
     203              :         size_t spdm_response_size;
     204              :         size_t transport_header_size;
     205              :         uint16_t portion_length;
     206              :         uint16_t remainder_length;
     207              :         size_t count;
     208              :         static size_t calling_index = 0;
     209              : 
     210            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     211            1 :             libspdm_read_responder_public_certificate_chain(
     212              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     213              :                 &m_libspdm_local_certificate_chain,
     214              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     215              :         }
     216            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     217            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     218              :         }
     219            2 :         count = (m_libspdm_local_certificate_chain_size +
     220            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     221              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     222            2 :         if (calling_index != count - 1) {
     223            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     224            1 :             remainder_length =
     225            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     226              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     227            1 :                            (calling_index + 1));
     228              :         } else {
     229            1 :             portion_length = (uint16_t)(
     230              :                 m_libspdm_local_certificate_chain_size -
     231            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     232            1 :             remainder_length = 0;
     233              :         }
     234              : 
     235            2 :         spdm_response_size =
     236            2 :             sizeof(spdm_certificate_response_t) + portion_length;
     237            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     238            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     239              : 
     240            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     241            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     242            2 :         spdm_response->header.param1 = 0;
     243            2 :         spdm_response->header.param2 = 0;
     244            2 :         spdm_response->portion_length = portion_length;
     245            2 :         spdm_response->remainder_length = remainder_length;
     246            2 :         libspdm_copy_mem(spdm_response + 1,
     247            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     248            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     249            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     250              :                          portion_length);
     251              : 
     252            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     253              :                                               false, spdm_response_size,
     254              :                                               spdm_response, response_size,
     255              :                                               response);
     256              : 
     257            2 :         calling_index++;
     258            2 :         if (calling_index == count) {
     259            1 :             calling_index = 0;
     260            1 :             free(m_libspdm_local_certificate_chain);
     261            1 :             m_libspdm_local_certificate_chain = NULL;
     262            1 :             m_libspdm_local_certificate_chain_size = 0;
     263              :         }
     264              :     }
     265            2 :         return LIBSPDM_STATUS_SUCCESS;
     266              : 
     267            0 :     case 0x3: {
     268              :         spdm_certificate_response_t *spdm_response;
     269              :         size_t spdm_response_size;
     270              :         size_t transport_header_size;
     271              :         uint16_t portion_length;
     272              :         uint16_t remainder_length;
     273              :         size_t count;
     274              :         static size_t calling_index = 0;
     275              : 
     276            0 :         if (m_libspdm_local_certificate_chain == NULL) {
     277            0 :             libspdm_read_responder_public_certificate_chain(
     278              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     279              :                 &m_libspdm_local_certificate_chain,
     280              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     281              :         }
     282            0 :         if (m_libspdm_local_certificate_chain == NULL) {
     283            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     284              :         }
     285            0 :         count = (m_libspdm_local_certificate_chain_size +
     286            0 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     287              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     288            0 :         if (calling_index != count - 1) {
     289            0 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     290            0 :             remainder_length =
     291            0 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     292              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     293            0 :                            (calling_index + 1));
     294              :         } else {
     295            0 :             portion_length = (uint16_t)(
     296              :                 m_libspdm_local_certificate_chain_size -
     297            0 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     298            0 :             remainder_length = 0;
     299              :         }
     300              : 
     301            0 :         spdm_response_size =
     302            0 :             sizeof(spdm_certificate_response_t) + portion_length;
     303            0 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     304            0 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     305              : 
     306            0 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     307            0 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     308            0 :         spdm_response->header.param1 = 0;
     309            0 :         spdm_response->header.param2 = 0;
     310            0 :         spdm_response->portion_length = portion_length;
     311            0 :         spdm_response->remainder_length = remainder_length;
     312            0 :         libspdm_copy_mem(spdm_response + 1,
     313            0 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     314            0 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     315            0 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     316              :                          portion_length);
     317              : 
     318            0 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     319              :                                               false, spdm_response_size,
     320              :                                               spdm_response, response_size,
     321              :                                               response);
     322              : 
     323            0 :         calling_index++;
     324            0 :         if (calling_index == count) {
     325            0 :             calling_index = 0;
     326            0 :             free(m_libspdm_local_certificate_chain);
     327            0 :             m_libspdm_local_certificate_chain = NULL;
     328            0 :             m_libspdm_local_certificate_chain_size = 0;
     329              :         }
     330              :     }
     331            0 :         return LIBSPDM_STATUS_SUCCESS;
     332              : 
     333            1 :     case 0x4: {
     334              :         spdm_error_response_t *spdm_response;
     335              :         size_t spdm_response_size;
     336              :         size_t transport_header_size;
     337              : 
     338            1 :         spdm_response_size = sizeof(spdm_error_response_t);
     339            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     340            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     341              : 
     342            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     343            1 :         spdm_response->header.request_response_code = SPDM_ERROR;
     344            1 :         spdm_response->header.param1 = SPDM_ERROR_CODE_INVALID_REQUEST;
     345            1 :         spdm_response->header.param2 = 0;
     346              : 
     347            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     348              :                                               false, spdm_response_size,
     349              :                                               spdm_response,
     350              :                                               response_size, response);
     351              :     }
     352            1 :         return LIBSPDM_STATUS_SUCCESS;
     353              : 
     354            1 :     case 0x5: {
     355              :         spdm_error_response_t *spdm_response;
     356              :         size_t spdm_response_size;
     357              :         size_t transport_header_size;
     358              : 
     359            1 :         spdm_response_size = sizeof(spdm_error_response_t);
     360            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     361            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     362              : 
     363            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     364            1 :         spdm_response->header.request_response_code = SPDM_ERROR;
     365            1 :         spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
     366            1 :         spdm_response->header.param2 = 0;
     367              : 
     368            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     369              :                                               false, spdm_response_size,
     370              :                                               spdm_response,
     371              :                                               response_size, response);
     372              :     }
     373            1 :         return LIBSPDM_STATUS_SUCCESS;
     374              : 
     375            3 :     case 0x6: {
     376              :         static size_t sub_index1 = 0;
     377            3 :         if (sub_index1 == 0) {
     378              :             spdm_error_response_t *spdm_response;
     379              :             size_t spdm_response_size;
     380              :             size_t transport_header_size;
     381              : 
     382            1 :             spdm_response_size = sizeof(spdm_error_response_t);
     383            1 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     384            1 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     385              : 
     386            1 :             spdm_response->header.spdm_version =
     387              :                 SPDM_MESSAGE_VERSION_10;
     388            1 :             spdm_response->header.request_response_code = SPDM_ERROR;
     389            1 :             spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
     390            1 :             spdm_response->header.param2 = 0;
     391            1 :             sub_index1++;
     392              : 
     393            1 :             libspdm_transport_test_encode_message(
     394              :                 spdm_context, NULL, false, false,
     395              :                 spdm_response_size, spdm_response,
     396              :                 response_size, response);
     397            2 :         } else if (sub_index1 == 1) {
     398              :             spdm_certificate_response_t *spdm_response;
     399              :             size_t spdm_response_size;
     400              :             size_t transport_header_size;
     401              :             uint16_t portion_length;
     402              :             uint16_t remainder_length;
     403              :             size_t count;
     404              :             static size_t calling_index = 0;
     405              : 
     406            2 :             if (m_libspdm_local_certificate_chain == NULL) {
     407            1 :                 libspdm_read_responder_public_certificate_chain(
     408              :                     m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     409              :                     &m_libspdm_local_certificate_chain,
     410              :                     &m_libspdm_local_certificate_chain_size, NULL,
     411              :                     NULL);
     412              :             }
     413            2 :             if (m_libspdm_local_certificate_chain == NULL) {
     414            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
     415              :             }
     416            2 :             count = (m_libspdm_local_certificate_chain_size +
     417            2 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     418              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     419            2 :             if (calling_index != count - 1) {
     420            1 :                 portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     421            1 :                 remainder_length = (uint16_t)(
     422              :                     m_libspdm_local_certificate_chain_size -
     423              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     424            1 :                     (calling_index + 1));
     425              :             } else {
     426            1 :                 portion_length = (uint16_t)(
     427              :                     m_libspdm_local_certificate_chain_size -
     428              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     429            1 :                     (count - 1));
     430            1 :                 remainder_length = 0;
     431              :             }
     432              : 
     433            2 :             spdm_response_size = sizeof(spdm_certificate_response_t) +
     434              :                                  portion_length;
     435            2 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     436            2 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     437              : 
     438            2 :             spdm_response->header.spdm_version =
     439              :                 SPDM_MESSAGE_VERSION_10;
     440            2 :             spdm_response->header.request_response_code =
     441              :                 SPDM_CERTIFICATE;
     442            2 :             spdm_response->header.param1 = 0;
     443            2 :             spdm_response->header.param2 = 0;
     444            2 :             spdm_response->portion_length = portion_length;
     445            2 :             spdm_response->remainder_length = remainder_length;
     446            2 :             libspdm_copy_mem(spdm_response + 1,
     447            2 :                              (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     448            2 :                              (uint8_t *)m_libspdm_local_certificate_chain +
     449            2 :                              LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     450              :                              calling_index,
     451              :                              portion_length);
     452              : 
     453            2 :             libspdm_transport_test_encode_message(
     454              :                 spdm_context, NULL, false, false, spdm_response_size,
     455              :                 spdm_response, response_size, response);
     456              : 
     457            2 :             calling_index++;
     458            2 :             if (calling_index == count) {
     459            1 :                 calling_index = 0;
     460            1 :                 free(m_libspdm_local_certificate_chain);
     461            1 :                 m_libspdm_local_certificate_chain = NULL;
     462            1 :                 m_libspdm_local_certificate_chain_size = 0;
     463              :             }
     464              :         }
     465              :     }
     466            3 :         return LIBSPDM_STATUS_SUCCESS;
     467              : 
     468            1 :     case 0x7: {
     469              :         spdm_error_response_t *spdm_response;
     470              :         size_t spdm_response_size;
     471              :         size_t transport_header_size;
     472              : 
     473            1 :         spdm_response_size = sizeof(spdm_error_response_t);
     474            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     475            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     476              : 
     477            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     478            1 :         spdm_response->header.request_response_code = SPDM_ERROR;
     479            1 :         spdm_response->header.param1 = SPDM_ERROR_CODE_REQUEST_RESYNCH;
     480            1 :         spdm_response->header.param2 = 0;
     481              : 
     482            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     483              :                                               false, spdm_response_size,
     484              :                                               spdm_response,
     485              :                                               response_size, response);
     486              :     }
     487            1 :         return LIBSPDM_STATUS_SUCCESS;
     488              : 
     489            2 :     case 0x8: {
     490              :         spdm_error_response_data_response_not_ready_t *spdm_response;
     491              :         size_t spdm_response_size;
     492              :         size_t transport_header_size;
     493              : 
     494            2 :         spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
     495            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     496            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     497              : 
     498            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     499            2 :         spdm_response->header.request_response_code = SPDM_ERROR;
     500            2 :         spdm_response->header.param1 =
     501              :             SPDM_ERROR_CODE_RESPONSE_NOT_READY;
     502            2 :         spdm_response->header.param2 = 0;
     503            2 :         spdm_response->extend_error_data.rd_exponent = 1;
     504            2 :         spdm_response->extend_error_data.rd_tm = 2;
     505            2 :         spdm_response->extend_error_data.request_code =
     506              :             SPDM_GET_CERTIFICATE;
     507            2 :         spdm_response->extend_error_data.token = 0;
     508              : 
     509            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     510              :                                               false, spdm_response_size,
     511              :                                               spdm_response,
     512              :                                               response_size, response);
     513              :     }
     514            2 :         return LIBSPDM_STATUS_SUCCESS;
     515              : 
     516            3 :     case 0x9: {
     517              :         static size_t sub_index2 = 0;
     518            3 :         if (sub_index2 == 0) {
     519              :             spdm_error_response_data_response_not_ready_t
     520              :             *spdm_response;
     521              :             size_t spdm_response_size;
     522              :             size_t transport_header_size;
     523              : 
     524            1 :             spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
     525            1 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     526            1 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     527              : 
     528            1 :             spdm_response->header.spdm_version =
     529              :                 SPDM_MESSAGE_VERSION_10;
     530            1 :             spdm_response->header.request_response_code = SPDM_ERROR;
     531            1 :             spdm_response->header.param1 =
     532              :                 SPDM_ERROR_CODE_RESPONSE_NOT_READY;
     533            1 :             spdm_response->header.param2 = 0;
     534            1 :             spdm_response->extend_error_data.rd_exponent = 1;
     535            1 :             spdm_response->extend_error_data.rd_tm = 2;
     536            1 :             spdm_response->extend_error_data.request_code =
     537              :                 SPDM_GET_CERTIFICATE;
     538            1 :             spdm_response->extend_error_data.token = 1;
     539            1 :             sub_index2++;
     540              : 
     541            1 :             libspdm_transport_test_encode_message(
     542              :                 spdm_context, NULL, false, false,
     543              :                 spdm_response_size, spdm_response,
     544              :                 response_size, response);
     545            2 :         } else if (sub_index2 == 1) {
     546              :             spdm_certificate_response_t *spdm_response;
     547              :             size_t spdm_response_size;
     548              :             size_t transport_header_size;
     549              :             uint16_t portion_length;
     550              :             uint16_t remainder_length;
     551              :             size_t count;
     552              :             static size_t calling_index = 0;
     553              : 
     554            2 :             if (m_libspdm_local_certificate_chain == NULL) {
     555            1 :                 libspdm_read_responder_public_certificate_chain(
     556              :                     m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     557              :                     &m_libspdm_local_certificate_chain,
     558              :                     &m_libspdm_local_certificate_chain_size, NULL,
     559              :                     NULL);
     560              :             }
     561            2 :             if (m_libspdm_local_certificate_chain == NULL) {
     562            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
     563              :             }
     564            2 :             count = (m_libspdm_local_certificate_chain_size +
     565            2 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     566              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     567            2 :             if (calling_index != count - 1) {
     568            1 :                 portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     569            1 :                 remainder_length = (uint16_t)(
     570              :                     m_libspdm_local_certificate_chain_size -
     571              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     572            1 :                     (calling_index + 1));
     573              :             } else {
     574            1 :                 portion_length = (uint16_t)(
     575              :                     m_libspdm_local_certificate_chain_size -
     576              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     577            1 :                     (count - 1));
     578            1 :                 remainder_length = 0;
     579              :             }
     580              : 
     581            2 :             spdm_response_size = sizeof(spdm_certificate_response_t) +
     582              :                                  portion_length;
     583            2 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     584            2 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     585              : 
     586            2 :             spdm_response->header.spdm_version =
     587              :                 SPDM_MESSAGE_VERSION_10;
     588            2 :             spdm_response->header.request_response_code =
     589              :                 SPDM_CERTIFICATE;
     590            2 :             spdm_response->header.param1 = 0;
     591            2 :             spdm_response->header.param2 = 0;
     592            2 :             spdm_response->portion_length = portion_length;
     593            2 :             spdm_response->remainder_length = remainder_length;
     594            2 :             libspdm_copy_mem(spdm_response + 1,
     595            2 :                              (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     596            2 :                              (uint8_t *)m_libspdm_local_certificate_chain +
     597            2 :                              LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     598              :                              calling_index,
     599              :                              portion_length);
     600              : 
     601            2 :             libspdm_transport_test_encode_message(
     602              :                 spdm_context, NULL, false, false, spdm_response_size,
     603              :                 spdm_response, response_size, response);
     604              : 
     605            2 :             calling_index++;
     606            2 :             if (calling_index == count) {
     607            1 :                 calling_index = 0;
     608            1 :                 free(m_libspdm_local_certificate_chain);
     609            1 :                 m_libspdm_local_certificate_chain = NULL;
     610            1 :                 m_libspdm_local_certificate_chain_size = 0;
     611              :             }
     612              :         }
     613              :     }
     614            3 :         return LIBSPDM_STATUS_SUCCESS;
     615              : 
     616            2 :     case 0xA: {
     617              :         spdm_certificate_response_t *spdm_response;
     618              :         size_t spdm_response_size;
     619              :         size_t transport_header_size;
     620              :         uint16_t portion_length;
     621              :         uint16_t remainder_length;
     622              :         size_t count;
     623              :         static size_t calling_index = 0;
     624              : 
     625            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     626            1 :             libspdm_read_responder_public_certificate_chain(
     627              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     628              :                 &m_libspdm_local_certificate_chain,
     629              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     630              :         }
     631            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     632            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     633              :         }
     634            2 :         count = (m_libspdm_local_certificate_chain_size +
     635            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     636              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     637            2 :         if (calling_index != count - 1) {
     638            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     639            1 :             remainder_length =
     640            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     641              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     642            1 :                            (calling_index + 1));
     643              :         } else {
     644            1 :             portion_length = (uint16_t)(
     645              :                 m_libspdm_local_certificate_chain_size -
     646            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     647            1 :             remainder_length = 0;
     648              :         }
     649              : 
     650            2 :         spdm_response_size =
     651            2 :             sizeof(spdm_certificate_response_t) + portion_length;
     652            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     653            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     654              : 
     655            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     656            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     657            2 :         spdm_response->header.param1 = 0;
     658            2 :         spdm_response->header.param2 = 0;
     659            2 :         spdm_response->portion_length = portion_length;
     660            2 :         spdm_response->remainder_length = remainder_length;
     661            2 :         libspdm_copy_mem(spdm_response + 1,
     662            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     663            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     664            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     665              :                          portion_length);
     666              : 
     667            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     668              :                                               false, spdm_response_size,
     669              :                                               spdm_response, response_size,
     670              :                                               response);
     671              : 
     672            2 :         calling_index++;
     673            2 :         if (calling_index == count) {
     674            1 :             calling_index = 0;
     675            1 :             free(m_libspdm_local_certificate_chain);
     676            1 :             m_libspdm_local_certificate_chain = NULL;
     677            1 :             m_libspdm_local_certificate_chain_size = 0;
     678              :         }
     679              :     }
     680            2 :         return LIBSPDM_STATUS_SUCCESS;
     681              : 
     682            2 :     case 0xB: {
     683              :         spdm_certificate_response_t *spdm_response;
     684              :         size_t spdm_response_size;
     685              :         size_t transport_header_size;
     686              :         uint16_t portion_length;
     687              :         uint16_t remainder_length;
     688              :         size_t count;
     689              :         static size_t calling_index = 0;
     690              : 
     691              :         const uint8_t *leaf_cert_buffer;
     692              :         size_t leaf_cert_buffer_size;
     693              :         uint8_t *cert_buffer;
     694              :         size_t cert_buffer_size;
     695              :         size_t hash_size;
     696              : 
     697            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     698            1 :             libspdm_read_responder_public_certificate_chain(
     699              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     700              :                 &m_libspdm_local_certificate_chain,
     701              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     702            1 :             if (m_libspdm_local_certificate_chain == NULL) {
     703            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
     704              :             }
     705              : 
     706              :             /* load certificate*/
     707            1 :             hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
     708            1 :             cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
     709            1 :                           sizeof(spdm_cert_chain_t) + hash_size;
     710            1 :             cert_buffer_size = m_libspdm_local_certificate_chain_size -
     711            1 :                                sizeof(spdm_cert_chain_t) -
     712              :                                hash_size;
     713            1 :             if (!libspdm_x509_get_cert_from_cert_chain(
     714              :                     cert_buffer, cert_buffer_size, -1,
     715              :                     &leaf_cert_buffer,
     716              :                     &leaf_cert_buffer_size)) {
     717            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     718              :                                "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
     719            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
     720              :             }
     721              :             /* tamper certificate signature on purpose
     722              :              * arbitrarily change the last byte of the certificate signature*/
     723            1 :             cert_buffer[cert_buffer_size - 1]++;
     724              :         }
     725            2 :         count = (m_libspdm_local_certificate_chain_size +
     726            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     727              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     728            2 :         if (calling_index != count - 1) {
     729            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     730            1 :             remainder_length =
     731            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     732              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     733            1 :                            (calling_index + 1));
     734              :         } else {
     735            1 :             portion_length = (uint16_t)(
     736              :                 m_libspdm_local_certificate_chain_size -
     737            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     738            1 :             remainder_length = 0;
     739              :         }
     740              : 
     741            2 :         spdm_response_size =
     742            2 :             sizeof(spdm_certificate_response_t) + portion_length;
     743            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     744            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     745              : 
     746            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     747            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     748            2 :         spdm_response->header.param1 = 0;
     749            2 :         spdm_response->header.param2 = 0;
     750            2 :         spdm_response->portion_length = portion_length;
     751            2 :         spdm_response->remainder_length = remainder_length;
     752            2 :         libspdm_copy_mem(spdm_response + 1,
     753            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     754            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     755            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     756              :                          portion_length);
     757              : 
     758            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     759              :                                               false, spdm_response_size,
     760              :                                               spdm_response, response_size,
     761              :                                               response);
     762              : 
     763            2 :         calling_index++;
     764            2 :         if (calling_index == count) {
     765            1 :             calling_index = 0;
     766            1 :             free(m_libspdm_local_certificate_chain);
     767            1 :             m_libspdm_local_certificate_chain = NULL;
     768            1 :             m_libspdm_local_certificate_chain_size = 0;
     769              :         }
     770              :     }
     771            2 :         return LIBSPDM_STATUS_SUCCESS;
     772              : 
     773            2 :     case 0xC: {
     774              :         spdm_certificate_response_t *spdm_response;
     775              :         size_t spdm_response_size;
     776              :         size_t transport_header_size;
     777              :         uint16_t portion_length;
     778              :         uint16_t remainder_length;
     779              :         size_t count;
     780              :         static size_t calling_index = 0;
     781              : 
     782            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     783            1 :             libspdm_read_responder_public_certificate_chain(
     784              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     785              :                 &m_libspdm_local_certificate_chain,
     786              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     787              :         }
     788            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     789            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     790              :         }
     791            2 :         count = (m_libspdm_local_certificate_chain_size +
     792            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     793              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     794            2 :         if (calling_index != count - 1) {
     795            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     796            1 :             remainder_length =
     797            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     798              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     799            1 :                            (calling_index + 1));
     800              :         } else {
     801            1 :             portion_length = (uint16_t)(
     802              :                 m_libspdm_local_certificate_chain_size -
     803            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     804            1 :             remainder_length = 0;
     805              :         }
     806              : 
     807            2 :         spdm_response_size =
     808            2 :             sizeof(spdm_certificate_response_t) + portion_length;
     809            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     810            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     811              : 
     812            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     813            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     814            2 :         spdm_response->header.param1 = 0;
     815            2 :         spdm_response->header.param2 = 0;
     816            2 :         spdm_response->portion_length = portion_length;
     817            2 :         spdm_response->remainder_length = remainder_length;
     818            2 :         libspdm_copy_mem(spdm_response + 1,
     819            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     820            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     821            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     822              :                          portion_length);
     823              : 
     824            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     825              :                                               false, spdm_response_size,
     826              :                                               spdm_response, response_size,
     827              :                                               response);
     828              : 
     829            2 :         calling_index++;
     830            2 :         if (calling_index == count) {
     831            1 :             calling_index = 0;
     832            1 :             free(m_libspdm_local_certificate_chain);
     833            1 :             m_libspdm_local_certificate_chain = NULL;
     834            1 :             m_libspdm_local_certificate_chain_size = 0;
     835              :         }
     836              :     }
     837            2 :         return LIBSPDM_STATUS_SUCCESS;
     838              : 
     839            1 :     case 0xD: {
     840              :         spdm_certificate_response_t *spdm_response;
     841              :         size_t spdm_response_size;
     842              :         size_t transport_header_size;
     843              :         uint16_t portion_length;
     844              :         uint16_t remainder_length;
     845              :         size_t count;
     846              :         static size_t calling_index = 0;
     847              : 
     848            1 :         if (m_libspdm_local_certificate_chain == NULL) {
     849            1 :             libspdm_read_responder_public_certificate_chain_by_size(
     850              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     851              :                 LIBSPDM_TEST_CERT_SMALL, &m_libspdm_local_certificate_chain,
     852              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     853              :         }
     854            1 :         if (m_libspdm_local_certificate_chain == NULL) {
     855            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     856              :         }
     857            1 :         count = (m_libspdm_local_certificate_chain_size +
     858            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     859              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     860            1 :         if (calling_index != count - 1) {
     861            0 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     862            0 :             remainder_length =
     863            0 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     864              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
     865            0 :                            (calling_index + 1));
     866              :         } else {
     867            1 :             portion_length = (uint16_t)(
     868              :                 m_libspdm_local_certificate_chain_size -
     869            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
     870            1 :             remainder_length = 0;
     871              :         }
     872              : 
     873            1 :         spdm_response_size =
     874            1 :             sizeof(spdm_certificate_response_t) + portion_length;
     875            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     876            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     877              : 
     878            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     879            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     880            1 :         spdm_response->header.param1 = 0;
     881            1 :         spdm_response->header.param2 = 0;
     882            1 :         spdm_response->portion_length = portion_length;
     883            1 :         spdm_response->remainder_length = remainder_length;
     884            1 :         libspdm_copy_mem(spdm_response + 1,
     885            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     886            1 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     887            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
     888              :                          portion_length);
     889              : 
     890            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     891              :                                               false, spdm_response_size,
     892              :                                               spdm_response, response_size,
     893              :                                               response);
     894              : 
     895            1 :         calling_index++;
     896            1 :         if (calling_index == count) {
     897            1 :             calling_index = 0;
     898            1 :             free(m_libspdm_local_certificate_chain);
     899            1 :             m_libspdm_local_certificate_chain = NULL;
     900            1 :             m_libspdm_local_certificate_chain_size = 0;
     901              :         }
     902              :     }
     903            1 :         return LIBSPDM_STATUS_SUCCESS;
     904              : 
     905         1390 :     case 0xE: {
     906              :         spdm_certificate_response_t *spdm_response;
     907              :         size_t spdm_response_size;
     908              :         size_t transport_header_size;
     909              :         uint16_t portion_length;
     910              :         uint16_t remainder_length;
     911              :         uint16_t get_cert_length;
     912              :         size_t count;
     913              :         static size_t calling_index = 0;
     914              : 
     915              :         /* this should match the value on the test function*/
     916         1390 :         get_cert_length = 1;
     917              : 
     918         1390 :         if (m_libspdm_local_certificate_chain == NULL) {
     919            1 :             libspdm_read_responder_public_certificate_chain(
     920              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
     921              :                 &m_libspdm_local_certificate_chain,
     922              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     923              :         }
     924         1390 :         if (m_libspdm_local_certificate_chain == NULL) {
     925            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     926              :         }
     927         1390 :         count = (m_libspdm_local_certificate_chain_size + get_cert_length + 1) /
     928              :                 get_cert_length;
     929         1390 :         if (calling_index != count - 1) {
     930         1390 :             portion_length = get_cert_length;
     931         1390 :             remainder_length =
     932         1390 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     933         1390 :                            get_cert_length * (calling_index + 1));
     934              :         } else {
     935            0 :             portion_length =
     936            0 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
     937            0 :                            get_cert_length * (count - 1));
     938            0 :             remainder_length = 0;
     939              :         }
     940              : 
     941         1390 :         spdm_response_size =
     942         1390 :             sizeof(spdm_certificate_response_t) + portion_length;
     943         1390 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
     944         1390 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
     945              : 
     946         1390 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
     947         1390 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
     948         1390 :         spdm_response->header.param1 = 0;
     949         1390 :         spdm_response->header.param2 = 0;
     950         1390 :         spdm_response->portion_length = portion_length;
     951         1390 :         spdm_response->remainder_length = remainder_length;
     952         1390 :         libspdm_copy_mem(spdm_response + 1,
     953         1390 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
     954         1390 :                          (uint8_t *)m_libspdm_local_certificate_chain +
     955         1390 :                          get_cert_length * calling_index,
     956              :                          portion_length);
     957              : 
     958         1390 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
     959              :                                               false, spdm_response_size,
     960              :                                               spdm_response, response_size,
     961              :                                               response);
     962              : 
     963         1390 :         calling_index++;
     964         1390 :         if (calling_index == count) {
     965            0 :             calling_index = 0;
     966            0 :             free(m_libspdm_local_certificate_chain);
     967            0 :             m_libspdm_local_certificate_chain = NULL;
     968            0 :             m_libspdm_local_certificate_chain_size = 0;
     969              :         }
     970              :     }
     971         1390 :         return LIBSPDM_STATUS_SUCCESS;
     972              : 
     973            2 :     case 0xF: {
     974              :         spdm_certificate_response_t *spdm_response;
     975              :         size_t spdm_response_size;
     976              :         size_t transport_header_size;
     977              :         uint16_t portion_length;
     978              :         uint16_t remainder_length;
     979              :         size_t count;
     980              :         static size_t calling_index = 0;
     981              : 
     982            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     983            0 :             libspdm_read_responder_public_certificate_chain_by_size(
     984              :                 m_libspdm_use_hash_algo,
     985              :                 /*MAXUINT16_CERT signature_algo is SHA256RSA */
     986              :                 SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
     987              :                 LIBSPDM_TEST_CERT_MAXUINT16, &m_libspdm_local_certificate_chain,
     988              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
     989              :         }
     990            2 :         if (m_libspdm_local_certificate_chain == NULL) {
     991            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
     992              :         }
     993            2 :         count = (m_libspdm_local_certificate_chain_size +
     994            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
     995              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     996            2 :         if (calling_index != count - 1) {
     997            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
     998            1 :             remainder_length =
     999            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1000              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1001            1 :                            (calling_index + 1));
    1002              :         } else {
    1003            1 :             portion_length = (uint16_t)(
    1004              :                 m_libspdm_local_certificate_chain_size -
    1005            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1006            1 :             remainder_length = 0;
    1007              :         }
    1008              : 
    1009            2 :         spdm_response_size =
    1010            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    1011            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1012            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1013              : 
    1014            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1015            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1016            2 :         spdm_response->header.param1 = 0;
    1017            2 :         spdm_response->header.param2 = 0;
    1018            2 :         spdm_response->portion_length = portion_length;
    1019            2 :         spdm_response->remainder_length = remainder_length;
    1020            2 :         libspdm_copy_mem(spdm_response + 1,
    1021            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1022            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1023            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1024              :                          portion_length);
    1025              : 
    1026            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1027              :                                               false, spdm_response_size,
    1028              :                                               spdm_response, response_size,
    1029              :                                               response);
    1030              : 
    1031            2 :         calling_index++;
    1032            2 :         if (calling_index == count) {
    1033            1 :             calling_index = 0;
    1034            1 :             free(m_libspdm_local_certificate_chain);
    1035            1 :             m_libspdm_local_certificate_chain = NULL;
    1036            1 :             m_libspdm_local_certificate_chain_size = 0;
    1037              :         }
    1038              :     }
    1039            2 :         return LIBSPDM_STATUS_SUCCESS;
    1040              : 
    1041           18 :     case 0x10:
    1042              :     {
    1043              :         static uint16_t error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
    1044              : 
    1045              :         spdm_error_response_t *spdm_response;
    1046              :         size_t spdm_response_size;
    1047              :         size_t transport_header_size;
    1048              : 
    1049           18 :         spdm_response_size = sizeof(spdm_error_response_t);
    1050           18 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1051           18 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1052              : 
    1053           18 :         if(error_code <= 0xff) {
    1054           18 :             libspdm_zero_mem (spdm_response, spdm_response_size);
    1055           18 :             spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
    1056           18 :             spdm_response->header.request_response_code = SPDM_ERROR;
    1057           18 :             spdm_response->header.param1 = (uint8_t) error_code;
    1058           18 :             spdm_response->header.param2 = 0;
    1059              : 
    1060           18 :             libspdm_transport_test_encode_message (spdm_context, NULL, false, false,
    1061              :                                                    spdm_response_size, spdm_response,
    1062              :                                                    response_size, response);
    1063              :         }
    1064              : 
    1065           18 :         error_code++;
    1066           18 :         if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
    1067            1 :             error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
    1068              :         }
    1069           18 :         if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
    1070            1 :             error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
    1071              :         }
    1072           18 :         if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
    1073            1 :             error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
    1074              :         }
    1075              :     }
    1076           18 :         return LIBSPDM_STATUS_SUCCESS;
    1077              : 
    1078            1 :     case 0x11: {
    1079              :         spdm_certificate_response_t *spdm_response;
    1080              :         size_t spdm_response_size;
    1081              :         size_t transport_header_size;
    1082              :         uint16_t portion_length;
    1083              :         uint16_t remainder_length;
    1084              :         size_t count;
    1085              :         static size_t calling_index = 0;
    1086              : 
    1087              :         const uint8_t *leaf_cert_buffer;
    1088              :         size_t leaf_cert_buffer_size;
    1089              :         uint8_t *cert_buffer;
    1090              :         size_t cert_buffer_size;
    1091              :         size_t hash_size;
    1092              :         uint8_t cert_chain_without_root[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    1093              :         size_t cert_chain_without_root_size;
    1094              :         void *root_cert_data;
    1095              :         size_t root_cert_size;
    1096              : 
    1097            1 :         root_cert_size = 0;
    1098            1 :         cert_buffer_size = 0;
    1099            1 :         hash_size = 0;
    1100              : 
    1101            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1102            1 :             libspdm_read_responder_public_certificate_chain(
    1103              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1104              :                 &m_libspdm_local_certificate_chain,
    1105              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1106            1 :             if (m_libspdm_local_certificate_chain == NULL) {
    1107            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
    1108              :             }
    1109              :         }
    1110              : 
    1111              :         /* read root certificate size*/
    1112            1 :         libspdm_read_responder_root_public_certificate(
    1113              :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1114              :             &root_cert_data,
    1115              :             &root_cert_size, NULL, NULL);
    1116              :         /* load certificate*/
    1117            1 :         hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
    1118            1 :         root_cert_size = root_cert_size - sizeof(spdm_cert_chain_t) - hash_size;
    1119            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root_cert_size %zu \n", root_cert_size));
    1120            1 :         cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
    1121            1 :                       sizeof(spdm_cert_chain_t) + hash_size + root_cert_size;
    1122            1 :         cert_buffer_size = m_libspdm_local_certificate_chain_size -
    1123            1 :                            sizeof(spdm_cert_chain_t) -
    1124            1 :                            hash_size - root_cert_size;
    1125              : 
    1126            1 :         if (!libspdm_x509_get_cert_from_cert_chain(
    1127              :                 cert_buffer, cert_buffer_size, -1,
    1128              :                 &leaf_cert_buffer,
    1129              :                 &leaf_cert_buffer_size)) {
    1130            0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1131              :                            "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
    1132            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1133              :         }
    1134              : 
    1135            1 :         libspdm_copy_mem(cert_chain_without_root,
    1136              :                          sizeof(cert_chain_without_root),
    1137              :                          m_libspdm_local_certificate_chain,
    1138              :                          sizeof(spdm_cert_chain_t) + hash_size);
    1139            1 :         libspdm_copy_mem(cert_chain_without_root + sizeof(spdm_cert_chain_t) + hash_size,
    1140              :                          sizeof(cert_chain_without_root) - (sizeof(spdm_cert_chain_t) + hash_size),
    1141              :                          cert_buffer,
    1142              :                          cert_buffer_size);
    1143            1 :         cert_chain_without_root_size = m_libspdm_local_certificate_chain_size - root_cert_size;
    1144            1 :         ((spdm_cert_chain_t *)cert_chain_without_root)->length =
    1145            1 :             (uint16_t)cert_chain_without_root_size;
    1146            1 :         count = (cert_chain_without_root_size +
    1147            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1148              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1149            1 :         if (calling_index != count - 1) {
    1150            0 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1151            0 :             remainder_length =
    1152            0 :                 (uint16_t)(cert_chain_without_root_size -
    1153              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1154            0 :                            (calling_index + 1));
    1155              :         } else {
    1156            1 :             portion_length = (uint16_t)(
    1157              :                 cert_chain_without_root_size -
    1158            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1159            1 :             remainder_length = 0;
    1160              :         }
    1161              : 
    1162            1 :         spdm_response_size =
    1163            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    1164            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1165            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1166              : 
    1167            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1168            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1169            1 :         spdm_response->header.param1 = 0;
    1170            1 :         spdm_response->header.param2 = 0;
    1171            1 :         spdm_response->portion_length = portion_length;
    1172            1 :         spdm_response->remainder_length = remainder_length;
    1173              :         /* send certchain without root*/
    1174            1 :         libspdm_copy_mem(spdm_response + 1,
    1175            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1176              :                          (uint8_t *)cert_chain_without_root +
    1177            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1178              :                          portion_length);
    1179              : 
    1180            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1181              :                                               false, spdm_response_size,
    1182              :                                               spdm_response, response_size,
    1183              :                                               response);
    1184              : 
    1185            1 :         calling_index++;
    1186            1 :         if (calling_index == count) {
    1187            1 :             calling_index = 0;
    1188            1 :             free(m_libspdm_local_certificate_chain);
    1189            1 :             m_libspdm_local_certificate_chain = NULL;
    1190            1 :             m_libspdm_local_certificate_chain_size = 0;
    1191              :         }
    1192              : 
    1193            1 :         free(root_cert_data);
    1194              :     }
    1195            1 :         return LIBSPDM_STATUS_SUCCESS;
    1196              : 
    1197            1 :     case 0x12: {
    1198              :         spdm_certificate_response_t *spdm_response;
    1199              :         size_t spdm_response_size;
    1200              :         size_t transport_header_size;
    1201              :         uint16_t portion_length;
    1202              :         uint16_t remainder_length;
    1203              :         size_t count;
    1204              :         static size_t calling_index = 0;
    1205              : 
    1206              :         const uint8_t *leaf_cert_buffer;
    1207              :         size_t leaf_cert_buffer_size;
    1208              :         uint8_t *cert_buffer;
    1209              :         size_t cert_buffer_size;
    1210              :         size_t hash_size;
    1211              :         uint8_t cert_chain_without_root[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    1212              :         size_t cert_chain_without_root_size;
    1213              :         void *root_cert_data;
    1214              :         size_t root_cert_size;
    1215              : 
    1216            1 :         root_cert_size = 0;
    1217            1 :         cert_buffer_size = 0;
    1218            1 :         hash_size = 0;
    1219              : 
    1220            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1221            1 :             libspdm_read_responder_public_certificate_chain(
    1222              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1223              :                 &m_libspdm_local_certificate_chain,
    1224              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1225            1 :             if (m_libspdm_local_certificate_chain == NULL) {
    1226            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
    1227              :             }
    1228              :         }
    1229              : 
    1230              :         /* read root certificate size*/
    1231            1 :         libspdm_read_responder_root_public_certificate(
    1232              :             m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1233              :             &root_cert_data,
    1234              :             &root_cert_size, NULL, NULL);
    1235              :         /* load certificate*/
    1236            1 :         hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
    1237            1 :         root_cert_size = root_cert_size - sizeof(spdm_cert_chain_t) - hash_size;
    1238            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root_cert_size %zu \n", root_cert_size));
    1239            1 :         cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
    1240            1 :                       sizeof(spdm_cert_chain_t) + hash_size + root_cert_size;
    1241            1 :         cert_buffer_size = m_libspdm_local_certificate_chain_size -
    1242            1 :                            sizeof(spdm_cert_chain_t) -
    1243            1 :                            hash_size - root_cert_size;
    1244              : 
    1245            1 :         if (!libspdm_x509_get_cert_from_cert_chain(
    1246              :                 cert_buffer, cert_buffer_size, -1,
    1247              :                 &leaf_cert_buffer,
    1248              :                 &leaf_cert_buffer_size)) {
    1249            0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
    1250              :                            "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
    1251            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1252              :         }
    1253              :         /* tamper certificate signature on purpose
    1254              :          * arbitrarily change the last byte of the certificate signature*/
    1255            1 :         cert_buffer[cert_buffer_size - 1]++;
    1256              : 
    1257            1 :         libspdm_copy_mem(cert_chain_without_root,
    1258              :                          sizeof(cert_chain_without_root),
    1259              :                          m_libspdm_local_certificate_chain,
    1260              :                          sizeof(spdm_cert_chain_t) + hash_size);
    1261            1 :         libspdm_copy_mem(cert_chain_without_root + sizeof(spdm_cert_chain_t) + hash_size,
    1262              :                          sizeof(cert_chain_without_root) - (sizeof(spdm_cert_chain_t) + hash_size),
    1263              :                          cert_buffer,
    1264              :                          cert_buffer_size);
    1265            1 :         cert_chain_without_root_size = m_libspdm_local_certificate_chain_size - root_cert_size;
    1266            1 :         ((spdm_cert_chain_t *)cert_chain_without_root)->length =
    1267            1 :             (uint16_t)cert_chain_without_root_size;
    1268            1 :         count = (cert_chain_without_root_size +
    1269            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1270              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1271            1 :         if (calling_index != count - 1) {
    1272            0 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1273            0 :             remainder_length =
    1274            0 :                 (uint16_t)(cert_chain_without_root_size -
    1275              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1276            0 :                            (calling_index + 1));
    1277              :         } else {
    1278            1 :             portion_length = (uint16_t)(
    1279              :                 cert_chain_without_root_size -
    1280            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1281            1 :             remainder_length = 0;
    1282              :         }
    1283              : 
    1284            1 :         spdm_response_size =
    1285            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    1286            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1287            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1288              : 
    1289            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1290            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1291            1 :         spdm_response->header.param1 = 0;
    1292            1 :         spdm_response->header.param2 = 0;
    1293            1 :         spdm_response->portion_length = portion_length;
    1294            1 :         spdm_response->remainder_length = remainder_length;
    1295              :         /* send certchain without root*/
    1296            1 :         libspdm_copy_mem(spdm_response + 1,
    1297            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1298              :                          (uint8_t *)cert_chain_without_root +
    1299            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1300              :                          portion_length);
    1301              : 
    1302            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1303              :                                               false, spdm_response_size,
    1304              :                                               spdm_response, response_size,
    1305              :                                               response);
    1306              : 
    1307            1 :         calling_index++;
    1308            1 :         if (calling_index == count) {
    1309            1 :             calling_index = 0;
    1310            1 :             free(m_libspdm_local_certificate_chain);
    1311            1 :             m_libspdm_local_certificate_chain = NULL;
    1312            1 :             m_libspdm_local_certificate_chain_size = 0;
    1313              :         }
    1314              : 
    1315            1 :         free(root_cert_data);
    1316              :     }
    1317            1 :         return LIBSPDM_STATUS_SUCCESS;
    1318              : 
    1319            4 :     case 0x13: {
    1320              :         spdm_certificate_response_t *spdm_response;
    1321              :         size_t spdm_response_size;
    1322              :         size_t transport_header_size;
    1323              :         uint16_t portion_length;
    1324              :         uint16_t remainder_length;
    1325              :         size_t count;
    1326              :         static size_t calling_index = 0;
    1327              : 
    1328            4 :         if (m_libspdm_local_certificate_chain == NULL) {
    1329            1 :             libspdm_libspdm_read_responder_public_certificate_chain_expiration(
    1330              :                 &m_libspdm_local_certificate_chain,
    1331              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1332              :         }
    1333            4 :         if (m_libspdm_local_certificate_chain == NULL) {
    1334            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1335              :         }
    1336            4 :         count = (m_libspdm_local_certificate_chain_size +
    1337            4 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1338              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1339            4 :         if (calling_index != count - 1) {
    1340            3 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1341            3 :             remainder_length =
    1342            3 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1343              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1344            3 :                            (calling_index + 1));
    1345              :         } else {
    1346            1 :             portion_length = (uint16_t)(
    1347              :                 m_libspdm_local_certificate_chain_size -
    1348            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1349            1 :             remainder_length = 0;
    1350              :         }
    1351              : 
    1352            4 :         spdm_response_size =
    1353            4 :             sizeof(spdm_certificate_response_t) + portion_length;
    1354            4 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1355            4 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1356              : 
    1357            4 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1358            4 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1359            4 :         spdm_response->header.param1 = 0;
    1360            4 :         spdm_response->header.param2 = 0;
    1361            4 :         spdm_response->portion_length = portion_length;
    1362            4 :         spdm_response->remainder_length = remainder_length;
    1363            4 :         libspdm_copy_mem(spdm_response + 1,
    1364            4 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1365            4 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1366            4 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1367              :                          portion_length);
    1368              : 
    1369            4 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1370              :                                               false, spdm_response_size,
    1371              :                                               spdm_response, response_size,
    1372              :                                               response);
    1373              : 
    1374            4 :         calling_index++;
    1375            4 :         if (calling_index == count) {
    1376            1 :             calling_index = 0;
    1377            1 :             free(m_libspdm_local_certificate_chain);
    1378            1 :             m_libspdm_local_certificate_chain = NULL;
    1379            1 :             m_libspdm_local_certificate_chain_size = 0;
    1380              :         }
    1381              :     }
    1382            4 :         return LIBSPDM_STATUS_SUCCESS;
    1383              : 
    1384            1 :     case 0x14: {
    1385              :         spdm_certificate_response_t *spdm_response;
    1386              :         size_t spdm_response_size;
    1387              :         size_t transport_header_size;
    1388              :         uint16_t portion_length;
    1389              :         uint16_t remainder_length;
    1390              :         size_t count;
    1391              :         static size_t calling_index = 0;
    1392              : 
    1393            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1394            1 :             libspdm_read_responder_public_certificate_chain(
    1395              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1396              :                 &m_libspdm_local_certificate_chain,
    1397              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1398              :         }
    1399            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1400            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1401              :         }
    1402            1 :         count = (m_libspdm_local_certificate_chain_size +
    1403            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1404              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1405            1 :         if (calling_index != count - 1) {
    1406            1 :             portion_length = 0; /* Fail response: responder return portion_length is 0.*/
    1407            1 :             remainder_length =
    1408            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1409              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1410            1 :                            (calling_index + 1));
    1411              :         } else {
    1412            0 :             portion_length = (uint16_t)(
    1413              :                 m_libspdm_local_certificate_chain_size -
    1414            0 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1415            0 :             remainder_length = 0;
    1416              :         }
    1417              : 
    1418            1 :         spdm_response_size =
    1419            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    1420            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1421            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1422              : 
    1423            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1424            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1425            1 :         spdm_response->header.param1 = 0;
    1426            1 :         spdm_response->header.param2 = 0;
    1427            1 :         spdm_response->portion_length = portion_length;
    1428            1 :         spdm_response->remainder_length = remainder_length;
    1429            1 :         libspdm_copy_mem(spdm_response + 1,
    1430            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1431            1 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1432            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1433              :                          portion_length);
    1434              : 
    1435            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1436              :                                               false, spdm_response_size,
    1437              :                                               spdm_response, response_size,
    1438              :                                               response);
    1439              : 
    1440            1 :         calling_index++;
    1441            1 :         if (calling_index == count) {
    1442            0 :             calling_index = 0;
    1443            0 :             free(m_libspdm_local_certificate_chain);
    1444            0 :             m_libspdm_local_certificate_chain = NULL;
    1445            0 :             m_libspdm_local_certificate_chain_size = 0;
    1446              :         }
    1447              :     }
    1448            1 :         return LIBSPDM_STATUS_SUCCESS;
    1449              : 
    1450            1 :     case 0x15: {
    1451              :         spdm_certificate_response_t *spdm_response;
    1452              :         size_t spdm_response_size;
    1453              :         size_t transport_header_size;
    1454              :         uint16_t portion_length;
    1455              :         uint16_t remainder_length;
    1456              :         size_t count;
    1457              :         static size_t calling_index = 0;
    1458              : 
    1459            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1460            0 :             libspdm_read_responder_public_certificate_chain(
    1461              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1462              :                 &m_libspdm_local_certificate_chain,
    1463              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1464              :         }
    1465            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1466            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1467              :         }
    1468            1 :         count = (m_libspdm_local_certificate_chain_size +
    1469            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1470              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1471            1 :         if (calling_index != count - 1) {
    1472            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1; /* Fail response: responder return portion_length > spdm_request.length*/
    1473            1 :             remainder_length =
    1474            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1475              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1476            1 :                            (calling_index + 1));
    1477              :         } else {
    1478            0 :             portion_length = (uint16_t)(
    1479              :                 m_libspdm_local_certificate_chain_size -
    1480            0 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1481            0 :             remainder_length = 0;
    1482              :         }
    1483              : 
    1484            1 :         spdm_response_size =
    1485            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    1486            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1487            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1488              : 
    1489            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1490            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1491            1 :         spdm_response->header.param1 = 0;
    1492            1 :         spdm_response->header.param2 = 0;
    1493            1 :         spdm_response->portion_length = portion_length;
    1494            1 :         spdm_response->remainder_length = remainder_length;
    1495            1 :         libspdm_copy_mem(spdm_response + 1,
    1496            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1497            1 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1498            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1499              :                          portion_length);
    1500              : 
    1501            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1502              :                                               false, spdm_response_size,
    1503              :                                               spdm_response, response_size,
    1504              :                                               response);
    1505              : 
    1506            1 :         calling_index++;
    1507            1 :         if (calling_index == count) {
    1508            0 :             calling_index = 0;
    1509            0 :             free(m_libspdm_local_certificate_chain);
    1510            0 :             m_libspdm_local_certificate_chain = NULL;
    1511            0 :             m_libspdm_local_certificate_chain_size = 0;
    1512              :         }
    1513              :     }
    1514            1 :         return LIBSPDM_STATUS_SUCCESS;
    1515              : 
    1516            2 :     case 0x16: {
    1517              :         spdm_certificate_response_t *spdm_response;
    1518              :         size_t spdm_response_size;
    1519              :         size_t transport_header_size;
    1520              :         uint16_t portion_length;
    1521              :         uint16_t remainder_length;
    1522              :         size_t count;
    1523              :         static size_t calling_index = 0;
    1524              : 
    1525            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1526            0 :             libspdm_read_responder_public_certificate_chain(
    1527              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1528              :                 &m_libspdm_local_certificate_chain,
    1529              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1530              :         }
    1531            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1532            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1533              :         }
    1534            2 :         count = (m_libspdm_local_certificate_chain_size +
    1535            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1536              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1537            2 :         if (calling_index != count - 1) {
    1538            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1539              :             /* Fail response: spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
    1540              :              * total_responder_cert_chain_buffer_length.*/
    1541            1 :             remainder_length =
    1542            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
    1543            1 :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *(calling_index + 1));
    1544              : 
    1545              :         } else {
    1546            1 :             portion_length = (uint16_t)(
    1547              :                 m_libspdm_local_certificate_chain_size -
    1548            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1549            1 :             remainder_length = 0;
    1550              :         }
    1551              : 
    1552            2 :         spdm_response_size =
    1553            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    1554            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1555            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1556              : 
    1557            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1558            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1559            2 :         spdm_response->header.param1 = 0;
    1560            2 :         spdm_response->header.param2 = 0;
    1561            2 :         spdm_response->portion_length = portion_length;
    1562            2 :         spdm_response->remainder_length = remainder_length;
    1563            2 :         libspdm_copy_mem(spdm_response + 1,
    1564            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1565            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1566            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1567              :                          portion_length);
    1568              : 
    1569            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1570              :                                               false, spdm_response_size,
    1571              :                                               spdm_response, response_size,
    1572              :                                               response);
    1573              : 
    1574            2 :         calling_index++;
    1575            2 :         if (calling_index == count) {
    1576            1 :             calling_index = 0;
    1577            1 :             free(m_libspdm_local_certificate_chain);
    1578            1 :             m_libspdm_local_certificate_chain = NULL;
    1579            1 :             m_libspdm_local_certificate_chain_size = 0;
    1580              :         }
    1581              :     }
    1582            2 :         return LIBSPDM_STATUS_SUCCESS;
    1583              : 
    1584            2 :     case 0x17: {
    1585              :         spdm_certificate_response_t *spdm_response;
    1586              :         size_t spdm_response_size;
    1587              :         size_t transport_header_size;
    1588              :         uint16_t portion_length;
    1589              :         uint16_t remainder_length;
    1590              :         size_t count;
    1591              :         static size_t calling_index = 0;
    1592              : 
    1593            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1594            1 :             libspdm_read_responder_public_certificate_chain(
    1595              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1596              :                 &m_libspdm_local_certificate_chain,
    1597              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1598              :         }
    1599            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1600            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1601              :         }
    1602            2 :         count = (m_libspdm_local_certificate_chain_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1603              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1604            2 :         if (calling_index != count - 1) {
    1605            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1606            1 :             remainder_length =
    1607            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1608              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1609            1 :                            (calling_index + 1));
    1610              :         } else {
    1611            1 :             portion_length = (uint16_t)(
    1612              :                 m_libspdm_local_certificate_chain_size -
    1613            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1614            1 :             remainder_length = 0;
    1615              :         }
    1616              : 
    1617            2 :         spdm_response_size =
    1618            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    1619            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1620            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1621              : 
    1622            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1623            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1624            2 :         spdm_response->header.param1 = 0;
    1625            2 :         spdm_response->header.param2 = 0;
    1626            2 :         spdm_response->portion_length = portion_length;
    1627            2 :         spdm_response->remainder_length = remainder_length;
    1628            2 :         libspdm_copy_mem(spdm_response + 1,
    1629            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1630            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1631            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1632              :                          portion_length);
    1633              : 
    1634            2 :         libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
    1635              :                          sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
    1636              :                          spdm_response, spdm_response_size);
    1637            2 :         m_libspdm_local_buffer_size += spdm_response_size;
    1638              : 
    1639            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1640              :                                               false, spdm_response_size,
    1641              :                                               spdm_response, response_size,
    1642              :                                               response);
    1643              : 
    1644            2 :         calling_index++;
    1645            2 :         if (calling_index == count) {
    1646            1 :             calling_index = 0;
    1647            1 :             free(m_libspdm_local_certificate_chain);
    1648            1 :             m_libspdm_local_certificate_chain = NULL;
    1649            1 :             m_libspdm_local_certificate_chain_size = 0;
    1650              :         }
    1651              :     }
    1652            2 :         return LIBSPDM_STATUS_SUCCESS;
    1653              : 
    1654            2 :     case 0x18: {
    1655              :         spdm_certificate_response_t *spdm_response;
    1656              :         size_t spdm_response_size;
    1657              :         size_t transport_header_size;
    1658              :         uint16_t portion_length;
    1659              :         uint16_t remainder_length;
    1660              :         size_t count;
    1661              :         static size_t calling_index = 0;
    1662              : 
    1663            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1664            1 :             libspdm_read_responder_public_certificate_chain(
    1665              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1666              :                 &m_libspdm_local_certificate_chain,
    1667              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1668              :         }
    1669            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1670            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1671              :         }
    1672            2 :         count = (m_libspdm_local_certificate_chain_size +
    1673            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1674              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1675            2 :         if (calling_index != count - 1) {
    1676            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1677            1 :             remainder_length =
    1678            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1679              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1680            1 :                            (calling_index + 1));
    1681              :         } else {
    1682            1 :             portion_length = (uint16_t)(
    1683              :                 m_libspdm_local_certificate_chain_size -
    1684            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1685            1 :             remainder_length = 0;
    1686              :         }
    1687              : 
    1688            2 :         spdm_response_size =
    1689            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    1690            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1691            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1692              : 
    1693            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1694            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1695            2 :         spdm_response->header.param1 = 0;
    1696            2 :         spdm_response->header.param2 = 0;
    1697            2 :         spdm_response->portion_length = portion_length;
    1698            2 :         spdm_response->remainder_length = remainder_length;
    1699            2 :         libspdm_copy_mem(spdm_response + 1,
    1700            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1701            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1702            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1703              :                          portion_length);
    1704              : 
    1705            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1706              :                                               false, spdm_response_size,
    1707              :                                               spdm_response, response_size,
    1708              :                                               response);
    1709              : 
    1710            2 :         calling_index++;
    1711            2 :         if (calling_index == count) {
    1712            1 :             calling_index = 0;
    1713            1 :             free(m_libspdm_local_certificate_chain);
    1714            1 :             m_libspdm_local_certificate_chain = NULL;
    1715            1 :             m_libspdm_local_certificate_chain_size = 0;
    1716              :         }
    1717              :     }
    1718            2 :         return LIBSPDM_STATUS_SUCCESS;
    1719              : 
    1720            6 :     case 0x19: {
    1721            6 :         if (m_get_cert) {
    1722              :             spdm_certificate_response_t *spdm_response;
    1723              :             size_t spdm_response_size;
    1724              :             size_t transport_header_size;
    1725              :             uint16_t portion_length;
    1726              :             uint16_t remainder_length;
    1727              :             size_t count;
    1728              :             static size_t calling_index = 0;
    1729              :             static uint8_t slot_id = 0;
    1730              : 
    1731            4 :             if (m_libspdm_local_certificate_chain == NULL) {
    1732            2 :                 if (slot_id == 0) {
    1733            1 :                     libspdm_read_responder_public_certificate_chain(
    1734              :                         m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1735              :                         &m_libspdm_local_certificate_chain,
    1736              :                         &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1737              :                 } else {
    1738            1 :                     libspdm_read_responder_public_certificate_chain_per_slot(
    1739              :                         1, m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1740              :                         &m_libspdm_local_certificate_chain,
    1741              :                         &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1742              :                 }
    1743              :             }
    1744            4 :             if (m_libspdm_local_certificate_chain == NULL) {
    1745            0 :                 return LIBSPDM_STATUS_RECEIVE_FAIL;
    1746              :             }
    1747            4 :             count = (m_libspdm_local_certificate_chain_size +
    1748            4 :                      LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1) /
    1749              :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1750            4 :             if (calling_index != count - 1) {
    1751            2 :                 portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1752            2 :                 remainder_length =
    1753            2 :                     (uint16_t)(m_libspdm_local_certificate_chain_size -
    1754              :                                LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1755            2 :                                (calling_index + 1));
    1756              :             } else {
    1757            2 :                 portion_length = (uint16_t)(
    1758              :                     m_libspdm_local_certificate_chain_size -
    1759            2 :                     LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1760            2 :                 remainder_length = 0;
    1761              :             }
    1762              : 
    1763            4 :             spdm_response_size =
    1764            4 :                 sizeof(spdm_certificate_response_t) + portion_length;
    1765            4 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1766            4 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1767              : 
    1768            4 :             spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
    1769            4 :             spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1770            4 :             spdm_response->header.param1 = slot_id;
    1771            4 :             spdm_response->header.param2 = 0;
    1772            4 :             spdm_response->portion_length = portion_length;
    1773            4 :             spdm_response->remainder_length = remainder_length;
    1774            4 :             libspdm_copy_mem(spdm_response + 1,
    1775            4 :                              (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1776            4 :                              (uint8_t *)m_libspdm_local_certificate_chain +
    1777            4 :                              LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1778              :                              portion_length);
    1779              : 
    1780            4 :             libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1781              :                                                   false, spdm_response_size,
    1782              :                                                   spdm_response, response_size,
    1783              :                                                   response);
    1784              : 
    1785            4 :             calling_index++;
    1786            4 :             if (calling_index == count) {
    1787            2 :                 calling_index = 0;
    1788            2 :                 free(m_libspdm_local_certificate_chain);
    1789            2 :                 m_libspdm_local_certificate_chain = NULL;
    1790            2 :                 m_libspdm_local_certificate_chain_size = 0;
    1791            2 :                 slot_id++;
    1792              :             }
    1793              :         } else { /*correct CHALLENGE_AUTH message*/
    1794              :             spdm_challenge_auth_response_t *spdm_response;
    1795              :             void *data;
    1796              :             size_t data_size;
    1797              :             uint8_t *ptr;
    1798              :             uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
    1799              :             size_t sig_size;
    1800              :             size_t spdm_response_size;
    1801              :             size_t transport_header_size;
    1802              :             static uint8_t slot_id = 0;
    1803              : 
    1804            2 :             if (slot_id == 0) {
    1805            1 :                 libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    1806              :                                                                 m_libspdm_use_asym_algo, &data,
    1807              :                                                                 &data_size, NULL, NULL);
    1808              :             } else {
    1809            1 :                 libspdm_read_responder_public_certificate_chain_per_slot(1,
    1810              :                                                                          m_libspdm_use_hash_algo,
    1811              :                                                                          m_libspdm_use_asym_algo,
    1812              :                                                                          &data,
    1813              :                                                                          &data_size, NULL, NULL);
    1814              :             }
    1815              :             ((libspdm_context_t *)spdm_context)
    1816            2 :             ->local_context.local_cert_chain_provision_size[slot_id] =
    1817              :                 data_size;
    1818              :             ((libspdm_context_t *)spdm_context)
    1819            2 :             ->local_context.local_cert_chain_provision[slot_id] = data;
    1820              :             ((libspdm_context_t *)spdm_context)
    1821            2 :             ->connection_info.algorithm.base_asym_algo =
    1822              :                 m_libspdm_use_asym_algo;
    1823              :             ((libspdm_context_t *)spdm_context)
    1824            2 :             ->connection_info.algorithm.base_hash_algo =
    1825              :                 m_libspdm_use_hash_algo;
    1826            2 :             spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
    1827            2 :                                  libspdm_get_hash_size(m_libspdm_use_hash_algo) +
    1828            2 :                                  SPDM_NONCE_SIZE + 0 + sizeof(uint16_t) + 0 +
    1829            2 :                                  libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
    1830            2 :             transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1831            2 :             spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1832              : 
    1833            2 :             spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
    1834            2 :             spdm_response->header.request_response_code =
    1835              :                 SPDM_CHALLENGE_AUTH;
    1836            2 :             spdm_response->header.param1 = slot_id & 0xF;
    1837            2 :             spdm_response->header.param2 = (1 << slot_id);
    1838            2 :             ptr = (void *)(spdm_response + 1);
    1839            2 :             libspdm_hash_all(
    1840              :                 m_libspdm_use_hash_algo,
    1841              :                 ((libspdm_context_t *)spdm_context)
    1842              :                 ->local_context.local_cert_chain_provision[slot_id],
    1843              :                 ((libspdm_context_t *)spdm_context)
    1844              :                 ->local_context
    1845              :                 .local_cert_chain_provision_size[slot_id],
    1846              :                 ptr);
    1847            2 :             free(data);
    1848            2 :             ptr += libspdm_get_hash_size(m_libspdm_use_hash_algo);
    1849            2 :             libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
    1850            2 :             ptr += SPDM_NONCE_SIZE;
    1851              :             /* libspdm_zero_mem (ptr, libspdm_get_hash_size (m_libspdm_use_hash_algo));
    1852              :              * ptr += libspdm_get_hash_size (m_libspdm_use_hash_algo);*/
    1853            2 :             *(uint16_t *)ptr = 0;
    1854            2 :             ptr += sizeof(uint16_t);
    1855            2 :             libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
    1856              :                              sizeof(m_libspdm_local_buffer) -
    1857            2 :                              (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
    1858              :                               m_libspdm_local_buffer),
    1859            2 :                              spdm_response, (size_t)ptr - (size_t)spdm_response);
    1860            2 :             m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
    1861            2 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
    1862              :                            m_libspdm_local_buffer_size));
    1863            2 :             libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
    1864            2 :             libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
    1865              :                              m_libspdm_local_buffer_size, hash_data);
    1866            2 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
    1867              :                            libspdm_get_hash_size(m_libspdm_use_hash_algo)));
    1868            2 :             libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
    1869            2 :             sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
    1870            2 :             libspdm_responder_data_sign(
    1871              :                 spdm_context,
    1872            2 :                 spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
    1873              :                     SPDM_CHALLENGE_AUTH,
    1874              :                     m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
    1875              :                     false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
    1876              :                     ptr, &sig_size);
    1877            2 :             ptr += sig_size;
    1878              : 
    1879            2 :             libspdm_transport_test_encode_message(spdm_context, NULL, false,
    1880              :                                                   false, spdm_response_size,
    1881              :                                                   spdm_response, response_size,
    1882              :                                                   response);
    1883            2 :             slot_id++;
    1884              :         }
    1885              :     }
    1886            6 :         return LIBSPDM_STATUS_SUCCESS;
    1887              : 
    1888            2 :     case 0x1A: {
    1889              :         spdm_certificate_response_t *spdm_response;
    1890              :         size_t spdm_response_size;
    1891              :         size_t transport_header_size;
    1892              :         uint16_t portion_length;
    1893              :         uint16_t remainder_length;
    1894              :         size_t count;
    1895              :         static size_t calling_index = 0;
    1896              :         uint32_t session_id;
    1897              :         libspdm_session_info_t *session_info;
    1898              :         uint8_t *scratch_buffer;
    1899              :         size_t scratch_buffer_size;
    1900              : 
    1901            2 :         session_id = 0xFFFFFFFF;
    1902              : 
    1903            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1904            1 :             libspdm_read_responder_public_certificate_chain(
    1905              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1906              :                 &m_libspdm_local_certificate_chain,
    1907              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1908              :         }
    1909            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    1910            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1911              :         }
    1912            2 :         count = (m_libspdm_local_certificate_chain_size +
    1913            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1) /
    1914              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1915            2 :         if (calling_index != count - 1) {
    1916            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1917            1 :             remainder_length =
    1918            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    1919              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    1920            1 :                            (calling_index + 1));
    1921              :         } else {
    1922            1 :             portion_length = (uint16_t)(
    1923              :                 m_libspdm_local_certificate_chain_size -
    1924            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    1925            1 :             remainder_length = 0;
    1926              :         }
    1927              : 
    1928            2 :         spdm_response_size =
    1929            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    1930            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    1931            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    1932              : 
    1933            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    1934            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    1935            2 :         spdm_response->header.param1 = 0;
    1936            2 :         spdm_response->header.param2 = 0;
    1937            2 :         spdm_response->portion_length = portion_length;
    1938            2 :         spdm_response->remainder_length = remainder_length;
    1939              : 
    1940              :         /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
    1941              :          * transport_message is always in sender buffer. */
    1942            2 :         libspdm_get_scratch_buffer (spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
    1943              : 
    1944            2 :         libspdm_copy_mem(spdm_response + 1,
    1945            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    1946            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    1947            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    1948              :                          portion_length);
    1949            2 :         libspdm_copy_mem (scratch_buffer + transport_header_size,
    1950              :                           scratch_buffer_size - transport_header_size,
    1951              :                           spdm_response, spdm_response_size);
    1952            2 :         spdm_response = (void *)(scratch_buffer + transport_header_size);
    1953              : 
    1954            2 :         libspdm_transport_test_encode_message(spdm_context, &session_id, false,
    1955              :                                               false, spdm_response_size,
    1956              :                                               spdm_response, response_size,
    1957              :                                               response);
    1958              : 
    1959            2 :         calling_index++;
    1960            2 :         if (calling_index == count) {
    1961            1 :             calling_index = 0;
    1962            1 :             free(m_libspdm_local_certificate_chain);
    1963            1 :             m_libspdm_local_certificate_chain = NULL;
    1964            1 :             m_libspdm_local_certificate_chain_size = 0;
    1965              :         }
    1966            2 :         session_info = libspdm_get_session_info_via_session_id(
    1967              :             spdm_context, session_id);
    1968            2 :         if (session_info == NULL) {
    1969            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1970              :         }
    1971              :         /* WALKAROUND: If just use single context to encode message and then decode message */
    1972              :         ((libspdm_secured_message_context_t
    1973            2 :           *)(session_info->secured_message_context))
    1974            2 :         ->application_secret.response_data_sequence_number--;
    1975              :     }
    1976            2 :         return LIBSPDM_STATUS_SUCCESS;
    1977              : 
    1978            1 :     case 0x1B: {
    1979              :         spdm_certificate_response_t *spdm_response;
    1980              :         size_t spdm_response_size;
    1981              :         size_t transport_header_size;
    1982              :         uint16_t portion_length;
    1983              :         uint16_t remainder_length;
    1984              :         size_t count;
    1985              :         static size_t calling_index = 0;
    1986              : 
    1987            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1988            1 :             libspdm_read_responder_public_certificate_chain(
    1989              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    1990              :                 &m_libspdm_local_certificate_chain,
    1991              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    1992              :         }
    1993            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    1994            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    1995              :         }
    1996            1 :         count = (m_libspdm_local_certificate_chain_size +
    1997            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    1998              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    1999            1 :         if (calling_index != count - 1) {
    2000            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2001            1 :             remainder_length =
    2002            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    2003              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    2004            1 :                            (calling_index + 1));
    2005              :         } else {
    2006            0 :             portion_length = (uint16_t)(
    2007              :                 m_libspdm_local_certificate_chain_size -
    2008            0 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    2009            0 :             remainder_length = 0;
    2010              :         }
    2011              : 
    2012            1 :         spdm_response_size =
    2013            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    2014            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    2015            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    2016              : 
    2017            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    2018            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    2019            1 :         spdm_response->header.param1 = 3; /* Fail response: responder return wrong SlotID 3, not equal with SlotID 0 in request message. */
    2020            1 :         spdm_response->header.param2 = 0;
    2021            1 :         spdm_response->portion_length = portion_length;
    2022            1 :         spdm_response->remainder_length = remainder_length;
    2023            1 :         libspdm_copy_mem(spdm_response + 1,
    2024            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    2025            1 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    2026            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    2027              :                          portion_length);
    2028              : 
    2029            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    2030              :                                               false, spdm_response_size,
    2031              :                                               spdm_response, response_size,
    2032              :                                               response);
    2033              : 
    2034            1 :         calling_index++;
    2035            1 :         if (calling_index == count) {
    2036            0 :             calling_index = 0;
    2037            0 :             free(m_libspdm_local_certificate_chain);
    2038            0 :             m_libspdm_local_certificate_chain = NULL;
    2039            0 :             m_libspdm_local_certificate_chain_size = 0;
    2040              :         }
    2041              :     }
    2042            1 :         return LIBSPDM_STATUS_SUCCESS;
    2043              : 
    2044            2 :     case 0x1C: {
    2045              :         spdm_certificate_response_t *spdm_response;
    2046              :         size_t spdm_response_size;
    2047              :         size_t transport_header_size;
    2048              :         uint16_t portion_length;
    2049              :         uint16_t remainder_length;
    2050              :         size_t count;
    2051              :         static size_t calling_index = 0;
    2052              : 
    2053            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    2054            1 :             libspdm_read_responder_public_certificate_chain_alias_cert(
    2055              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    2056              :                 &m_libspdm_local_certificate_chain,
    2057              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    2058              :         }
    2059            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    2060            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    2061              :         }
    2062            2 :         count = (m_libspdm_local_certificate_chain_size +
    2063            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2064              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2065            2 :         if (calling_index != count - 1) {
    2066            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2067            1 :             remainder_length =
    2068            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    2069              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    2070            1 :                            (calling_index + 1));
    2071              :         } else {
    2072            1 :             portion_length = (uint16_t)(
    2073              :                 m_libspdm_local_certificate_chain_size -
    2074            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    2075            1 :             remainder_length = 0;
    2076              :         }
    2077              : 
    2078            2 :         spdm_response_size =
    2079            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    2080            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    2081            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    2082              : 
    2083            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
    2084            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    2085            2 :         spdm_response->header.param1 = 0;
    2086            2 :         spdm_response->header.param2 = 0;
    2087            2 :         spdm_response->portion_length = portion_length;
    2088            2 :         spdm_response->remainder_length = remainder_length;
    2089            2 :         libspdm_copy_mem(spdm_response + 1,
    2090            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    2091            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    2092            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    2093              :                          portion_length);
    2094              : 
    2095            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    2096              :                                               false, spdm_response_size,
    2097              :                                               spdm_response, response_size,
    2098              :                                               response);
    2099              : 
    2100            2 :         calling_index++;
    2101            2 :         if (calling_index == count) {
    2102            1 :             calling_index = 0;
    2103            1 :             free(m_libspdm_local_certificate_chain);
    2104            1 :             m_libspdm_local_certificate_chain = NULL;
    2105            1 :             m_libspdm_local_certificate_chain_size = 0;
    2106              :         }
    2107              :     }
    2108            2 :         return LIBSPDM_STATUS_SUCCESS;
    2109              : 
    2110            2 :     case 0x1D: {
    2111              :         spdm_certificate_response_t *spdm_response;
    2112              :         size_t spdm_response_size;
    2113              :         size_t transport_header_size;
    2114              :         uint16_t portion_length;
    2115              :         uint16_t remainder_length;
    2116              :         size_t count;
    2117              :         static size_t calling_index = 0;
    2118              : 
    2119            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    2120            1 :             libspdm_read_responder_public_certificate_chain_alias_cert_till_dev_cert_ca(
    2121              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    2122              :                 &m_libspdm_local_certificate_chain,
    2123              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    2124              :         }
    2125            2 :         if (m_libspdm_local_certificate_chain == NULL) {
    2126            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    2127              :         }
    2128            2 :         count = (m_libspdm_local_certificate_chain_size +
    2129            2 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2130              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2131            2 :         if (calling_index != count - 1) {
    2132            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2133            1 :             remainder_length =
    2134            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    2135              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    2136            1 :                            (calling_index + 1));
    2137              :         } else {
    2138            1 :             portion_length = (uint16_t)(
    2139              :                 m_libspdm_local_certificate_chain_size -
    2140            1 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    2141            1 :             remainder_length = 0;
    2142              :         }
    2143              : 
    2144            2 :         spdm_response_size =
    2145            2 :             sizeof(spdm_certificate_response_t) + portion_length;
    2146            2 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    2147            2 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    2148              : 
    2149            2 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
    2150            2 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    2151            2 :         spdm_response->header.param1 = 0;
    2152            2 :         spdm_response->header.param2 = 0;
    2153            2 :         spdm_response->portion_length = portion_length;
    2154            2 :         spdm_response->remainder_length = remainder_length;
    2155            2 :         libspdm_copy_mem(spdm_response + 1,
    2156            2 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    2157            2 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    2158            2 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    2159              :                          portion_length);
    2160              : 
    2161            2 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    2162              :                                               false, spdm_response_size,
    2163              :                                               spdm_response, response_size,
    2164              :                                               response);
    2165              : 
    2166            2 :         calling_index++;
    2167            2 :         if (calling_index == count) {
    2168            1 :             calling_index = 0;
    2169            1 :             free(m_libspdm_local_certificate_chain);
    2170            1 :             m_libspdm_local_certificate_chain = NULL;
    2171            1 :             m_libspdm_local_certificate_chain_size = 0;
    2172              :         }
    2173              :     }
    2174            2 :         return LIBSPDM_STATUS_SUCCESS;
    2175           10 :     case 0x1E: {
    2176              :         spdm_certificate_response_t *spdm_response;
    2177              :         size_t spdm_response_size;
    2178              :         size_t transport_header_size;
    2179              :         uint16_t portion_length;
    2180              :         uint16_t remainder_length;
    2181              :         size_t count;
    2182              : 
    2183           10 :         if (m_calling_index ==0) {
    2184            6 :             free(m_libspdm_local_certificate_chain);
    2185            6 :             m_libspdm_local_certificate_chain = NULL;
    2186            6 :             m_libspdm_local_certificate_chain_size = 0;
    2187              :         }
    2188              : 
    2189           10 :         if (m_libspdm_local_certificate_chain == NULL) {
    2190            6 :             libspdm_read_responder_public_certificate_chain(
    2191              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    2192              :                 &m_libspdm_local_certificate_chain,
    2193              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    2194              :         }
    2195           10 :         if (m_libspdm_local_certificate_chain == NULL) {
    2196            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    2197              :         }
    2198           10 :         count = (m_libspdm_local_certificate_chain_size +
    2199           10 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2200              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2201           10 :         if (m_calling_index != count - 1) {
    2202            6 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2203            6 :             remainder_length =
    2204            6 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    2205              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    2206            6 :                            (m_calling_index + 1));
    2207              :         } else {
    2208            4 :             portion_length = (uint16_t)(
    2209              :                 m_libspdm_local_certificate_chain_size -
    2210            4 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    2211            4 :             remainder_length = 0;
    2212              :         }
    2213              : 
    2214           10 :         spdm_response_size =
    2215           10 :             sizeof(spdm_certificate_response_t) + portion_length;
    2216           10 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    2217           10 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    2218              : 
    2219           10 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
    2220           10 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    2221           10 :         spdm_response->header.param1 = m_slot_id;
    2222           10 :         spdm_response->header.param2 = m_cert_model;
    2223           10 :         spdm_response->portion_length = portion_length;
    2224           10 :         spdm_response->remainder_length = remainder_length;
    2225              : 
    2226           10 :         libspdm_copy_mem(spdm_response + 1,
    2227           10 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    2228           10 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    2229           10 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * m_calling_index,
    2230              :                          portion_length);
    2231              : 
    2232           10 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    2233              :                                               false, spdm_response_size,
    2234              :                                               spdm_response, response_size,
    2235              :                                               response);
    2236              : 
    2237           10 :         m_calling_index++;
    2238              :     }
    2239           10 :         return LIBSPDM_STATUS_SUCCESS;
    2240            1 :     case 0x1F: {
    2241              :         spdm_certificate_response_t *spdm_response;
    2242              :         size_t spdm_response_size;
    2243              :         size_t transport_header_size;
    2244              :         uint16_t portion_length;
    2245              :         uint16_t remainder_length;
    2246              :         size_t count;
    2247              :         static size_t calling_index = 0;
    2248              : 
    2249            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    2250            1 :             libspdm_read_responder_public_certificate_chain(
    2251              :                 m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
    2252              :                 &m_libspdm_local_certificate_chain,
    2253              :                 &m_libspdm_local_certificate_chain_size, NULL, NULL);
    2254              :         }
    2255            1 :         if (m_libspdm_local_certificate_chain == NULL) {
    2256            0 :             return LIBSPDM_STATUS_RECEIVE_FAIL;
    2257              :         }
    2258            1 :         count = (m_libspdm_local_certificate_chain_size +
    2259            1 :                  LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2260              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2261            1 :         if (calling_index != count - 1) {
    2262            1 :             portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2263            1 :             remainder_length =
    2264            1 :                 (uint16_t)(m_libspdm_local_certificate_chain_size -
    2265              :                            LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
    2266            1 :                            (calling_index + 1));
    2267              :         } else {
    2268            0 :             portion_length = (uint16_t)(
    2269              :                 m_libspdm_local_certificate_chain_size -
    2270            0 :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
    2271            0 :             remainder_length = 0;
    2272              :         }
    2273              : 
    2274            1 :         spdm_response_size =
    2275            1 :             sizeof(spdm_certificate_response_t) + portion_length;
    2276            1 :         transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
    2277            1 :         spdm_response = (void *)((uint8_t *)*response + transport_header_size);
    2278              : 
    2279            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
    2280            1 :         spdm_response->header.request_response_code = SPDM_CERTIFICATE;
    2281            1 :         spdm_response->header.param1 = 0;
    2282            1 :         spdm_response->header.param2 = 0;
    2283            1 :         spdm_response->portion_length = portion_length;
    2284            1 :         spdm_response->remainder_length = remainder_length;
    2285            1 :         libspdm_copy_mem(spdm_response + 1,
    2286            1 :                          (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
    2287            1 :                          (uint8_t *)m_libspdm_local_certificate_chain +
    2288            1 :                          LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
    2289              :                          portion_length);
    2290              : 
    2291            1 :         libspdm_transport_test_encode_message(spdm_context, NULL, false,
    2292              :                                               false, spdm_response_size,
    2293              :                                               spdm_response, response_size,
    2294              :                                               response);
    2295              : 
    2296            1 :         calling_index++;
    2297            1 :         if (calling_index == count) {
    2298            0 :             calling_index = 0;
    2299            0 :             free(m_libspdm_local_certificate_chain);
    2300            0 :             m_libspdm_local_certificate_chain = NULL;
    2301            0 :             m_libspdm_local_certificate_chain_size = 0;
    2302              :         }
    2303              :     }
    2304            1 :         return LIBSPDM_STATUS_SUCCESS;
    2305            0 :     default:
    2306            0 :         return LIBSPDM_STATUS_RECEIVE_FAIL;
    2307              :     }
    2308              : }
    2309              : 
    2310              : /**
    2311              :  * Test 1: message could not be sent
    2312              :  * Expected Behavior: get a LIBSPDM_STATUS_SEND_FAIL, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
    2313              :  **/
    2314            1 : static void req_get_certificate_case1(void **state)
    2315              : {
    2316              :     libspdm_return_t status;
    2317              :     libspdm_test_context_t *spdm_test_context;
    2318              :     libspdm_context_t *spdm_context;
    2319              :     size_t cert_chain_size;
    2320              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2321              :     void *data;
    2322              :     size_t data_size;
    2323              :     void *hash;
    2324              :     size_t hash_size;
    2325              :     const uint8_t *root_cert;
    2326              :     size_t root_cert_size;
    2327              : 
    2328            1 :     spdm_test_context = *state;
    2329            1 :     spdm_context = spdm_test_context->spdm_context;
    2330            1 :     spdm_test_context->case_id = 0x1;
    2331            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2332              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2333            1 :     spdm_context->connection_info.connection_state =
    2334              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2335            1 :     spdm_context->connection_info.capability.flags |=
    2336              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2337            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2338              :                                                          m_libspdm_use_asym_algo, &data,
    2339              :                                                          &data_size, &hash, &hash_size)) {
    2340            0 :         assert(false);
    2341              :     }
    2342            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2343            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2344            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2345            0 :         assert(false);
    2346              :     }
    2347            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2348              :         root_cert_size;
    2349            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2350            1 :     libspdm_reset_message_b(spdm_context);
    2351            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2352              :         m_libspdm_use_hash_algo;
    2353            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2354              :         m_libspdm_use_asym_algo;
    2355            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2356              :         m_libspdm_use_req_asym_algo;
    2357              : 
    2358            1 :     cert_chain_size = sizeof(cert_chain);
    2359            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2360            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2361              :                                      cert_chain);
    2362            1 :     assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
    2363              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2364              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
    2365              : #endif
    2366            1 :     free(data);
    2367            1 : }
    2368              : 
    2369              : /**
    2370              :  * Test 2: Normal case, request a certificate chain
    2371              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    2372              :  **/
    2373            1 : static void req_get_certificate_case2(void **state)
    2374              : {
    2375              :     libspdm_return_t status;
    2376              :     libspdm_test_context_t *spdm_test_context;
    2377              :     libspdm_context_t *spdm_context;
    2378              :     size_t cert_chain_size;
    2379              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2380              :     void *data;
    2381              :     size_t data_size;
    2382              :     void *hash;
    2383              :     size_t hash_size;
    2384              :     const uint8_t *root_cert;
    2385              :     size_t root_cert_size;
    2386              :     libspdm_data_parameter_t parameter;
    2387              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2388              :     size_t count;
    2389              : #else
    2390              :     uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    2391              :     uint32_t set_data_buffer_hash_size;
    2392              : #endif
    2393              : 
    2394            1 :     spdm_test_context = *state;
    2395            1 :     spdm_context = spdm_test_context->spdm_context;
    2396            1 :     spdm_test_context->case_id = 0x2;
    2397            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2398              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2399            1 :     spdm_context->connection_info.connection_state =
    2400              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2401            1 :     spdm_context->connection_info.capability.flags |=
    2402              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2403            1 :     spdm_context->local_context.is_requester = true;
    2404            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2405              :                                                          m_libspdm_use_asym_algo, &data,
    2406              :                                                          &data_size, &hash, &hash_size)) {
    2407            0 :         assert(false);
    2408              :     }
    2409            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2410            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2411            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2412            0 :         assert(false);
    2413              :     }
    2414            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    2415            1 :     libspdm_dump_hex(
    2416              :         root_cert,
    2417              :         root_cert_size);
    2418            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2419              :         root_cert_size;
    2420            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2421            1 :     libspdm_reset_message_b(spdm_context);
    2422            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2423              :         m_libspdm_use_hash_algo;
    2424            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2425              :         m_libspdm_use_asym_algo;
    2426            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2427              :         m_libspdm_use_req_asym_algo;
    2428              : 
    2429            1 :     libspdm_zero_mem(&parameter, sizeof(parameter));
    2430            1 :     parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
    2431            1 :     parameter.additional_data[0] = 0;
    2432            1 :     libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, &parameter,
    2433              :                      data, data_size);
    2434              : 
    2435              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2436              :     spdm_context->transcript.message_m.buffer_size =
    2437              :         spdm_context->transcript.message_m.max_buffer_size;
    2438              : #else
    2439            1 :     set_data_buffer_hash_size =
    2440              :         spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
    2441            1 :     libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
    2442            1 :                      spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
    2443              :                      set_data_buffer_hash_size);
    2444              : #endif
    2445            1 :     cert_chain_size = sizeof(cert_chain);
    2446            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2447            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2448              :                                      cert_chain);
    2449            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    2450              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2451              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2452              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2453              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    2454              :                      sizeof(spdm_get_certificate_request_t) * count +
    2455              :                      sizeof(spdm_certificate_response_t) * count +
    2456              :                      data_size);
    2457              :     assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
    2458              : #else
    2459              :     /*
    2460              :      * libspdm_get_certificate will get leaf_cert_public_key when LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT is not enabled.
    2461              :      * The follow check is for libspdm_set_data.
    2462              :      **/
    2463            1 :     assert_int_equal(set_data_buffer_hash_size,
    2464              :                      spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size);
    2465              : 
    2466            1 :     assert_memory_equal(set_data_buffer_hash,
    2467              :                         spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
    2468              :                         set_data_buffer_hash_size);
    2469              : #endif/*LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT*/
    2470            1 :     free(data);
    2471            1 : }
    2472              : 
    2473              : /**
    2474              :  * Test 3: simulate wrong connection_state when sending GET_CERTIFICATE (missing SPDM_GET_DIGESTS_RECEIVE_FLAG and SPDM_GET_CAPABILITIES_RECEIVE_FLAG)
    2475              :  * Expected Behavior: get a LIBSPDM_STATUS_INVALID_STATE_LOCAL, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
    2476              :  **/
    2477            1 : static void req_get_certificate_case3(void **state)
    2478              : {
    2479              :     libspdm_return_t status;
    2480              :     libspdm_test_context_t *spdm_test_context;
    2481              :     libspdm_context_t *spdm_context;
    2482              :     size_t cert_chain_size;
    2483              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2484              :     void *data;
    2485              :     size_t data_size;
    2486              :     void *hash;
    2487              :     size_t hash_size;
    2488              :     const uint8_t *root_cert;
    2489              :     size_t root_cert_size;
    2490              : 
    2491            1 :     spdm_test_context = *state;
    2492            1 :     spdm_context = spdm_test_context->spdm_context;
    2493            1 :     spdm_test_context->case_id = 0x3;
    2494            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2495              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2496            1 :     spdm_context->connection_info.connection_state =
    2497              :         LIBSPDM_CONNECTION_STATE_NOT_STARTED;
    2498            1 :     spdm_context->connection_info.capability.flags |=
    2499              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2500            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2501              :                                                          m_libspdm_use_asym_algo, &data,
    2502              :                                                          &data_size, &hash, &hash_size)) {
    2503            0 :         assert(false);
    2504              :     }
    2505            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2506            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2507            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2508            0 :         assert(false);
    2509              :     }
    2510            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2511              :         root_cert_size;
    2512            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2513            1 :     libspdm_reset_message_b(spdm_context);
    2514            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2515              :         m_libspdm_use_hash_algo;
    2516            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2517              :         m_libspdm_use_asym_algo;
    2518            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2519              :         m_libspdm_use_req_asym_algo;
    2520              : 
    2521            1 :     cert_chain_size = sizeof(cert_chain);
    2522            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2523            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2524              :                                      cert_chain);
    2525            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_STATE_LOCAL);
    2526              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2527              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
    2528              : #endif
    2529            1 :     free(data);
    2530            1 : }
    2531              : 
    2532              : /**
    2533              :  * Test 4: force responder to send an ERROR message with code SPDM_ERROR_CODE_INVALID_REQUEST
    2534              :  * Expected Behavior: get a LIBSPDM_STATUS_ERROR_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
    2535              :  **/
    2536            1 : static void req_get_certificate_case4(void **state)
    2537              : {
    2538              :     libspdm_return_t status;
    2539              :     libspdm_test_context_t *spdm_test_context;
    2540              :     libspdm_context_t *spdm_context;
    2541              :     size_t cert_chain_size;
    2542              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2543              :     void *data;
    2544              :     size_t data_size;
    2545              :     void *hash;
    2546              :     size_t hash_size;
    2547              :     const uint8_t *root_cert;
    2548              :     size_t root_cert_size;
    2549              : 
    2550            1 :     spdm_test_context = *state;
    2551            1 :     spdm_context = spdm_test_context->spdm_context;
    2552            1 :     spdm_test_context->case_id = 0x4;
    2553            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2554              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2555            1 :     spdm_context->connection_info.connection_state =
    2556              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2557            1 :     spdm_context->connection_info.capability.flags |=
    2558              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2559            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2560              :                                                          m_libspdm_use_asym_algo, &data,
    2561              :                                                          &data_size, &hash, &hash_size)) {
    2562            0 :         assert(false);
    2563              :     }
    2564            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2565            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2566            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2567            0 :         assert(false);
    2568              :     }
    2569            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2570              :         root_cert_size;
    2571            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2572            1 :     libspdm_reset_message_b(spdm_context);
    2573            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2574              :         m_libspdm_use_hash_algo;
    2575            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2576              :         m_libspdm_use_asym_algo;
    2577            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2578              :         m_libspdm_use_req_asym_algo;
    2579              : 
    2580            1 :     cert_chain_size = sizeof(cert_chain);
    2581            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2582            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2583              :                                      cert_chain);
    2584            1 :     assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
    2585              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2586              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
    2587              : #endif
    2588            1 :     free(data);
    2589            1 : }
    2590              : 
    2591              : /**
    2592              :  * Test 5: force responder to send an ERROR message with code SPDM_ERROR_CODE_BUSY
    2593              :  * Expected Behavior: get a LIBSPDM_STATUS_BUSY_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
    2594              :  **/
    2595            1 : static void req_get_certificate_case5(void **state)
    2596              : {
    2597              :     libspdm_return_t status;
    2598              :     libspdm_test_context_t *spdm_test_context;
    2599              :     libspdm_context_t *spdm_context;
    2600              :     size_t cert_chain_size;
    2601              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2602              :     void *data;
    2603              :     size_t data_size;
    2604              :     void *hash;
    2605              :     size_t hash_size;
    2606              :     const uint8_t *root_cert;
    2607              :     size_t root_cert_size;
    2608              : 
    2609            1 :     spdm_test_context = *state;
    2610            1 :     spdm_context = spdm_test_context->spdm_context;
    2611            1 :     spdm_test_context->case_id = 0x5;
    2612            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2613              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2614            1 :     spdm_context->connection_info.connection_state =
    2615              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2616            1 :     spdm_context->connection_info.capability.flags |=
    2617              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2618            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2619              :                                                          m_libspdm_use_asym_algo, &data,
    2620              :                                                          &data_size, &hash, &hash_size)) {
    2621            0 :         assert(false);
    2622              :     }
    2623            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2624            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2625            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2626            0 :         assert(false);
    2627              :     }
    2628            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2629              :         root_cert_size;
    2630            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2631            1 :     libspdm_reset_message_b(spdm_context);
    2632            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2633              :         m_libspdm_use_hash_algo;
    2634            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2635              :         m_libspdm_use_asym_algo;
    2636            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2637              :         m_libspdm_use_req_asym_algo;
    2638              : 
    2639            1 :     cert_chain_size = sizeof(cert_chain);
    2640            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2641            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2642              :                                      cert_chain);
    2643            1 :     assert_int_equal(status, LIBSPDM_STATUS_BUSY_PEER);
    2644              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2645              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
    2646              : #endif
    2647            1 :     free(data);
    2648            1 : }
    2649              : 
    2650              : /**
    2651              :  * Test 6: force responder to first send an ERROR message with code SPDM_ERROR_CODE_BUSY, but functions normally afterwards
    2652              :  * Expected Behavior: receives the correct number of CERTIFICATE messages
    2653              :  **/
    2654            1 : static void req_get_certificate_case6(void **state)
    2655              : {
    2656              :     libspdm_return_t status;
    2657              :     libspdm_test_context_t *spdm_test_context;
    2658              :     libspdm_context_t *spdm_context;
    2659              :     size_t cert_chain_size;
    2660              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2661              :     void *data;
    2662              :     size_t data_size;
    2663              :     void *hash;
    2664              :     size_t hash_size;
    2665              :     const uint8_t *root_cert;
    2666              :     size_t root_cert_size;
    2667              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2668              :     size_t count;
    2669              : #endif
    2670            1 :     spdm_test_context = *state;
    2671            1 :     spdm_context = spdm_test_context->spdm_context;
    2672            1 :     spdm_test_context->case_id = 0x6;
    2673            1 :     spdm_context->retry_times = 3;
    2674            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2675              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2676            1 :     spdm_context->connection_info.connection_state =
    2677              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2678            1 :     spdm_context->connection_info.capability.flags |=
    2679              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2680            1 :     spdm_context->local_context.is_requester = true;
    2681            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2682              :                                                          m_libspdm_use_asym_algo, &data,
    2683              :                                                          &data_size, &hash, &hash_size)) {
    2684            0 :         assert(false);
    2685              :     }
    2686            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2687            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2688            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2689            0 :         assert(false);
    2690              :     }
    2691            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2692              :         root_cert_size;
    2693            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2694            1 :     libspdm_reset_message_b(spdm_context);
    2695            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2696              :         m_libspdm_use_hash_algo;
    2697            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2698              :         m_libspdm_use_asym_algo;
    2699            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2700              :         m_libspdm_use_req_asym_algo;
    2701              : 
    2702            1 :     cert_chain_size = sizeof(cert_chain);
    2703            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2704            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2705              :                                      cert_chain);
    2706            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    2707              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2708              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2709              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2710              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    2711              :                      sizeof(spdm_get_certificate_request_t) * count +
    2712              :                      sizeof(spdm_certificate_response_t) * count +
    2713              :                      data_size);
    2714              : #endif
    2715            1 :     free(data);
    2716            1 : }
    2717              : 
    2718              : /**
    2719              :  * Test 7: force responder to send an ERROR message with code SPDM_ERROR_CODE_REQUEST_RESYNCH
    2720              :  * Expected Behavior: get a LIBSPDM_STATUS_RESYNCH_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
    2721              :  **/
    2722            1 : static void req_get_certificate_case7(void **state)
    2723              : {
    2724              :     libspdm_return_t status;
    2725              :     libspdm_test_context_t *spdm_test_context;
    2726              :     libspdm_context_t *spdm_context;
    2727              :     size_t cert_chain_size;
    2728              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2729              :     void *data;
    2730              :     size_t data_size;
    2731              :     void *hash;
    2732              :     size_t hash_size;
    2733              :     const uint8_t *root_cert;
    2734              :     size_t root_cert_size;
    2735              : 
    2736            1 :     spdm_test_context = *state;
    2737            1 :     spdm_context = spdm_test_context->spdm_context;
    2738            1 :     spdm_test_context->case_id = 0x7;
    2739            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2740              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2741            1 :     spdm_context->connection_info.connection_state =
    2742              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2743            1 :     spdm_context->connection_info.capability.flags |=
    2744              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2745            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2746              :                                                          m_libspdm_use_asym_algo, &data,
    2747              :                                                          &data_size, &hash, &hash_size)) {
    2748            0 :         assert(false);
    2749              :     }
    2750            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2751            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2752            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2753            0 :         assert(false);
    2754              :     }
    2755            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2756              :         root_cert_size;
    2757            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2758            1 :     libspdm_reset_message_b(spdm_context);
    2759            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2760              :         m_libspdm_use_hash_algo;
    2761            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2762              :         m_libspdm_use_asym_algo;
    2763            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2764              :         m_libspdm_use_req_asym_algo;
    2765              : 
    2766            1 :     cert_chain_size = sizeof(cert_chain);
    2767            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2768            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2769              :                                      cert_chain);
    2770            1 :     assert_int_equal(status, LIBSPDM_STATUS_RESYNCH_PEER);
    2771            1 :     assert_int_equal(spdm_context->connection_info.connection_state,
    2772              :                      LIBSPDM_CONNECTION_STATE_NOT_STARTED);
    2773              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2774              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
    2775              : #endif
    2776            1 :     free(data);
    2777            1 : }
    2778              : 
    2779              : /**
    2780              :  * Test 8: force responder to send an ERROR message with code SPDM_ERROR_CODE_RESPONSE_NOT_READY
    2781              :  * Expected Behavior: get a LIBSPDM_STATUS_ERROR_PEER
    2782              :  **/
    2783            1 : static void req_get_certificate_case8(void **state)
    2784              : {
    2785              :     libspdm_return_t status;
    2786              :     libspdm_test_context_t *spdm_test_context;
    2787              :     libspdm_context_t *spdm_context;
    2788              :     size_t cert_chain_size;
    2789              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2790              :     void *data;
    2791              :     size_t data_size;
    2792              :     void *hash;
    2793              :     size_t hash_size;
    2794              :     const uint8_t *root_cert;
    2795              :     size_t root_cert_size;
    2796              : 
    2797            1 :     spdm_test_context = *state;
    2798            1 :     spdm_context = spdm_test_context->spdm_context;
    2799            1 :     spdm_test_context->case_id = 0x8;
    2800            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2801              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2802            1 :     spdm_context->connection_info.connection_state =
    2803              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2804            1 :     spdm_context->connection_info.capability.flags |=
    2805              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2806            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2807              :                                                          m_libspdm_use_asym_algo, &data,
    2808              :                                                          &data_size, &hash, &hash_size)) {
    2809            0 :         assert(false);
    2810              :     }
    2811            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2812            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2813            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2814            0 :         assert(false);
    2815              :     }
    2816            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    2817              :         root_cert_size;
    2818            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2819            1 :     libspdm_reset_message_b(spdm_context);
    2820            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2821              :         m_libspdm_use_hash_algo;
    2822            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2823              :         m_libspdm_use_asym_algo;
    2824            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2825              :         m_libspdm_use_req_asym_algo;
    2826              : 
    2827            1 :     cert_chain_size = sizeof(cert_chain);
    2828            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2829            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2830              :                                      cert_chain);
    2831            1 :     assert_int_equal(status, LIBSPDM_STATUS_NOT_READY_PEER);
    2832            1 :     free(data);
    2833            1 : }
    2834              : 
    2835              : /**
    2836              :  * Test 9: force responder to first send an ERROR message with code SPDM_ERROR_CODE_RESPONSE_NOT_READY, but functions normally afterwards
    2837              :  * Expected Behavior: receives the correct number of CERTIFICATE messages
    2838              :  **/
    2839            1 : static void req_get_certificate_case9(void **state)
    2840              : {
    2841              :     libspdm_return_t status;
    2842              :     libspdm_test_context_t *spdm_test_context;
    2843              :     libspdm_context_t *spdm_context;
    2844              :     size_t cert_chain_size;
    2845              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2846              :     void *data;
    2847              :     size_t data_size;
    2848              :     void *hash;
    2849              :     size_t hash_size;
    2850              :     const uint8_t *root_cert;
    2851              :     size_t root_cert_size;
    2852              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2853              :     size_t count;
    2854              : #endif
    2855              : 
    2856            1 :     spdm_test_context = *state;
    2857            1 :     spdm_context = spdm_test_context->spdm_context;
    2858            1 :     spdm_test_context->case_id = 0x9;
    2859            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2860              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2861            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2862            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2863            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2864              :                                                          m_libspdm_use_asym_algo, &data,
    2865              :                                                          &data_size, &hash, &hash_size)) {
    2866            0 :         assert(false);
    2867              :     }
    2868            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2869            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2870            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2871            0 :         assert(false);
    2872              :     }
    2873            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
    2874            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    2875            1 :     libspdm_reset_message_b(spdm_context);
    2876            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    2877            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    2878            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
    2879            1 :     spdm_context->local_context.is_requester = true;
    2880              : 
    2881            1 :     cert_chain_size = sizeof(cert_chain);
    2882            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2883            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2884              :                                      cert_chain);
    2885              :     if (LIBSPDM_RESPOND_IF_READY_SUPPORT) {
    2886            1 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    2887              :     } else {
    2888              :         assert_int_equal(status, LIBSPDM_STATUS_NOT_READY_PEER);
    2889              :     }
    2890              : 
    2891              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2892              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) / LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2893              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    2894              :                      sizeof(spdm_get_certificate_request_t) * count +
    2895              :                      sizeof(spdm_certificate_response_t) * count + data_size);
    2896              : #endif
    2897            1 :     free(data);
    2898            1 : }
    2899              : 
    2900              : /**
    2901              :  * Test 10: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
    2902              :  * Expected Behavior: receives the correct number of Certificate messages
    2903              :  **/
    2904            1 : static void req_get_certificate_case10(void **state)
    2905              : {
    2906              :     libspdm_return_t status;
    2907              :     libspdm_test_context_t *spdm_test_context;
    2908              :     libspdm_context_t *spdm_context;
    2909              :     size_t cert_chain_size;
    2910              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2911              :     void *data;
    2912              :     size_t data_size;
    2913              :     void *hash;
    2914              :     size_t hash_size;
    2915              :     const uint8_t *root_cert;
    2916              :     size_t root_cert_size;
    2917              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2918              :     size_t count;
    2919              : #endif
    2920              : 
    2921            1 :     spdm_test_context = *state;
    2922            1 :     spdm_context = spdm_test_context->spdm_context;
    2923            1 :     spdm_test_context->case_id = 0xA;
    2924            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2925              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2926            1 :     spdm_context->connection_info.connection_state =
    2927              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2928            1 :     spdm_context->connection_info.capability.flags |=
    2929              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2930            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    2931              :                                                          m_libspdm_use_asym_algo, &data,
    2932              :                                                          &data_size, &hash, &hash_size)) {
    2933            0 :         assert(false);
    2934              :     }
    2935            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    2936            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    2937            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    2938            0 :         assert(false);
    2939              :     }
    2940              : 
    2941            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
    2942            1 :     spdm_context->local_context.peer_root_cert_provision[0] = NULL;
    2943            1 :     libspdm_reset_message_b(spdm_context);
    2944            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    2945              :         m_libspdm_use_hash_algo;
    2946            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    2947              :         m_libspdm_use_asym_algo;
    2948            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    2949              :         m_libspdm_use_req_asym_algo;
    2950            1 :     spdm_context->local_context.is_requester = true;
    2951              : 
    2952            1 :     cert_chain_size = sizeof(cert_chain);
    2953            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    2954            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    2955              :                                      cert_chain);
    2956            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    2957              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2958              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    2959              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    2960              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    2961              :                      sizeof(spdm_get_certificate_request_t) * count +
    2962              :                      sizeof(spdm_certificate_response_t) * count +
    2963              :                      data_size);
    2964              : #endif
    2965            1 :     free(data);
    2966            1 : }
    2967              : 
    2968              : /**
    2969              :  * Test 11: Normal procedure, but the retrieved certificate chain has an invalid signature
    2970              :  * Expected Behavior: get a LIBSPDM_STATUS_VERIF_FAIL, and receives the correct number of Certificate messages
    2971              :  **/
    2972            1 : static void req_get_certificate_case11(void **state)
    2973              : {
    2974              :     libspdm_return_t status;
    2975              :     libspdm_test_context_t *spdm_test_context;
    2976              :     libspdm_context_t *spdm_context;
    2977              :     size_t cert_chain_size;
    2978              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    2979              :     void *data;
    2980              :     size_t data_size;
    2981              :     void *hash;
    2982              :     size_t hash_size;
    2983              :     const uint8_t *root_cert;
    2984              :     size_t root_cert_size;
    2985              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2986              :     size_t count;
    2987              : #endif
    2988            1 :     spdm_test_context = *state;
    2989            1 :     spdm_context = spdm_test_context->spdm_context;
    2990            1 :     spdm_test_context->case_id = 0xB;
    2991            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    2992              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    2993              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    2994            1 :     spdm_context->connection_info.connection_state =
    2995              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    2996            1 :     spdm_context->connection_info.capability.flags |=
    2997              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    2998              :     /* Loading certificate chain and saving root certificate hash*/
    2999            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3000              :                                                          m_libspdm_use_asym_algo, &data,
    3001              :                                                          &data_size, &hash, &hash_size)) {
    3002            0 :         assert(false);
    3003              :     }
    3004            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3005            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3006            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3007            0 :         assert(false);
    3008              :     }
    3009            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3010              :         root_cert_size;
    3011            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3012            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3013              :         m_libspdm_use_hash_algo;
    3014            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3015              :         m_libspdm_use_asym_algo;
    3016            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3017              :         m_libspdm_use_req_asym_algo;
    3018              : 
    3019              :     /* Resetting message buffer*/
    3020            1 :     libspdm_reset_message_b(spdm_context);
    3021              :     /* Calculating expected number of messages received*/
    3022              : 
    3023            1 :     cert_chain_size = sizeof(cert_chain);
    3024            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3025            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3026              :                                      cert_chain);
    3027            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
    3028              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3029              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    3030              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    3031              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    3032              :                      sizeof(spdm_get_certificate_request_t) * count +
    3033              :                      sizeof(spdm_certificate_response_t) * count +
    3034              :                      data_size);
    3035              : #endif
    3036            1 :     free(data);
    3037            1 : }
    3038              : 
    3039              : /**
    3040              :  * Test 12: Normal procedure, but the retrieved root certificate does not match
    3041              :  * Expected Behavior: get a LIBSPDM_STATUS_VERIF_NO_AUTHORITY, and receives the correct number of Certificate messages
    3042              :  **/
    3043            1 : static void req_get_certificate_case12(void **state)
    3044              : {
    3045              :     libspdm_return_t status;
    3046              :     libspdm_test_context_t *spdm_test_context;
    3047              :     libspdm_context_t *spdm_context;
    3048              :     size_t cert_chain_size;
    3049              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3050              :     uint8_t root_cert_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3051              :     void *data;
    3052              :     size_t data_size;
    3053              :     void *hash;
    3054              :     size_t hash_size;
    3055              :     const uint8_t *root_cert;
    3056              :     size_t root_cert_size;
    3057              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3058              :     size_t count;
    3059              : #endif
    3060              : 
    3061            1 :     spdm_test_context = *state;
    3062            1 :     spdm_context = spdm_test_context->spdm_context;
    3063            1 :     spdm_test_context->case_id = 0xC;
    3064            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3065              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3066              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    3067            1 :     spdm_context->connection_info.connection_state =
    3068              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3069            1 :     spdm_context->connection_info.capability.flags |=
    3070              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3071            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3072              :                                                          m_libspdm_use_asym_algo, &data,
    3073              :                                                          &data_size, &hash, &hash_size)) {
    3074            0 :         assert(false);
    3075              :     }
    3076            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3077            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3078            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3079            0 :         assert(false);
    3080              :     }
    3081              :     /* arbitrarily changes the root certificate on purpose*/
    3082            1 :     if (root_cert != NULL) {
    3083            1 :         memcpy(root_cert_buffer, root_cert, root_cert_size);
    3084            1 :         root_cert_buffer[0]++;
    3085              :     }
    3086            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3087              :         root_cert_size;
    3088            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert_buffer;
    3089            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3090              :         m_libspdm_use_hash_algo;
    3091            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3092              :         m_libspdm_use_asym_algo;
    3093            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3094              :         m_libspdm_use_req_asym_algo;
    3095              :     /* Resetting message buffer*/
    3096            1 :     libspdm_reset_message_b(spdm_context);
    3097              :     /* Calculating expected number of messages received*/
    3098            1 :     spdm_context->local_context.is_requester = true;
    3099              : 
    3100            1 :     cert_chain_size = sizeof(cert_chain);
    3101            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3102            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3103              :                                      cert_chain);
    3104            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_NO_AUTHORITY);
    3105              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3106              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    3107              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    3108              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    3109              :                      sizeof(spdm_get_certificate_request_t) * count +
    3110              :                      sizeof(spdm_certificate_response_t) * count +
    3111              :                      data_size);
    3112              : #endif
    3113            1 :     free(data);
    3114            1 : }
    3115              : 
    3116              : /**
    3117              :  * Test 13: Gets a short certificate chain (fits in 1 message)
    3118              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    3119              :  **/
    3120            1 : static void req_get_certificate_case13(void **state)
    3121              : {
    3122              :     libspdm_return_t status;
    3123              :     libspdm_test_context_t *spdm_test_context;
    3124              :     libspdm_context_t *spdm_context;
    3125              :     size_t cert_chain_size;
    3126              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3127              :     void *data;
    3128              :     size_t data_size;
    3129              :     void *hash;
    3130              :     size_t hash_size;
    3131              :     const uint8_t *root_cert;
    3132              :     size_t root_cert_size;
    3133              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3134              :     size_t count;
    3135              : #endif
    3136              : 
    3137              :     /* This case requires a short certificate chain (fits in 1 message) for testing,
    3138              :      * so skip when m_libspdm_use_asym_algo is other than ECC_P256 */
    3139            1 :     if (m_libspdm_use_asym_algo !=
    3140              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256) {
    3141            0 :         return;
    3142              :     }
    3143              : 
    3144            1 :     spdm_test_context = *state;
    3145            1 :     spdm_context = spdm_test_context->spdm_context;
    3146            1 :     spdm_test_context->case_id = 0xD;
    3147            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3148              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3149              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    3150            1 :     spdm_context->connection_info.connection_state =
    3151              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3152            1 :     spdm_context->connection_info.capability.flags |=
    3153              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3154              :     /* Loading Root certificate and saving its hash*/
    3155            1 :     libspdm_read_responder_public_certificate_chain_by_size(
    3156              :         m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, LIBSPDM_TEST_CERT_SMALL, &data,
    3157              :         &data_size, &hash, &hash_size);
    3158            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3159            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3160            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3161            0 :         assert(false);
    3162              :     }
    3163            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3164              :         root_cert_size;
    3165            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3166            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3167              :         m_libspdm_use_hash_algo;
    3168            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3169              :         m_libspdm_use_asym_algo;
    3170            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3171              :         m_libspdm_use_req_asym_algo;
    3172            1 :     spdm_context->local_context.is_requester = true;
    3173              :     /* Resetting message buffer*/
    3174            1 :     libspdm_reset_message_b(spdm_context);
    3175              :     /* Calculating expected number of messages received*/
    3176              : 
    3177            1 :     cert_chain_size = sizeof(cert_chain);
    3178            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3179            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3180              :                                      cert_chain);
    3181            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    3182              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3183              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    3184              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    3185              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    3186              :                      sizeof(spdm_get_certificate_request_t) * count +
    3187              :                      sizeof(spdm_certificate_response_t) * count +
    3188              :                      data_size);
    3189              : #endif
    3190            1 :     free(data);
    3191              : }
    3192              : 
    3193              : /**
    3194              :  * Test 14: request a whole certificate chain byte by byte
    3195              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    3196              :  **/
    3197            1 : static void req_get_certificate_case14(void **state)
    3198              : {
    3199              :     libspdm_return_t status;
    3200              :     libspdm_test_context_t *spdm_test_context;
    3201              :     libspdm_context_t *spdm_context;
    3202              :     size_t cert_chain_size;
    3203              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3204              :     void *data;
    3205              :     size_t data_size;
    3206              :     void *hash;
    3207              :     size_t hash_size;
    3208              :     const uint8_t *root_cert;
    3209              :     size_t root_cert_size;
    3210              :     uint16_t get_cert_length;
    3211              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3212              :     size_t count;
    3213              : #endif
    3214              :     /* Get certificate chain byte by byte*/
    3215            1 :     get_cert_length = 1;
    3216              : 
    3217            1 :     spdm_test_context = *state;
    3218            1 :     spdm_context = spdm_test_context->spdm_context;
    3219            1 :     spdm_test_context->case_id = 0xE;
    3220            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3221              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3222              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    3223            1 :     spdm_context->connection_info.connection_state =
    3224              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3225            1 :     spdm_context->connection_info.capability.flags |=
    3226              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3227              :     /* Loading Root certificate and saving its hash*/
    3228            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3229              :                                                          m_libspdm_use_asym_algo, &data,
    3230              :                                                          &data_size, &hash, &hash_size)) {
    3231            0 :         assert(false);
    3232              :     }
    3233            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3234            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3235            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3236            0 :         assert(false);
    3237              :     }
    3238            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3239              :         root_cert_size;
    3240            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3241            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3242              :         m_libspdm_use_hash_algo;
    3243            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3244              :         m_libspdm_use_asym_algo;
    3245            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3246              :         m_libspdm_use_req_asym_algo;
    3247              :     /* Resetting message buffer*/
    3248            1 :     libspdm_reset_message_b(spdm_context);
    3249              :     /* Calculating expected number of messages received*/
    3250              : 
    3251            1 :     cert_chain_size = sizeof(cert_chain);
    3252            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3253            1 :     status = libspdm_get_certificate_choose_length(
    3254              :         spdm_context, NULL, 0, get_cert_length, &cert_chain_size, cert_chain);
    3255              :     /* It may fail because the spdm does not support too many messages.
    3256              :      * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
    3257              :     if (status == LIBSPDM_STATUS_SUCCESS) {
    3258              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3259              :         count = (data_size + get_cert_length - 1) / get_cert_length;
    3260              :         assert_int_equal(
    3261              :             spdm_context->transcript.message_b.buffer_size,
    3262              :             sizeof(spdm_get_certificate_request_t) * count +
    3263              :             sizeof(spdm_certificate_response_t) * count +
    3264              :             data_size);
    3265              : #endif
    3266              :     }
    3267            1 :     free(data);
    3268            1 : }
    3269              : 
    3270              : /**
    3271              :  * Test 15: request a long certificate chain
    3272              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    3273              :  **/
    3274            1 : static void req_get_certificate_case15(void **state)
    3275              : {
    3276              :     libspdm_return_t status;
    3277              :     libspdm_test_context_t *spdm_test_context;
    3278              :     libspdm_context_t *spdm_context;
    3279              :     size_t cert_chain_size;
    3280              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3281              :     void *data;
    3282              :     size_t data_size;
    3283              :     void *hash;
    3284              :     size_t hash_size;
    3285              :     const uint8_t *root_cert;
    3286              :     size_t root_cert_size;
    3287              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3288              :     size_t count;
    3289              : #endif
    3290              : 
    3291            1 :     spdm_test_context = *state;
    3292            1 :     spdm_context = spdm_test_context->spdm_context;
    3293            1 :     spdm_test_context->case_id = 0xF;
    3294            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3295              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3296              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    3297            1 :     spdm_context->connection_info.connection_state =
    3298              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3299            1 :     spdm_context->connection_info.capability.flags |=
    3300              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3301              :     /* Loading Root certificate and saving its hash*/
    3302              : 
    3303            1 :     libspdm_read_responder_public_certificate_chain_by_size(
    3304              :         /*MAXUINT16_CERT signature_algo is SHA256RSA */
    3305              :         m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
    3306              :         LIBSPDM_TEST_CERT_MAXUINT16, &data, &data_size, &hash, &hash_size);
    3307            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3308            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3309            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3310            0 :         assert(false);
    3311              :     }
    3312            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3313              :         root_cert_size;
    3314            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3315            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3316              :         m_libspdm_use_hash_algo;
    3317            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3318              :         m_libspdm_use_asym_algo;
    3319            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3320              :         m_libspdm_use_req_asym_algo;
    3321              :     /* Resetting message buffer*/
    3322            1 :     libspdm_reset_message_b(spdm_context);
    3323              :     /* Calculating expected number of messages received*/
    3324              : 
    3325            1 :     cert_chain_size = sizeof(cert_chain);
    3326            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3327            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3328              :                                      cert_chain);
    3329              :     /* It may fail because the spdm does not support too long message.
    3330              :      * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
    3331              :     if (status == LIBSPDM_STATUS_SUCCESS) {
    3332              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3333              :         count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    3334              :                 LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    3335              :         assert_int_equal(
    3336              :             spdm_context->transcript.message_b.buffer_size,
    3337              :             sizeof(spdm_get_certificate_request_t) * count +
    3338              :             sizeof(spdm_certificate_response_t) * count +
    3339              :             data_size);
    3340              : #endif
    3341              :     }
    3342            1 :     free(data);
    3343            1 : }
    3344              : 
    3345              : /**
    3346              :  * Test 16: receiving an unexpected ERROR message from the responder.
    3347              :  * There are tests for all named codes, including some reserved ones
    3348              :  * (namely, 0x00, 0x0b, 0x0c, 0x3f, 0xfd, 0xfe).
    3349              :  * However, for having specific test cases, it is excluded from this case:
    3350              :  * Busy (0x03), ResponseNotReady (0x42), and RequestResync (0x43).
    3351              :  * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
    3352              :  **/
    3353            1 : static void req_get_certificate_case16(void **state) {
    3354              :     libspdm_return_t status;
    3355              :     libspdm_test_context_t    *spdm_test_context;
    3356              :     libspdm_context_t  *spdm_context;
    3357              :     size_t cert_chain_size;
    3358              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3359              :     void                 *data;
    3360              :     size_t data_size;
    3361              :     void                 *hash;
    3362              :     size_t hash_size;
    3363              :     const uint8_t                 *root_cert;
    3364              :     size_t root_cert_size;
    3365              :     uint16_t error_code;
    3366              : 
    3367            1 :     spdm_test_context = *state;
    3368            1 :     spdm_context = spdm_test_context->spdm_context;
    3369            1 :     spdm_test_context->case_id = 0x10;
    3370            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
    3371              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3372            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3373            1 :     libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
    3374              :                                                      m_libspdm_use_asym_algo,
    3375              :                                                      &data, &data_size,
    3376              :                                                      &hash, &hash_size);
    3377            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3378            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3379            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3380            0 :         assert(false);
    3381              :     }
    3382            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
    3383            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3384            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    3385            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    3386            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
    3387              : 
    3388            1 :     error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
    3389           19 :     while(error_code <= 0xff) {
    3390           18 :         spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3391           18 :         libspdm_reset_message_b(spdm_context);
    3392              : 
    3393           18 :         cert_chain_size = sizeof(cert_chain);
    3394           18 :         libspdm_zero_mem (cert_chain, sizeof(cert_chain));
    3395           18 :         status = libspdm_get_certificate (spdm_context, NULL, 0, &cert_chain_size, cert_chain);
    3396           18 :         LIBSPDM_ASSERT_INT_EQUAL_CASE (status, LIBSPDM_STATUS_ERROR_PEER, error_code);
    3397              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3398              :         /* assert_int_equal (spdm_context->transcript.message_b.buffer_size, 0);*/
    3399              :         LIBSPDM_ASSERT_INT_EQUAL_CASE (spdm_context->transcript.message_b.buffer_size, 0,
    3400              :                                        error_code);
    3401              : #endif
    3402              : 
    3403           18 :         error_code++;
    3404           18 :         if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
    3405            1 :             error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
    3406              :         }
    3407           18 :         if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
    3408            1 :             error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
    3409              :         }
    3410           18 :         if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
    3411            1 :             error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
    3412              :         }
    3413              :     }
    3414              : 
    3415            1 :     free(data);
    3416            1 : }
    3417              : 
    3418              : /**
    3419              :  * Test 17: Normal case, get a certificate chain start not with root cert. Validates certificate by using a preloaded chain.
    3420              :  * Expected Behavior: receives the correct number of Certificate messages
    3421              :  **/
    3422            1 : static void req_get_certificate_case17(void **state)
    3423              : {
    3424              :     libspdm_return_t status;
    3425              :     libspdm_test_context_t *spdm_test_context;
    3426              :     libspdm_context_t *spdm_context;
    3427              :     size_t cert_chain_size;
    3428              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3429              :     void *data;
    3430              :     size_t data_size;
    3431              :     void *hash;
    3432              :     size_t hash_size;
    3433              :     const uint8_t *root_cert;
    3434              :     size_t root_cert_size;
    3435              : 
    3436            1 :     spdm_test_context = *state;
    3437            1 :     spdm_context = spdm_test_context->spdm_context;
    3438            1 :     spdm_test_context->case_id = 0x11;
    3439            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3440              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3441            1 :     spdm_context->connection_info.connection_state =
    3442              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3443            1 :     spdm_context->connection_info.capability.flags |=
    3444              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3445            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3446              :                                                          m_libspdm_use_asym_algo, &data,
    3447              :                                                          &data_size, &hash, &hash_size)) {
    3448            0 :         assert(false);
    3449              :     }
    3450            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3451            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3452            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3453            0 :         assert(false);
    3454              :     }
    3455              : 
    3456            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
    3457            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3458            1 :     libspdm_reset_message_b(spdm_context);
    3459            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3460              :         m_libspdm_use_hash_algo;
    3461            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3462              :         m_libspdm_use_asym_algo;
    3463            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3464              :         m_libspdm_use_req_asym_algo;
    3465            1 :     spdm_context->local_context.is_requester = true;
    3466              : 
    3467            1 :     cert_chain_size = sizeof(cert_chain);
    3468            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3469            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3470              :                                      cert_chain);
    3471            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    3472            1 :     free(data);
    3473            1 : }
    3474              : 
    3475              : /**
    3476              :  * Test 18: Fail case, get a certificate chain start not with root cert and with wrong signature. Validates certificate by using a preloaded chain.
    3477              :  * Expected Behavior: receives the correct number of Certificate messages
    3478              :  **/
    3479            1 : static void req_get_certificate_case18(void **state)
    3480              : {
    3481              :     libspdm_return_t status;
    3482              :     libspdm_test_context_t *spdm_test_context;
    3483              :     libspdm_context_t *spdm_context;
    3484              :     size_t cert_chain_size;
    3485              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3486              :     void *data;
    3487              :     size_t data_size;
    3488              :     void *hash;
    3489              :     size_t hash_size;
    3490              :     const uint8_t *root_cert;
    3491              :     size_t root_cert_size;
    3492              : 
    3493            1 :     spdm_test_context = *state;
    3494            1 :     spdm_context = spdm_test_context->spdm_context;
    3495            1 :     spdm_test_context->case_id = 0x12;
    3496            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3497              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3498            1 :     spdm_context->connection_info.connection_state =
    3499              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3500            1 :     spdm_context->connection_info.capability.flags |=
    3501              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3502            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3503              :                                                          m_libspdm_use_asym_algo, &data,
    3504              :                                                          &data_size, &hash, &hash_size)) {
    3505            0 :         assert(false);
    3506              :     }
    3507            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3508            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3509            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3510            0 :         assert(false);
    3511              :     }
    3512              : 
    3513            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
    3514            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3515            1 :     libspdm_reset_message_b(spdm_context);
    3516            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3517              :         m_libspdm_use_hash_algo;
    3518            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3519              :         m_libspdm_use_asym_algo;
    3520            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3521              :         m_libspdm_use_req_asym_algo;
    3522              : 
    3523            1 :     cert_chain_size = sizeof(cert_chain);
    3524            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3525            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3526              :                                      cert_chain);
    3527            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
    3528            1 :     free(data);
    3529            1 : }
    3530              : 
    3531              : /**
    3532              :  * Test 19: Normal procedure, but one certificate in the retrieved certificate chain past its expiration date.
    3533              :  * Expected Behavior: get a LIBSPDM_STATUS_VERIF_FAIL, and receives the correct number of Certificate messages
    3534              :  **/
    3535            1 : static void req_get_certificate_case19(void **state)
    3536              : {
    3537              :     libspdm_return_t status;
    3538              :     libspdm_test_context_t *spdm_test_context;
    3539              :     libspdm_context_t *spdm_context;
    3540              :     size_t cert_chain_size;
    3541              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3542              :     void *data;
    3543              :     size_t data_size;
    3544              :     void *hash;
    3545              :     size_t hash_size;
    3546              :     const uint8_t *root_cert;
    3547              :     size_t root_cert_size;
    3548              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3549              :     size_t count;
    3550              : #endif
    3551              : 
    3552            1 :     spdm_test_context = *state;
    3553            1 :     spdm_context = spdm_test_context->spdm_context;
    3554            1 :     spdm_test_context->case_id = 0x13;
    3555            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3556              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3557              :     /* Setting SPDM context as the first steps of the protocol has been accomplished*/
    3558            1 :     spdm_context->connection_info.connection_state =
    3559              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3560            1 :     spdm_context->connection_info.capability.flags |=
    3561              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3562              :     /* Loading the target expiration certificate chain and saving root certificate hash
    3563              :      * "rsa3072_Expiration/bundle_responder.certchain.der"*/
    3564            1 :     libspdm_libspdm_read_responder_public_certificate_chain_expiration(&data,
    3565              :                                                                        &data_size, &hash,
    3566              :                                                                        &hash_size);
    3567            1 :     libspdm_x509_get_cert_from_cert_chain(
    3568            1 :         (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3569            1 :         data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
    3570              :         &root_cert, &root_cert_size);
    3571            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3572              :         root_cert_size;
    3573            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3574            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3575              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
    3576            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3577              :         m_libspdm_use_asym_algo;
    3578            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3579              :         m_libspdm_use_req_asym_algo;
    3580              :     /* Resetting message buffer*/
    3581            1 :     libspdm_reset_message_b(spdm_context);
    3582              :     /* Calculating expected number of messages received*/
    3583              : 
    3584            1 :     cert_chain_size = sizeof(cert_chain);
    3585            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3586            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3587              :                                      cert_chain);
    3588            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
    3589              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3590              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    3591              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    3592              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    3593              :                      sizeof(spdm_get_certificate_request_t) * count +
    3594              :                      sizeof(spdm_certificate_response_t) * count +
    3595              :                      data_size);
    3596              : #endif
    3597            1 :     free(data);
    3598            1 : }
    3599              : 
    3600              : /**
    3601              :  * Test 20: Fail case, request a certificate chain, responder return portion_length is 0.
    3602              :  * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
    3603              :  **/
    3604            1 : static void req_get_certificate_case20(void **state)
    3605              : {
    3606              :     libspdm_return_t status;
    3607              :     libspdm_test_context_t *spdm_test_context;
    3608              :     libspdm_context_t *spdm_context;
    3609              :     size_t cert_chain_size;
    3610              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3611              :     void *data;
    3612              :     size_t data_size;
    3613              :     void *hash;
    3614              :     size_t hash_size;
    3615              :     const uint8_t *root_cert;
    3616              :     size_t root_cert_size;
    3617              : 
    3618            1 :     spdm_test_context = *state;
    3619            1 :     spdm_context = spdm_test_context->spdm_context;
    3620            1 :     spdm_test_context->case_id = 0x14;
    3621            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3622              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3623            1 :     spdm_context->connection_info.connection_state =
    3624              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3625            1 :     spdm_context->connection_info.capability.flags |=
    3626              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3627            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3628              :                                                          m_libspdm_use_asym_algo, &data,
    3629              :                                                          &data_size, &hash, &hash_size)) {
    3630            0 :         assert(false);
    3631              :     }
    3632            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3633            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3634            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3635            0 :         assert(false);
    3636              :     }
    3637            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3638            1 :     libspdm_dump_hex(
    3639              :         root_cert,
    3640              :         root_cert_size);
    3641            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3642              :         root_cert_size;
    3643            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3644            1 :     libspdm_reset_message_b(spdm_context);
    3645            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3646              :         m_libspdm_use_hash_algo;
    3647            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3648              :         m_libspdm_use_asym_algo;
    3649            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3650              :         m_libspdm_use_req_asym_algo;
    3651              : 
    3652            1 :     cert_chain_size = sizeof(cert_chain);
    3653            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3654            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3655              :                                      cert_chain);
    3656            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    3657            1 :     free(data);
    3658            1 : }
    3659              : 
    3660              : /**
    3661              :  * Test 21: Fail case, request a certificate chain, responder return portion_length > spdm_request.length.
    3662              :  * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
    3663              :  **/
    3664            1 : static void req_get_certificate_case21(void **state)
    3665              : {
    3666              :     libspdm_return_t status;
    3667              :     libspdm_test_context_t *spdm_test_context;
    3668              :     libspdm_context_t *spdm_context;
    3669              :     size_t cert_chain_size;
    3670              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3671              :     void *data;
    3672              :     size_t data_size;
    3673              :     void *hash;
    3674              :     size_t hash_size;
    3675              :     const uint8_t *root_cert;
    3676              :     size_t root_cert_size;
    3677              : 
    3678            1 :     spdm_test_context = *state;
    3679            1 :     spdm_context = spdm_test_context->spdm_context;
    3680            1 :     spdm_test_context->case_id = 0x15;
    3681            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3682              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3683            1 :     spdm_context->connection_info.connection_state =
    3684              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3685            1 :     spdm_context->connection_info.capability.flags |=
    3686              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3687            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3688              :                                                          m_libspdm_use_asym_algo, &data,
    3689              :                                                          &data_size, &hash, &hash_size)) {
    3690            0 :         assert(false);
    3691              :     }
    3692            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3693            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3694            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3695            0 :         assert(false);
    3696              :     }
    3697            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3698            1 :     libspdm_dump_hex(
    3699              :         root_cert,
    3700              :         root_cert_size);
    3701            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3702              :         root_cert_size;
    3703            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3704            1 :     libspdm_reset_message_b(spdm_context);
    3705            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3706              :         m_libspdm_use_hash_algo;
    3707            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3708              :         m_libspdm_use_asym_algo;
    3709            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3710              :         m_libspdm_use_req_asym_algo;
    3711              : 
    3712            1 :     cert_chain_size = sizeof(cert_chain);
    3713            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3714            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3715              :                                      cert_chain);
    3716            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    3717            1 :     free(data);
    3718            1 : }
    3719              : 
    3720              : /**
    3721              :  * Test 22: Fail case, request a certificate chain,
    3722              :  * spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
    3723              :  * total_responder_cert_chain_buffer_length.
    3724              :  * Expected Behavior:returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
    3725              :  **/
    3726            1 : static void req_get_certificate_case22(void **state)
    3727              : {
    3728              :     libspdm_return_t status;
    3729              :     libspdm_test_context_t *spdm_test_context;
    3730              :     libspdm_context_t *spdm_context;
    3731              :     size_t cert_chain_size;
    3732              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3733              :     void *data;
    3734              :     size_t data_size;
    3735              :     void *hash;
    3736              :     size_t hash_size;
    3737              :     const uint8_t *root_cert;
    3738              :     size_t root_cert_size;
    3739              : 
    3740            1 :     spdm_test_context = *state;
    3741            1 :     spdm_context = spdm_test_context->spdm_context;
    3742            1 :     spdm_test_context->case_id = 0x16;
    3743            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3744              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3745            1 :     spdm_context->connection_info.connection_state =
    3746              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3747            1 :     spdm_context->connection_info.capability.flags |=
    3748              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3749            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3750              :                                                          m_libspdm_use_asym_algo, &data,
    3751              :                                                          &data_size, &hash, &hash_size)) {
    3752            0 :         assert(false);
    3753              :     }
    3754            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3755            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3756            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3757            0 :         assert(false);
    3758              :     }
    3759            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3760            1 :     libspdm_dump_hex(
    3761              :         root_cert,
    3762              :         root_cert_size);
    3763            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3764              :         root_cert_size;
    3765            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3766            1 :     libspdm_reset_message_b(spdm_context);
    3767            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3768              :         m_libspdm_use_hash_algo;
    3769            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3770              :         m_libspdm_use_asym_algo;
    3771            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3772              :         m_libspdm_use_req_asym_algo;
    3773              : 
    3774            1 :     cert_chain_size = sizeof(cert_chain);
    3775            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3776            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3777              :                                      cert_chain);
    3778            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    3779            1 :     free(data);
    3780            1 : }
    3781              : 
    3782              : /**
    3783              :  * Test 23: request messages are successfully sent and response messages are successfully
    3784              :  * received. Buffer B already has arbitrary data.
    3785              :  * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS and CERTIFICATE messages are
    3786              :  * received, buffer B appends the exchanged GET_CERTIFICATE and CERTIFICATE messages.
    3787              :  **/
    3788            1 : static void req_get_certificate_case23(void **state)
    3789              : {
    3790              :     libspdm_return_t status;
    3791              :     libspdm_test_context_t *spdm_test_context;
    3792              :     libspdm_context_t *spdm_context;
    3793              :     size_t cert_chain_size;
    3794              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3795              :     void *data;
    3796              :     size_t data_size;
    3797              :     void *hash;
    3798              :     size_t hash_size;
    3799              :     const uint8_t *root_cert;
    3800              :     size_t root_cert_size;
    3801              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3802              :     size_t arbitrary_size;
    3803              : #endif
    3804              : 
    3805            1 :     spdm_test_context = *state;
    3806            1 :     spdm_context = spdm_test_context->spdm_context;
    3807            1 :     spdm_test_context->case_id = 0x17;
    3808            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3809              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3810            1 :     spdm_context->connection_info.connection_state =
    3811              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3812            1 :     spdm_context->connection_info.capability.flags |=
    3813              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3814            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3815              :                                                          m_libspdm_use_asym_algo, &data,
    3816              :                                                          &data_size, &hash, &hash_size)) {
    3817            0 :         assert(false);
    3818              :     }
    3819            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3820            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3821            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3822            0 :         assert(false);
    3823              :     }
    3824            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3825            1 :     libspdm_dump_hex(root_cert, root_cert_size);
    3826            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
    3827            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3828            1 :     libspdm_reset_message_b(spdm_context);
    3829            1 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
    3830            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
    3831            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
    3832            1 :     spdm_context->local_context.is_requester = true;
    3833              : 
    3834              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3835              :     /*filling B with arbitrary data*/
    3836              :     arbitrary_size = 8;
    3837              :     libspdm_set_mem(spdm_context->transcript.message_b.buffer, arbitrary_size, (uint8_t) 0xEE);
    3838              :     spdm_context->transcript.message_b.buffer_size = arbitrary_size;
    3839              : #endif
    3840            1 :     cert_chain_size = sizeof(cert_chain);
    3841            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3842            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size, cert_chain);
    3843            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    3844              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3845              :     libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
    3846              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    3847              :                      (arbitrary_size + m_libspdm_local_buffer_size));
    3848              :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer (0x%x):\n",
    3849              :                    m_libspdm_local_buffer_size));
    3850              :     libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
    3851              :     assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size,
    3852              :                         m_libspdm_local_buffer, m_libspdm_local_buffer_size);
    3853              : #endif
    3854            1 :     free(data);
    3855            1 : }
    3856              : 
    3857              : /**
    3858              :  * Test 24: test the Alias Cert model, hardware identify OID is found in AliasCert model cert
    3859              :  * Expected Behavior: return RETURN_SECURITY_VIOLATION
    3860              :  **/
    3861            1 : static void req_get_certificate_case24(void **state)
    3862              : {
    3863              :     libspdm_return_t status;
    3864              :     libspdm_test_context_t *spdm_test_context;
    3865              :     libspdm_context_t *spdm_context;
    3866              :     size_t cert_chain_size;
    3867              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3868              :     void *data;
    3869              :     size_t data_size;
    3870              :     void *hash;
    3871              :     size_t hash_size;
    3872              :     const uint8_t *root_cert;
    3873              :     size_t root_cert_size;
    3874              : 
    3875            1 :     spdm_test_context = *state;
    3876            1 :     spdm_context = spdm_test_context->spdm_context;
    3877            1 :     spdm_test_context->case_id = 0x18;
    3878            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    3879              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3880            1 :     spdm_context->connection_info.connection_state =
    3881              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3882            1 :     spdm_context->connection_info.capability.flags |=
    3883              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3884              :     /*The only different setting with normal case2: cert model is AliasCert model*/
    3885            1 :     spdm_context->connection_info.capability.flags |=
    3886              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    3887            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3888              :                                                          m_libspdm_use_asym_algo, &data,
    3889              :                                                          &data_size, &hash, &hash_size)) {
    3890            0 :         assert(false);
    3891              :     }
    3892            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3893            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3894            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3895            0 :         assert(false);
    3896              :     }
    3897            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3898            1 :     LIBSPDM_INTERNAL_DUMP_HEX(
    3899              :         root_cert,
    3900              :         root_cert_size);
    3901            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3902              :         root_cert_size;
    3903            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3904            1 :     libspdm_reset_message_b(spdm_context);
    3905            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3906              :         m_libspdm_use_hash_algo;
    3907            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3908              :         m_libspdm_use_asym_algo;
    3909            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3910              :         m_libspdm_use_req_asym_algo;
    3911              : 
    3912            1 :     cert_chain_size = sizeof(cert_chain);
    3913            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    3914            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    3915              :                                      cert_chain);
    3916            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
    3917            1 :     free(data);
    3918            1 : }
    3919              : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
    3920              : /**
    3921              :  * Test 25: Normal case, request a certificate chain
    3922              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    3923              :  **/
    3924            1 : static void req_get_certificate_case25(void **state)
    3925              : {
    3926              :     libspdm_return_t status;
    3927              :     libspdm_test_context_t *spdm_test_context;
    3928              :     libspdm_context_t *spdm_context;
    3929              :     size_t cert_chain_size;
    3930              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    3931              :     void *data;
    3932              :     void *data1;
    3933              :     size_t data_size;
    3934              :     size_t data1_size;
    3935              :     void *hash;
    3936              :     void *hash1;
    3937              :     size_t hash_size;
    3938              :     size_t hash1_size;
    3939              :     const uint8_t *root_cert;
    3940              :     const uint8_t *root_cert1;
    3941              :     size_t root_cert_size;
    3942              :     size_t root_cert1_size;
    3943              :     uint8_t slot_id;
    3944              :     uint8_t measurement_hash[LIBSPDM_MAX_HASH_SIZE];
    3945              : 
    3946            1 :     spdm_test_context = *state;
    3947            1 :     spdm_context = spdm_test_context->spdm_context;
    3948            1 :     spdm_test_context->case_id = 0x19;
    3949            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
    3950              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    3951            1 :     spdm_context->connection_info.connection_state =
    3952              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    3953            1 :     spdm_context->connection_info.capability.flags |=
    3954              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    3955            1 :     spdm_context->connection_info.capability.flags &=
    3956              :         ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    3957            1 :     spdm_context->connection_info.capability.flags |=
    3958              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP;
    3959            1 :     libspdm_reset_message_a(spdm_context);
    3960            1 :     libspdm_reset_message_b(spdm_context);
    3961            1 :     libspdm_reset_message_c(spdm_context);
    3962            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    3963              :         m_libspdm_use_hash_algo;
    3964            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    3965              :         m_libspdm_use_asym_algo;
    3966            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    3967              :         m_libspdm_use_req_asym_algo;
    3968            1 :     spdm_context->local_context.is_requester = true;
    3969              : 
    3970            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    3971              :                                                          m_libspdm_use_asym_algo, &data,
    3972              :                                                          &data_size, &hash, &hash_size)) {
    3973            0 :         assert(false);
    3974              :     }
    3975            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    3976            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    3977            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    3978            0 :         assert(false);
    3979              :     }
    3980            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3981            1 :     libspdm_dump_hex(
    3982              :         root_cert,
    3983              :         root_cert_size);
    3984            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    3985              :         root_cert_size;
    3986            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    3987              : 
    3988            1 :     libspdm_read_responder_public_certificate_chain_per_slot(1, m_libspdm_use_hash_algo,
    3989              :                                                              m_libspdm_use_asym_algo, &data1,
    3990              :                                                              &data1_size, &hash1, &hash1_size);
    3991            1 :     libspdm_x509_get_cert_from_cert_chain((uint8_t *)data1 + sizeof(spdm_cert_chain_t) + hash1_size,
    3992            1 :                                           data1_size - sizeof(spdm_cert_chain_t) - hash1_size, 0,
    3993              :                                           &root_cert1, &root_cert1_size);
    3994            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    3995            1 :     libspdm_dump_hex(
    3996              :         root_cert1,
    3997              :         root_cert1_size);
    3998            1 :     spdm_context->local_context.peer_root_cert_provision_size[1] =
    3999              :         root_cert1_size;
    4000            1 :     spdm_context->local_context.peer_root_cert_provision[1] = root_cert1;
    4001              : 
    4002            1 :     m_get_cert = true;
    4003            3 :     for (slot_id = 0; slot_id < 2; slot_id++) {
    4004            2 :         cert_chain_size = sizeof(cert_chain);
    4005            2 :         libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4006            2 :         status = libspdm_get_certificate(spdm_context, NULL, slot_id, &cert_chain_size,
    4007              :                                          cert_chain);
    4008            2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_get_certificate - %xu\n", status));
    4009            2 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4010              :     }
    4011              : 
    4012            1 :     libspdm_reset_message_b(spdm_context);
    4013            1 :     m_get_cert = false;
    4014            3 :     for (slot_id = 0; slot_id < 2; slot_id++) {
    4015            2 :         libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
    4016            2 :         status = libspdm_challenge(
    4017              :             spdm_context, NULL, slot_id,
    4018              :             SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH,
    4019              :             measurement_hash, NULL);
    4020            2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_challenge - %xu\n", status));
    4021            2 :         assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4022              :     }
    4023              : 
    4024            1 :     free(data);
    4025            1 :     free(data1);
    4026            1 : }
    4027              : #endif
    4028              : /**
    4029              :  * Test 26: Normal case, request a certificate chain in a session
    4030              :  * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
    4031              :  **/
    4032            1 : static void req_get_certificate_case26(void **state)
    4033              : {
    4034              :     libspdm_return_t status;
    4035              :     libspdm_test_context_t *spdm_test_context;
    4036              :     libspdm_context_t *spdm_context;
    4037              :     size_t cert_chain_size;
    4038              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4039              :     void *data;
    4040              :     size_t data_size;
    4041              :     void *hash;
    4042              :     size_t hash_size;
    4043              :     const uint8_t *root_cert;
    4044              :     size_t root_cert_size;
    4045              :     uint32_t session_id;
    4046              :     libspdm_session_info_t *session_info;
    4047              : 
    4048            1 :     spdm_test_context = *state;
    4049            1 :     spdm_context = spdm_test_context->spdm_context;
    4050            1 :     spdm_test_context->case_id = 0x1A;
    4051            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    4052              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4053            1 :     spdm_context->connection_info.connection_state =
    4054              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4055            1 :     spdm_context->connection_info.capability.flags |=
    4056              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4057            1 :     spdm_context->connection_info.capability.flags |=
    4058              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    4059            1 :     spdm_context->connection_info.capability.flags &=
    4060              :         ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    4061            1 :     spdm_context->connection_info.capability.flags |=
    4062              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
    4063            1 :     spdm_context->connection_info.capability.flags |=
    4064              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
    4065            1 :     spdm_context->connection_info.capability.flags |=
    4066              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
    4067            1 :     spdm_context->local_context.capability.flags |=
    4068              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
    4069            1 :     spdm_context->local_context.capability.flags |=
    4070              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
    4071            1 :     spdm_context->local_context.capability.flags |=
    4072              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
    4073            1 :     spdm_context->connection_info.algorithm.dhe_named_group =
    4074              :         m_libspdm_use_dhe_algo;
    4075            1 :     spdm_context->connection_info.algorithm.aead_cipher_suite =
    4076              :         m_libspdm_use_aead_algo;
    4077              : 
    4078            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    4079              :                                                          m_libspdm_use_asym_algo, &data,
    4080              :                                                          &data_size, &hash, &hash_size)) {
    4081            0 :         assert(false);
    4082              :     }
    4083            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4084            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4085            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4086            0 :         assert(false);
    4087              :     }
    4088            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    4089            1 :     libspdm_dump_hex(
    4090              :         root_cert,
    4091              :         root_cert_size);
    4092            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    4093              :         root_cert_size;
    4094            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    4095            1 :     libspdm_reset_message_b(spdm_context);
    4096            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4097              :         m_libspdm_use_hash_algo;
    4098            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4099              :         m_libspdm_use_asym_algo;
    4100            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4101              :         m_libspdm_use_req_asym_algo;
    4102            1 :     spdm_context->local_context.is_requester = true;
    4103              : 
    4104            1 :     session_id = 0xFFFFFFFF;
    4105            1 :     session_info = &spdm_context->session_info[0];
    4106            1 :     libspdm_session_info_init(spdm_context, session_info, session_id,
    4107              :                               SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
    4108            1 :     libspdm_secured_message_set_session_state(session_info->secured_message_context,
    4109              :                                               LIBSPDM_SESSION_STATE_ESTABLISHED);
    4110              : 
    4111              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4112              :     session_info->session_transcript.message_m.buffer_size =
    4113              :         session_info->session_transcript.message_m.max_buffer_size;
    4114              : #endif
    4115            1 :     cert_chain_size = sizeof(cert_chain);
    4116            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4117            1 :     status = libspdm_get_certificate_ex(spdm_context, &session_id,
    4118              :                                         0, &cert_chain_size,
    4119              :                                         cert_chain, NULL, 0);
    4120            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4121              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4122              :     assert_int_equal(session_info->session_transcript.message_m.buffer_size, 0);
    4123              : #endif
    4124            1 :     free(data);
    4125            1 : }
    4126              : 
    4127              : /**
    4128              :  * Test 27: Fail case, responder return wrong SlotID 3, but it should be equal with SlotID 0 in request message.
    4129              :  * Expected Behavior:returns a status of INVALID_MSG_FIELD.
    4130              :  **/
    4131            1 : static void req_get_certificate_case27(void **state)
    4132              : {
    4133              :     libspdm_return_t status;
    4134              :     libspdm_test_context_t *spdm_test_context;
    4135              :     libspdm_context_t *spdm_context;
    4136              :     size_t cert_chain_size;
    4137              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4138              :     void *data;
    4139              :     size_t data_size;
    4140              :     void *hash;
    4141              :     size_t hash_size;
    4142              :     const uint8_t *root_cert;
    4143              :     size_t root_cert_size;
    4144              : 
    4145            1 :     spdm_test_context = *state;
    4146            1 :     spdm_context = spdm_test_context->spdm_context;
    4147            1 :     spdm_test_context->case_id = 0x1B;
    4148            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    4149              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4150            1 :     spdm_context->connection_info.connection_state =
    4151              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4152            1 :     spdm_context->connection_info.capability.flags |=
    4153              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4154            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    4155              :                                                          m_libspdm_use_asym_algo, &data,
    4156              :                                                          &data_size, &hash, &hash_size)) {
    4157            0 :         assert(false);
    4158              :     }
    4159            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4160            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4161            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4162            0 :         assert(false);
    4163              :     }
    4164            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    4165            1 :     libspdm_dump_hex(
    4166              :         root_cert,
    4167              :         root_cert_size);
    4168            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    4169              :         root_cert_size;
    4170            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    4171            1 :     libspdm_reset_message_b(spdm_context);
    4172            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4173              :         m_libspdm_use_hash_algo;
    4174            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4175              :         m_libspdm_use_asym_algo;
    4176            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4177              :         m_libspdm_use_req_asym_algo;
    4178              : 
    4179            1 :     cert_chain_size = sizeof(cert_chain);
    4180            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4181            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    4182              :                                      cert_chain);
    4183            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    4184            1 :     free(data);
    4185              : 
    4186            1 :     if (m_libspdm_local_certificate_chain != NULL) {
    4187            1 :         free(m_libspdm_local_certificate_chain);
    4188            1 :         m_libspdm_local_certificate_chain = NULL;
    4189              :     }
    4190            1 : }
    4191              : 
    4192              : /**
    4193              :  * Test 28: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
    4194              :  * Expected Behavior: receives the correct number of Certificate messages
    4195              :  **/
    4196            1 : static void req_get_certificate_case28(void **state)
    4197              : {
    4198              :     libspdm_return_t status;
    4199              :     libspdm_test_context_t *spdm_test_context;
    4200              :     libspdm_context_t *spdm_context;
    4201              :     size_t cert_chain_size;
    4202              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4203              :     void *data;
    4204              :     size_t data_size;
    4205              :     void *hash;
    4206              :     size_t hash_size;
    4207              :     const uint8_t *root_cert;
    4208              :     size_t root_cert_size;
    4209              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4210              :     size_t count;
    4211              : #endif
    4212              : 
    4213            1 :     spdm_test_context = *state;
    4214            1 :     spdm_context = spdm_test_context->spdm_context;
    4215            1 :     spdm_test_context->case_id = 0x1C;
    4216            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
    4217              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4218            1 :     spdm_context->connection_info.connection_state =
    4219              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4220            1 :     spdm_context->connection_info.capability.flags |=
    4221              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4222            1 :     spdm_context->connection_info.capability.flags |=
    4223              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    4224            1 :     libspdm_read_responder_public_certificate_chain_alias_cert(
    4225              :         m_libspdm_use_hash_algo,
    4226              :         m_libspdm_use_asym_algo, &data,
    4227              :         &data_size, &hash, &hash_size);
    4228            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4229            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4230            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4231            0 :         assert(false);
    4232              :     }
    4233              : 
    4234            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
    4235            1 :     spdm_context->local_context.peer_root_cert_provision[0] = NULL;
    4236            1 :     libspdm_reset_message_b(spdm_context);
    4237            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4238              :         m_libspdm_use_hash_algo;
    4239            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4240              :         m_libspdm_use_asym_algo;
    4241            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4242              :         m_libspdm_use_req_asym_algo;
    4243            1 :     spdm_context->local_context.is_requester = true;
    4244              : 
    4245            1 :     cert_chain_size = sizeof(cert_chain);
    4246            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4247            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    4248              :                                      cert_chain);
    4249            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4250              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4251              :     count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
    4252              :             LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
    4253              :     assert_int_equal(spdm_context->transcript.message_b.buffer_size,
    4254              :                      sizeof(spdm_get_certificate_request_t) * count +
    4255              :                      sizeof(spdm_certificate_response_t) * count +
    4256              :                      data_size);
    4257              : #endif
    4258            1 :     free(data);
    4259            1 : }
    4260              : 
    4261              : /**
    4262              :  * Test 29: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
    4263              :  * Expected Behavior: receives the correct number of Certificate messages
    4264              :  **/
    4265            1 : static void req_get_certificate_case29(void **state)
    4266              : {
    4267              :     libspdm_return_t status;
    4268              :     libspdm_test_context_t *spdm_test_context;
    4269              :     libspdm_context_t *spdm_context;
    4270              :     size_t cert_chain_size;
    4271              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4272              :     void *data;
    4273              :     size_t data_size;
    4274              :     void *hash;
    4275              :     size_t hash_size;
    4276              :     const uint8_t *root_cert;
    4277              :     size_t root_cert_size;
    4278              : 
    4279            1 :     spdm_test_context = *state;
    4280            1 :     spdm_context = spdm_test_context->spdm_context;
    4281            1 :     spdm_test_context->case_id = 0x1D;
    4282            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
    4283              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4284            1 :     spdm_context->connection_info.connection_state =
    4285              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4286            1 :     spdm_context->connection_info.capability.flags |=
    4287              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4288            1 :     spdm_context->connection_info.capability.flags |=
    4289              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
    4290            1 :     libspdm_read_responder_public_certificate_chain_alias_cert(
    4291              :         m_libspdm_use_hash_algo,
    4292              :         m_libspdm_use_asym_algo, &data,
    4293              :         &data_size, &hash, &hash_size);
    4294            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4295            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4296            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4297            0 :         assert(false);
    4298              :     }
    4299              : 
    4300            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
    4301            1 :     spdm_context->local_context.peer_root_cert_provision[0] = NULL;
    4302            1 :     libspdm_reset_message_b(spdm_context);
    4303            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4304              :         m_libspdm_use_hash_algo;
    4305            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4306              :         m_libspdm_use_asym_algo;
    4307            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4308              :         m_libspdm_use_req_asym_algo;
    4309            1 :     spdm_context->local_context.is_requester = true;
    4310              : 
    4311            1 :     cert_chain_size = sizeof(cert_chain);
    4312            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4313            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    4314              :                                      cert_chain);
    4315            1 :     assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
    4316            1 :     free(data);
    4317            1 : }
    4318              : 
    4319              : /**
    4320              :  * Test 30: check request attributes and response attributes ,
    4321              :  * Set CertModel to determine whether it meets expectations
    4322              :  * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
    4323              :  * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
    4324              :  * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
    4325              :  **/
    4326            1 : static void req_get_certificate_case30(void **state)
    4327              : {
    4328              :     libspdm_return_t status;
    4329              :     libspdm_test_context_t *spdm_test_context;
    4330              :     libspdm_context_t *spdm_context;
    4331              :     size_t cert_chain_size;
    4332              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4333              :     void *data;
    4334              :     size_t data_size;
    4335              :     void *hash;
    4336              :     size_t hash_size;
    4337              :     const uint8_t *root_cert;
    4338              :     size_t root_cert_size;
    4339              :     libspdm_data_parameter_t parameter;
    4340              : 
    4341              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4342              : #else
    4343              :     uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    4344              :     uint32_t set_data_buffer_hash_size;
    4345              : #endif
    4346              : 
    4347            1 :     spdm_test_context = *state;
    4348            1 :     spdm_context = spdm_test_context->spdm_context;
    4349            1 :     spdm_test_context->case_id = 0x1E;
    4350            1 :     spdm_context->retry_times = 1;
    4351            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
    4352              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4353            1 :     spdm_context->connection_info.connection_state =
    4354              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4355            1 :     spdm_context->connection_info.capability.flags = 0;
    4356            1 :     spdm_context->connection_info.capability.flags |=
    4357              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4358            1 :     spdm_context->local_context.is_requester = true;
    4359            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    4360              :                                                          m_libspdm_use_asym_algo, &data,
    4361              :                                                          &data_size, &hash, &hash_size)) {
    4362            0 :         assert(false);
    4363              :     }
    4364            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4365            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4366            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4367            0 :         assert(false);
    4368              :     }
    4369            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    4370            1 :     libspdm_dump_hex(
    4371              :         root_cert,
    4372              :         root_cert_size);
    4373            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    4374              :         root_cert_size;
    4375            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    4376            1 :     libspdm_reset_message_b(spdm_context);
    4377            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4378              :         m_libspdm_use_hash_algo;
    4379            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4380              :         m_libspdm_use_asym_algo;
    4381            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4382              :         m_libspdm_use_req_asym_algo;
    4383              : 
    4384            1 :     libspdm_zero_mem(&parameter, sizeof(parameter));
    4385            1 :     parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
    4386            1 :     parameter.additional_data[0] = 0;
    4387            1 :     libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, &parameter,
    4388              :                      data, data_size);
    4389              : 
    4390              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4391              :     spdm_context->transcript.message_m.buffer_size =
    4392              :         spdm_context->transcript.message_m.max_buffer_size;
    4393              : #else
    4394            1 :     set_data_buffer_hash_size =
    4395              :         spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
    4396            1 :     libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
    4397            1 :                      spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
    4398              :                      set_data_buffer_hash_size);
    4399              : #endif
    4400              : 
    4401              :     /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
    4402            1 :     spdm_context->connection_info.multi_key_conn_rsp = true;
    4403            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
    4404            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
    4405            1 :     libspdm_reset_message_b(spdm_context);
    4406            1 :     m_slot_id = 0;
    4407            1 :     m_calling_index = 0;
    4408              : 
    4409            1 :     cert_chain_size = sizeof(cert_chain);
    4410            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4411            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4412              :                                      cert_chain);
    4413            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4414            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
    4415            1 :     assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
    4416            1 :     assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
    4417              :                         m_libspdm_local_certificate_chain_size);
    4418              : 
    4419              :     /* Sub Case 2: CertModel Value of 2 , AliasCert model*/
    4420            1 :     spdm_context->connection_info.multi_key_conn_rsp = true;
    4421            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
    4422            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
    4423            1 :     libspdm_reset_message_b(spdm_context);
    4424            1 :     m_slot_id = 0;
    4425            1 :     m_calling_index = 0;
    4426              : 
    4427            1 :     cert_chain_size = sizeof(cert_chain);
    4428            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4429            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4430              :                                      cert_chain);
    4431            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4432            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
    4433            1 :     assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
    4434            1 :     assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
    4435              :                         m_libspdm_local_certificate_chain_size);
    4436              : 
    4437              :     /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
    4438              :      * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
    4439            1 :     spdm_context->connection_info.multi_key_conn_rsp = true;
    4440            1 :     spdm_context->connection_info.peer_cert_info[1] = 0;
    4441            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
    4442            1 :     libspdm_reset_message_b(spdm_context);
    4443            1 :     m_slot_id = 1;
    4444            1 :     m_calling_index = 0;
    4445              : 
    4446            1 :     cert_chain_size = sizeof(cert_chain);
    4447            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4448            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4449              :                                      cert_chain);
    4450            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4451            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[1], m_cert_model);
    4452            1 :     assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
    4453            1 :     assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
    4454              :                         m_libspdm_local_certificate_chain_size);
    4455              : 
    4456              :     /* Sub Case 4: CertModel Value of 3 , GenericCert model , slot_id set 0
    4457              :      * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
    4458            1 :     spdm_context->connection_info.multi_key_conn_rsp = true;
    4459            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
    4460            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
    4461            1 :     libspdm_reset_message_b(spdm_context);
    4462            1 :     m_slot_id = 0;
    4463            1 :     m_calling_index = 0;
    4464              : 
    4465            1 :     cert_chain_size = sizeof(cert_chain);
    4466            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4467            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4468              :                                      cert_chain);
    4469            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    4470            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
    4471              : 
    4472              :     /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_RSP is true*/
    4473              :     /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
    4474              :      * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
    4475            1 :     spdm_context->connection_info.multi_key_conn_rsp = true;
    4476            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
    4477            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
    4478            1 :     libspdm_reset_message_b(spdm_context);
    4479            1 :     m_slot_id = 0;
    4480            1 :     m_calling_index = 0;
    4481              : 
    4482            1 :     cert_chain_size = sizeof(cert_chain);
    4483            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4484            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4485              :                                      cert_chain);
    4486            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
    4487            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
    4488              : 
    4489              :     /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_RSP is false*/
    4490              :     /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
    4491              :      * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
    4492            1 :     spdm_context->connection_info.multi_key_conn_rsp = false;
    4493            1 :     spdm_context->connection_info.peer_cert_info[0] = 0;
    4494            1 :     m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
    4495            1 :     libspdm_reset_message_b(spdm_context);
    4496            1 :     m_slot_id = 0;
    4497            1 :     m_calling_index = 0;
    4498              : 
    4499            1 :     cert_chain_size = sizeof(cert_chain);
    4500            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4501            1 :     status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
    4502              :                                      cert_chain);
    4503            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
    4504            1 :     assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
    4505            1 :     assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
    4506            1 :     assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
    4507              :                         m_libspdm_local_certificate_chain_size);
    4508              : 
    4509            1 :     free(data);
    4510            1 :     free(m_libspdm_local_certificate_chain);
    4511            1 :     m_libspdm_local_certificate_chain = NULL;
    4512            1 :     m_libspdm_local_certificate_chain_size = 0;
    4513            1 : }
    4514              : 
    4515              : /**
    4516              :  * Test 31: Fail case, input buffer size too small for holding cert chain.
    4517              :  * Expected Behavior: returns a status of BUFFER_TOO_SMALL.
    4518              :  **/
    4519            1 : static void req_get_certificate_case31(void **state)
    4520              : {
    4521              :     libspdm_return_t status;
    4522              :     libspdm_test_context_t *spdm_test_context;
    4523              :     libspdm_context_t *spdm_context;
    4524              :     size_t cert_chain_size;
    4525              :     uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
    4526              :     void *data;
    4527              :     size_t data_size;
    4528              :     void *hash;
    4529              :     size_t hash_size;
    4530              :     const uint8_t *root_cert;
    4531              :     size_t root_cert_size;
    4532              :     libspdm_data_parameter_t parameter;
    4533              : #if !LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4534              :     uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    4535              :     uint32_t set_data_buffer_hash_size;
    4536              : #endif
    4537              : 
    4538            1 :     spdm_test_context = *state;
    4539            1 :     spdm_context = spdm_test_context->spdm_context;
    4540            1 :     spdm_test_context->case_id = 0x1F;
    4541            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
    4542              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
    4543            1 :     spdm_context->connection_info.connection_state =
    4544              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
    4545            1 :     spdm_context->connection_info.capability.flags |=
    4546              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
    4547            1 :     spdm_context->local_context.is_requester = true;
    4548            1 :     if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
    4549              :                                                          m_libspdm_use_asym_algo, &data,
    4550              :                                                          &data_size, &hash, &hash_size)) {
    4551            0 :         assert(false);
    4552              :     }
    4553            1 :     if (!libspdm_x509_get_cert_from_cert_chain(
    4554            1 :             (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
    4555            1 :             data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
    4556            0 :         assert(false);
    4557              :     }
    4558            1 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
    4559            1 :     libspdm_dump_hex(
    4560              :         root_cert,
    4561              :         root_cert_size);
    4562            1 :     spdm_context->local_context.peer_root_cert_provision_size[0] =
    4563              :         root_cert_size;
    4564            1 :     spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
    4565            1 :     libspdm_reset_message_b(spdm_context);
    4566            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
    4567              :         m_libspdm_use_hash_algo;
    4568            1 :     spdm_context->connection_info.algorithm.base_asym_algo =
    4569              :         m_libspdm_use_asym_algo;
    4570            1 :     spdm_context->connection_info.algorithm.req_base_asym_alg =
    4571              :         m_libspdm_use_req_asym_algo;
    4572              : 
    4573            1 :     libspdm_zero_mem(&parameter, sizeof(parameter));
    4574            1 :     parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
    4575            1 :     parameter.additional_data[0] = 0;
    4576            1 :     libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, &parameter,
    4577              :                      data, data_size);
    4578              : 
    4579              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    4580              :     spdm_context->transcript.message_m.buffer_size =
    4581              :         spdm_context->transcript.message_m.max_buffer_size;
    4582              : #else
    4583            1 :     set_data_buffer_hash_size =
    4584              :         spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
    4585            1 :     libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
    4586            1 :                      spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
    4587              :                      set_data_buffer_hash_size);
    4588              : #endif
    4589              :     /* Set cert_chain_size to a value that is less than the actual size of the certificate chain */
    4590            1 :     cert_chain_size = data_size - 1;
    4591            1 :     libspdm_zero_mem(cert_chain, sizeof(cert_chain));
    4592            1 :     status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
    4593              :                                      cert_chain);
    4594            1 :     assert_int_equal(status, LIBSPDM_STATUS_BUFFER_TOO_SMALL);
    4595            1 :     free(data);
    4596            1 :     if (m_libspdm_local_certificate_chain != NULL) {
    4597            1 :         free(m_libspdm_local_certificate_chain);
    4598            1 :         m_libspdm_local_certificate_chain = NULL;
    4599            1 :         m_libspdm_local_certificate_chain_size = 0;
    4600              :     }
    4601            1 : }
    4602              : 
    4603            1 : int libspdm_req_get_certificate_test(void)
    4604              : {
    4605            1 :     const struct CMUnitTest test_cases[] = {
    4606              :         /* SendRequest failed*/
    4607              :         cmocka_unit_test(req_get_certificate_case1),
    4608              :         /* Successful response: check root certificate hash*/
    4609              :         cmocka_unit_test(req_get_certificate_case2),
    4610              :         /* connection_state check failed*/
    4611              :         cmocka_unit_test(req_get_certificate_case3),
    4612              :         /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
    4613              :         cmocka_unit_test(req_get_certificate_case4),
    4614              :         /* Always SPDM_ERROR_CODE_BUSY*/
    4615              :         cmocka_unit_test(req_get_certificate_case5),
    4616              :         /* SPDM_ERROR_CODE_BUSY + Successful response*/
    4617              :         cmocka_unit_test(req_get_certificate_case6),
    4618              :         /* Error response: SPDM_ERROR_CODE_REQUEST_RESYNCH*/
    4619              :         cmocka_unit_test(req_get_certificate_case7),
    4620              :         /* Always SPDM_ERROR_CODE_RESPONSE_NOT_READY*/
    4621              :         cmocka_unit_test(req_get_certificate_case8),
    4622              :         /* SPDM_ERROR_CODE_RESPONSE_NOT_READY + Successful response*/
    4623              :         cmocka_unit_test(req_get_certificate_case9),
    4624              :         /* Successful response: check certificate chain*/
    4625              :         cmocka_unit_test(req_get_certificate_case10),
    4626              :         /* Invalid certificate signature*/
    4627              :         cmocka_unit_test(req_get_certificate_case11),
    4628              :         /* Fail certificate chain check*/
    4629              :         cmocka_unit_test(req_get_certificate_case12),
    4630              :         /* Successful response: get a certificate chain that fits in one single message*/
    4631              :         cmocka_unit_test(req_get_certificate_case13),
    4632              :         /* Successful response: get certificate chain byte by byte*/
    4633              :         cmocka_unit_test(req_get_certificate_case14),
    4634              :         /* Successful response: get a long certificate chain*/
    4635              :         cmocka_unit_test(req_get_certificate_case15),
    4636              :         /* Unexpected errors*/
    4637              :         cmocka_unit_test(req_get_certificate_case16),
    4638              :         /* Successful response: get a certificate chain not start with root cert.*/
    4639              :         cmocka_unit_test(req_get_certificate_case17),
    4640              :         /* Fail response: get a certificate chain not start with root cert but with wrong signature.*/
    4641              :         cmocka_unit_test(req_get_certificate_case18),
    4642              :         /* Fail response: one certificate in the retrieved certificate chain past its expiration date.*/
    4643              :         cmocka_unit_test(req_get_certificate_case19),
    4644              :         /* Fail response: responder return portion_length is 0.*/
    4645              :         cmocka_unit_test(req_get_certificate_case20),
    4646              :         /* Fail response: responder return portion_length > spdm_request.length*/
    4647              :         cmocka_unit_test(req_get_certificate_case21),
    4648              :         /* Fail response: spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
    4649              :          * total_responder_cert_chain_buffer_length.*/
    4650              :         cmocka_unit_test(req_get_certificate_case22),
    4651              :         /* Buffer verification*/
    4652              :         cmocka_unit_test(req_get_certificate_case23),
    4653              :         /* hardware identify OID is found in AliasCert model cert*/
    4654              :         cmocka_unit_test(req_get_certificate_case24),
    4655              : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
    4656              :         /* GetCert (0), GetCert(1) and Challenge(0) */
    4657              :         cmocka_unit_test(req_get_certificate_case25),
    4658              : #endif
    4659              :         /* get cert in secure session */
    4660              :         cmocka_unit_test(req_get_certificate_case26),
    4661              :         /* Fail response: responder return wrong SlotID 3, not equal with SlotID 0 in request message. */
    4662              :         cmocka_unit_test(req_get_certificate_case27),
    4663              :         /*Successful response: get the entire alias_cert model cert_chain*/
    4664              :         cmocka_unit_test(req_get_certificate_case28),
    4665              :         /*Fail response: get the partial alias_cert model cert_chain*/
    4666              :         cmocka_unit_test(req_get_certificate_case29),
    4667              :         /* check request attributes and response attributes*/
    4668              :         cmocka_unit_test(req_get_certificate_case30),
    4669              :         /* Fail response: input buffer size too small for holding cert chain */
    4670              :         cmocka_unit_test(req_get_certificate_case31),
    4671              :     };
    4672              : 
    4673            1 :     libspdm_test_context_t test_context = {
    4674              :         LIBSPDM_TEST_CONTEXT_VERSION,
    4675              :         true,
    4676              :         send_message,
    4677              :         receive_message,
    4678              :     };
    4679              : 
    4680            1 :     libspdm_setup_test_context(&test_context);
    4681              : 
    4682            1 :     return cmocka_run_group_tests(test_cases,
    4683              :                                   libspdm_unit_test_group_setup,
    4684              :                                   libspdm_unit_test_group_teardown);
    4685              : }
    4686              : 
    4687              : #endif /* LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT */
        

Generated by: LCOV version 2.0-1