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: 90.2 % 2259 2038
Test Date: 2026-06-14 09:11:02 Functions: 100.0 % 37 37

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

Generated by: LCOV version 2.0-1