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.6 % 2229 2042
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 37 37

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

Generated by: LCOV version 2.0-1