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

Generated by: LCOV version 2.0-1