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: 93.6 % 2108 1973
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 35 35

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

Generated by: LCOV version 2.0-1